1 /*
  2 * Copyright (c) 2013-2014 Nonki Takahashi. All rights reserved.
  3 *
  4 * History:
  5 *  0.4 2014-01-30 Added methods top and beforeDelim.
  6 *  0.3 2014-09-19 Method text is added.
  7 *  0.2 2014-01-09 Interface changed and methods sq, sp are added.
  8 *  0.1 2013-06-26 Created. Ported from GoSimulator03.smallbasic .
  9 */
 10 
 11 /**
 12  * @fileOverview Lex - Lexical Analyzer Object
 13  * @version 0.4
 14  * @author Nonki Takahashi
 15  */
 16 
 17 const DIGIT0 = 48;
 18 const DIGIT9 = 57;
 19 const UPPERA = 65;
 20 const UPPERZ = 90;
 21 const LOWERA = 97;
 22 const LOWERZ = 122;
 23 
 24 /**
 25  * Lexical Analyzer Object
 26  * @class Represents Lexical Analyzer Object
 27  * @this {Lex}
 28  * @param {String} src source string to analyze
 29  * @since 0.1
 30  */
 31 function Lex(src) {
 32 	Source.call(this, src);
 33 };
 34 
 35 Lex.prototype = new Source();
 36 
 37 Lex.prototype.constructor = Lex;
 38 
 39 /**
 40  * Analyze Digit
 41  * @return {String} digit if matched, null if not matched
 42  * @since 0.2
 43  */
 44 Lex.prototype.digit = function() {
 45 	var code = this.buf.charCodeAt(this.ptr);
 46 	if (DIGIT0 <= code && code <= DIGIT9)
 47 		return this.buf.charAt(this.ptr++);
 48 	else
 49 		return null;
 50 };
 51 
 52 /**
 53  * Analyze Upper Case Character
 54  * @return {String} character if matched, null if not matched
 55  * @since 0.2
 56  */
 57 Lex.prototype.upper = function() {
 58 	var code = this.buf.charCodeAt(this.ptr);
 59 	if (UPPERA <= code && code <= UPPERZ)
 60 		return this.buf.charAt(this.ptr++);
 61 	else
 62 		return null;
 63 };
 64 
 65 /**
 66  * Analyze Lower Case Character
 67  * @return {String} character if matched, null if not matched
 68  * @since 0.2
 69  */
 70 Lex.prototype.lower = function() {
 71 	var code = this.buf.charCodeAt(this.ptr);
 72 	if (LOWERA <= code && code <= LOWERZ)
 73 		return this.buf.charAt(this.ptr++);
 74 	else
 75 		return null;
 76 };
 77 
 78 /**
 79  * Given Character
 80  * @param {Char} ch given character
 81  * @return {String} character if matched, null if not matched
 82  * @since 0.2
 83  */
 84 Lex.prototype.ch = function(ch) {
 85 	if (this.buf.charAt(this.ptr) == ch) {
 86 		this.ptr++;
 87 		return ch;
 88 	} else
 89 		return null;
 90 };
 91 
 92 /**
 93  * Analyze Single Quote
 94  * @return {String} single quote if matched, null if not matched
 95  * @since 0.2
 96  */
 97 Lex.prototype.sq = function() {
 98 	return this.ch("'");
 99 };
100 
101 /**
102  * Analyze Space
103  * @return {String} space if matched, null if not matched
104  * @since 0.2
105  */
106 Lex.prototype.sp = function() {
107 	var match = false;
108 	while (this.ch(" ") || this.ch("\t") || this.ch("\n")) {
109 		match = true;
110 	}
111 	if (match)
112 		return " ";
113 	else
114 		return null;
115 };
116 
117 /**
118  * Analyze Text
119  * @param {Boolean} text given text
120  * @param {Boolean} ignoreCase true if ignore case
121  * @return {String} text if matched, null if not matched
122  * @since 0.3
123  */
124 Lex.prototype.text = function(text, ignoreCase) {
125 	var text2 = text;
126 	if (ignoreCase)
127 		text2 = text2.toLowerCase();
128 	var text1 = this.buf.substr(this.ptr, text.length);
129 	if (ignoreCase)
130 		text1 = text1.toLowerCase();
131 	if (text1 == text2) {
132 		var retval = this.buf.substr(this.ptr, text.length);
133 		this.ptr += text.length;
134 		return retval;
135 	} else
136 		return null;
137 };
138 
139 /**
140  * Return top one character on the pointer of the buffer<br>
141  * Caution: This method doesn't update buffer pointer.
142  * @return {String} character on the pointer of the buffer
143  * @since 0.4
144  */
145 Lex.prototype.top = function() {
146     return this.buf.charAt(this.ptr);
147 };
148 
149 /**
150  * Analyze text before given delimiter
151  * @param {String} delim delimiters such as ",;"
152  * @return {String} text before given delimiters
153  * @since 0.4
154  */
155 Lex.prototype.beforeDelim = function(delim) {
156     var text = "";
157     var c = this.buf.charAt(this.ptr);
158     while (delim.indexOf(c) < 0) {
159         text += c;
160         c = this.buf.charAt(++this.ptr);
161     }
162     return text;
163 };
164