Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: frog/tokenizer.dart

Issue 9121025: cleanup to Value - fix for StringEscapesTest (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 // Generated by scripts/tokenizer_gen.py. 4 // Generated by scripts/tokenizer_gen.py.
5 5
6 6
7 interface TokenSource { 7 interface TokenSource {
8 Token next(); 8 Token next();
9 } 9 }
10 10
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 89
90 Token _finishToken(int kind) { 90 Token _finishToken(int kind) {
91 return new Token(kind, _source, _startIndex, _index); 91 return new Token(kind, _source, _startIndex, _index);
92 } 92 }
93 93
94 Token _errorToken([String message = null]) { 94 Token _errorToken([String message = null]) {
95 return new ErrorToken( 95 return new ErrorToken(
96 TokenKind.ERROR, _source, _startIndex, _index, message); 96 TokenKind.ERROR, _source, _startIndex, _index, message);
97 } 97 }
98 98
99 Token nextFromPreviousLine(int kind) {
100 _startIndex = _index;
101
102 switch(kind) {
103 case TokenKind.INCOMPLETE_COMMENT:
104 return finishMultiLineComment();
105 case TokenKind.INCOMPLETE_MULTILINE_STRING_DQ:
106 return finishMultilineString(34/*"*/);
107 case TokenKind.INCOMPLETE_MULTILINE_STRING_SQ:
108 return finishMultilineString(39/*'*/);
109 default:
110 return next();
111 }
112 }
113
114 Token finishWhitespace() { 99 Token finishWhitespace() {
115 _index--; 100 _index--;
116 while (_index < _text.length) { 101 while (_index < _text.length) {
117 final ch = _text.charCodeAt(_index++); 102 final ch = _text.charCodeAt(_index++);
118 if (ch == 32/*' '*/ || ch == 9/*'\t'*/ || ch == 13/*'\r'*/) { 103 if (ch == 32/*' '*/ || ch == 9/*'\t'*/ || ch == 13/*'\r'*/) {
119 // do nothing 104 // do nothing
120 } else if (ch == 10/*'\n'*/) { 105 } else if (ch == 10/*'\n'*/) {
121 if (!_skipWhitespace) { 106 if (!_skipWhitespace) {
122 return _finishToken(TokenKind.WHITESPACE); // note the newline? 107 return _finishToken(TokenKind.WHITESPACE); // note the newline?
123 } 108 }
(...skipping 30 matching lines...) Expand all
154 } 139 }
155 } 140 }
156 } 141 }
157 } 142 }
158 143
159 Token finishMultiLineComment() { 144 Token finishMultiLineComment() {
160 int nesting = 1; 145 int nesting = 1;
161 do { 146 do {
162 int ch = _nextChar(); 147 int ch = _nextChar();
163 if (ch == 0) { 148 if (ch == 0) {
164 return _finishToken(TokenKind.INCOMPLETE_COMMENT); 149 return _errorToken();
165 } else if (ch == 42/*'*'*/) { 150 } else if (ch == 42/*'*'*/) {
166 if (_maybeEatChar(47/*'/'*/)) { 151 if (_maybeEatChar(47/*'/'*/)) {
167 nesting--; 152 nesting--;
168 } 153 }
169 } else if (ch == 47/*'/'*/) { 154 } else if (ch == 47/*'/'*/) {
170 if (_maybeEatChar(42/*'*'*/)) { 155 if (_maybeEatChar(42/*'*'*/)) {
171 nesting++; 156 nesting++;
172 } 157 }
173 } 158 }
174 } while (nesting > 0); 159 } while (nesting > 0);
175 160
176 if (_skipWhitespace) { 161 if (_skipWhitespace) {
177 return next(); 162 return next();
178 } else { 163 } else {
179 return _finishToken(TokenKind.COMMENT); 164 return _finishToken(TokenKind.COMMENT);
180 } 165 }
181 } 166 }
182 167
183 void eatDigits() { 168 void eatDigits() {
184 while (_index < _text.length) { 169 while (_index < _text.length) {
185 if (isDigit(_text.charCodeAt(_index))) { 170 if (isDigit(_text.charCodeAt(_index))) {
186 _index++; 171 _index++;
187 } else { 172 } else {
188 return; 173 return;
189 } 174 }
190 } 175 }
191 } 176 }
192 177
193 void eatHexDigits() { 178 static int _hexDigit(int c) {
194 while (_index < _text.length) { 179 if(c >= 48/*0*/ && c <= 57/*9*/) {
195 if (isHexDigit(_text.charCodeAt(_index))) { 180 return c - 48;
196 _index++; 181 } else if (c >= 97/*a*/ && c <= 102/*f*/) {
197 } else { 182 return c - 87;
198 return; 183 } else if (c >= 65/*A*/ && c <= 70/*F*/) {
199 } 184 return c - 55;
185 } else {
186 return -1;
200 } 187 }
201 } 188 }
202 189
203 bool maybeEatHexDigit() { 190 int readHex([int hexLength]) {
204 if (_index < _text.length && isHexDigit(_text.charCodeAt(_index))) { 191 int maxIndex;
192 if (hexLength === null) {
193 maxIndex = _text.length - 1;
194 } else {
195 // TODO(jimhug): What if this is too long?
196 maxIndex = _index + hexLength;
197 if (maxIndex >= _text.length) return -1;
198 }
199 var result = 0;
200 while (_index < maxIndex) {
201 final digit = _hexDigit(_text.charCodeAt(_index));
202 if (digit == -1) {
203 if (hexLength === null) {
204 return result;
205 } else {
206 return -1;
207 }
208 }
209 _hexDigit(_text.charCodeAt(_index));
210 // Multiply by 16 rather than shift by 4 since that will result in a
211 // correct value for numbers that exceed the 32 bit precision of JS
212 // 'integers'.
213 // TODO: Figure out a better solution to integer truncation. Issue 638.
214 result = (result * 16) + digit;
205 _index++; 215 _index++;
206 return true;
207 } 216 }
208 return false; 217
218 return result;
209 } 219 }
210 220
211 Token finishHex() { 221 Token finishHex() {
212 eatHexDigits(); 222 final value = readHex();
213 return _finishToken(TokenKind.HEX_INTEGER); 223 return new LiteralToken(TokenKind.HEX_INTEGER, _source, _startIndex,
224 _index, value);
214 } 225 }
215 226
216 Token finishNumber() { 227 Token finishNumber() {
217 eatDigits(); 228 eatDigits();
218 229
219 if (_peekChar() == 46/*.*/) { 230 if (_peekChar() == 46/*.*/) {
220 // Handle the case of 1.toString(). 231 // Handle the case of 1.toString().
221 _nextChar(); 232 _nextChar();
222 if (isDigit(_peekChar())) { 233 if (isDigit(_peekChar())) {
223 eatDigits(); 234 eatDigits();
(...skipping 14 matching lines...) Expand all
238 eatDigits(); 249 eatDigits();
239 } 250 }
240 if (_peekChar() != 0 && isIdentifierStart(_peekChar())) { 251 if (_peekChar() != 0 && isIdentifierStart(_peekChar())) {
241 _nextChar(); 252 _nextChar();
242 return _errorToken("illegal character in number"); 253 return _errorToken("illegal character in number");
243 } 254 }
244 255
245 return _finishToken(kind); 256 return _finishToken(kind);
246 } 257 }
247 258
259 Token _makeStringToken(List<int> buf, bool isPart) {
260 final s = new String.fromCharCodes(buf);
261 final kind = isPart ? TokenKind.STRING_PART : TokenKind.STRING;
262 return new LiteralToken(kind, _source, _startIndex, _index, s);
263 }
264
265 Token _makeRawStringToken(bool isMultiline) {
266 String s;
267 if (isMultiline) {
268 // Skip initial newline in multiline strings
269 if (_source.text[_startIndex + 4] == '\n') {
Jennifer Messerly 2012/01/09 20:16:26 might be nice to tweak this as: int start = _star
jimhug 2012/01/09 21:19:05 Nice - done. On 2012/01/09 20:16:26, John Messerly
270 s = _source.text.substring(_startIndex + 5, _index - 3);
271 } else {
272 s = _source.text.substring(_startIndex + 4, _index - 3);
273 }
274 } else {
275 s = _source.text.substring(_startIndex + 2, _index - 1);
276 }
277 return new LiteralToken(TokenKind.STRING, _source, _startIndex, _index, s);
278 }
279
248 Token finishMultilineString(int quote) { 280 Token finishMultilineString(int quote) {
281 var buf = new List<int>();
Jennifer Messerly 2012/01/09 20:16:26 <int>[] ?
jimhug 2012/01/09 21:19:05 Done.
249 while (true) { 282 while (true) {
250 int ch = _nextChar(); 283 int ch = _nextChar();
251 if (ch == 0) { 284 if (ch == 0) {
252 final kind = quote == 34/*"*/ ? 285 return _errorToken();
253 TokenKind.INCOMPLETE_MULTILINE_STRING_DQ :
254 TokenKind.INCOMPLETE_MULTILINE_STRING_SQ;
255 return _finishToken(kind);
256 } else if (ch == quote) { 286 } else if (ch == quote) {
257 if (_maybeEatChar(quote)) { 287 if (_maybeEatChar(quote)) {
258 if (_maybeEatChar(quote)) { 288 if (_maybeEatChar(quote)) {
259 return _finishToken(TokenKind.STRING); 289 return _makeStringToken(buf, false);
260 } 290 }
291 buf.add(quote);
261 } 292 }
293 buf.add(quote);
262 } else if (ch == 36/*$*/) { 294 } else if (ch == 36/*$*/) {
263 // start of string interp 295 // start of string interp
264 _interpStack = InterpStack.push(_interpStack, quote, true); 296 _interpStack = InterpStack.push(_interpStack, quote, true);
265 return _finishToken(TokenKind.INCOMPLETE_STRING); // TODO 297 return _makeStringToken(buf, true);
266 } else if (ch == 92/*\*/) { 298 } else if (ch == 92/*\*/) {
267 if (!eatEscapeSequence()) { 299 var escapeVal = readEscapeSequence();
300 if (escapeVal == -1) {
268 return _errorToken("invalid hex escape sequence"); 301 return _errorToken("invalid hex escape sequence");
302 } else {
303 buf.add(escapeVal);
269 } 304 }
305 } else {
306 buf.add(ch);
270 } 307 }
271 } 308 }
272 } 309 }
273 310
274 Token _finishOpenBrace() { 311 Token _finishOpenBrace() {
275 if (_interpStack != null) { 312 if (_interpStack != null) {
276 if (_interpStack.depth == -1) { 313 if (_interpStack.depth == -1) {
277 _interpStack.depth = 1; 314 _interpStack.depth = 1;
278 } else { 315 } else {
279 assert(_interpStack.depth >= 0); 316 assert(_interpStack.depth >= 0);
280 _interpStack.depth += 1; 317 _interpStack.depth += 1;
281 } 318 }
282 } 319 }
283 return _finishToken(TokenKind.LBRACE); 320 return _finishToken(TokenKind.LBRACE);
284 } 321 }
285 322
286 Token _finishCloseBrace() { 323 Token _finishCloseBrace() {
287 if (_interpStack != null) { 324 if (_interpStack != null) {
288 _interpStack.depth -= 1; 325 _interpStack.depth -= 1;
289 assert(_interpStack.depth >= 0); 326 assert(_interpStack.depth >= 0);
290 } 327 }
291 return _finishToken(TokenKind.RBRACE); 328 return _finishToken(TokenKind.RBRACE);
292 } 329 }
293 330
294 Token finishString(int quote) { 331 Token finishString(int quote) {
295 if (_maybeEatChar(quote)) { 332 if (_maybeEatChar(quote)) {
296 if (_maybeEatChar(quote)) { 333 if (_maybeEatChar(quote)) {
334 // skip an initial newline
335 _maybeEatChar(10/*'\n'*/);
297 return finishMultilineString(quote); 336 return finishMultilineString(quote);
298 } else { 337 } else {
299 return _finishToken(TokenKind.STRING); 338 return _makeStringToken(new List<int>(), false);
300 } 339 }
301 } 340 }
302 return finishStringBody(quote); 341 return finishStringBody(quote);
303 } 342 }
304 343
305 Token finishRawString(int quote) { 344 Token finishRawString(int quote) {
306 if (_maybeEatChar(quote)) { 345 if (_maybeEatChar(quote)) {
307 if (_maybeEatChar(quote)) { 346 if (_maybeEatChar(quote)) {
308 return finishMultilineRawString(quote); 347 return finishMultilineRawString(quote);
309 } else { 348 } else {
310 return _finishToken(TokenKind.STRING); 349 return _makeStringToken(new List<int>(), false);
Jennifer Messerly 2012/01/09 20:16:26 <int>[] ?
jimhug 2012/01/09 21:19:05 Done.
311 } 350 }
312 } 351 }
313 while (true) { 352 while (true) {
314 int ch = _nextChar(); 353 int ch = _nextChar();
315 if (ch == quote) { 354 if (ch == quote) {
316 return _finishToken(TokenKind.STRING); 355 return _makeRawStringToken(false);
317 } else if (ch == 0) { 356 } else if (ch == 0) {
318 return _finishToken(TokenKind.INCOMPLETE_STRING); 357 return _errorToken();
319 } 358 }
320 } 359 }
321 } 360 }
322 361
323 Token finishMultilineRawString(int quote) { 362 Token finishMultilineRawString(int quote) {
324 while (true) { 363 while (true) {
325 int ch = _nextChar(); 364 int ch = _nextChar();
326 if (ch == 0) { 365 if (ch == 0) {
327 final kind = quote == 34/*"*/ ? 366 return _errorToken();
328 TokenKind.INCOMPLETE_MULTILINE_STRING_DQ :
329 TokenKind.INCOMPLETE_MULTILINE_STRING_SQ;
330 return _finishToken(kind);
331 } else if (ch == quote && _maybeEatChar(quote) && _maybeEatChar(quote)) { 367 } else if (ch == quote && _maybeEatChar(quote) && _maybeEatChar(quote)) {
332 return _finishToken(TokenKind.STRING); 368 return _makeRawStringToken(true);
333 } 369 }
334 } 370 }
335 } 371 }
336 372
337 Token finishStringBody(int quote) { 373 Token finishStringBody(int quote) {
374 var buf = new List<int>();
338 while (true) { 375 while (true) {
339 int ch = _nextChar(); 376 int ch = _nextChar();
340 if (ch == quote) { 377 if (ch == quote) {
341 return _finishToken(TokenKind.STRING); 378 return _makeStringToken(buf, false);
342 } else if (ch == 36/*$*/) { 379 } else if (ch == 36/*$*/) {
343 // start of string interp 380 // start of string interp
344 _interpStack = InterpStack.push(_interpStack, quote, false); 381 _interpStack = InterpStack.push(_interpStack, quote, false);
345 return _finishToken(TokenKind.INCOMPLETE_STRING); // TODO 382 return _makeStringToken(buf, true);
346 } else if (ch == 0) { 383 } else if (ch == 0) {
347 return _finishToken(TokenKind.INCOMPLETE_STRING); 384 return _errorToken();
348 } else if (ch == 92/*\*/) { 385 } else if (ch == 92/*\*/) {
349 if (!eatEscapeSequence()) { 386 var escapeVal = readEscapeSequence();
387 if (escapeVal == -1) {
350 return _errorToken("invalid hex escape sequence"); 388 return _errorToken("invalid hex escape sequence");
389 } else {
390 buf.add(escapeVal);
351 } 391 }
392 } else {
393 buf.add(ch);
352 } 394 }
353 } 395 }
354 } 396 }
355 397
356 bool eatEscapeSequence() { 398 int readEscapeSequence() {
357 String hex; 399 final ch = _nextChar();
358 switch (_nextChar()) { 400 int hexValue;
401 switch (ch) {
402 case 110/*n*/:
403 return 0x0a/*'\n'*/;
404 case 114/*r*/:
405 return 0x0d/*'\r'*/;
406 case 102/*f*/:
407 return 0x0c/*'\f'*/;
408 case 98/*b*/:
409 return 0x08/*'\b'*/;
410 case 116/*t*/:
411 return 0x09/*'\t'*/;
412 case 118/*v*/:
413 return 0x0b/*'\v'*/;
359 case 120/*x*/: 414 case 120/*x*/:
360 return maybeEatHexDigit() && maybeEatHexDigit(); 415 hexValue = readHex(2);
416 break;
361 case 117/*u*/: 417 case 117/*u*/:
362 if (_maybeEatChar(123/*{*/)) { 418 if (_maybeEatChar(123/*{*/)) {
363 int start = _index; 419 hexValue = readHex();
364 eatHexDigits(); 420 if (!_maybeEatChar(125/*}*/)) {
365 int chars = _index - start; 421 return -1;
366 if (chars > 0 && chars <= 6 && _maybeEatChar(125/*}*/)) { 422 } else {
367 hex = _text.substring(start, start + chars);
368 break; 423 break;
369 } else {
370 return false;
371 } 424 }
372 } else { 425 } else {
373 if (maybeEatHexDigit() && maybeEatHexDigit() && 426 hexValue = readHex(4);
374 maybeEatHexDigit() && maybeEatHexDigit()) { 427 break;
375 hex = _text.substring(_index - 4, _index);
376 break;
377 } else {
378 return false;
379 }
380 } 428 }
381 default: return true; 429 default: return ch;
382 } 430 }
431
432 if (hexValue == -1) return -1;
433
383 // According to the Unicode standard the high and low surrogate halves 434 // According to the Unicode standard the high and low surrogate halves
384 // used by UTF-16 (U+D800 through U+DFFF) and values above U+10FFFF 435 // used by UTF-16 (U+D800 through U+DFFF) and values above U+10FFFF
385 // are not legal Unicode values. 436 // are not legal Unicode values.
386 num n = Parser.parseHex(hex); 437 if (hexValue < 0xD800 || hexValue > 0xDFFF && hexValue <= 0xFFFF) {
387 return n < 0xD800 || n > 0xDFFF && n <= 0x10FFFF; 438 return hexValue;
439 } else if (hexValue <= 0x10FFFF){
440 world.fatal('unicode values greater than 2 bytes not implemented yet');
441 return -1;
442 } else {
443 return -1;
444 }
388 } 445 }
389 446
390 Token finishDot() { 447 Token finishDot() {
391 if (isDigit(_peekChar())) { 448 if (isDigit(_peekChar())) {
392 eatDigits(); 449 eatDigits();
393 return finishNumberExtra(TokenKind.DOUBLE); 450 return finishNumberExtra(TokenKind.DOUBLE);
394 } else { 451 } else {
395 return _finishToken(TokenKind.DOT); 452 return _finishToken(TokenKind.DOT);
396 } 453 }
397 } 454 }
(...skipping 20 matching lines...) Expand all
418 } 475 }
419 } 476 }
420 int kind = getIdentifierKind(); 477 int kind = getIdentifierKind();
421 if (kind == TokenKind.IDENTIFIER) { 478 if (kind == TokenKind.IDENTIFIER) {
422 return _finishToken(TokenKind.IDENTIFIER); 479 return _finishToken(TokenKind.IDENTIFIER);
423 } else { 480 } else {
424 return _finishToken(kind); 481 return _finishToken(kind);
425 } 482 }
426 } 483 }
427 } 484 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698