OLD | NEW |
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 | 4 |
5 part of layout; | 5 part of layout; |
6 | 6 |
7 /** | 7 /** |
8 * Base class for simple recursive descent parsers. | 8 * Base class for simple recursive descent parsers. |
9 * Handles the lower level stuff, i.e. what a scanner/tokenizer would do. | 9 * Handles the lower level stuff, i.e. what a scanner/tokenizer would do. |
10 */ | 10 */ |
11 class _Parser { | 11 class _Parser { |
12 static const WHITESPACE = ' \r\n\t'; | 12 static const WHITESPACE = ' \r\n\t'; |
13 | 13 |
14 // TODO(jmesserly): shouldn't need this optimization, but dart_json parser | 14 // TODO(jmesserly): shouldn't need this optimization, but dart_json parser |
15 // found that they needed this. | 15 // found that they needed this. |
16 static const A_BIG = 65; // 'A'.charCodeAt(0) | 16 static const A_BIG = 65; // 'A'.codeUnitAt(0) |
17 static const Z_BIG = 90; // 'Z'.charCodeAt(0) | 17 static const Z_BIG = 90; // 'Z'.codeUnitAt(0) |
18 static const A_SMALL = 97; // 'a'.charCodeAt(0) | 18 static const A_SMALL = 97; // 'a'.codeUnitAt(0) |
19 static const Z_SMALL = 122; // 'z'.charCodeAt(0) | 19 static const Z_SMALL = 122; // 'z'.codeUnitAt(0) |
20 static const TAB = 9; // '\t'.charCodeAt(0) | 20 static const TAB = 9; // '\t'.codeUnitAt(0) |
21 static const NEW_LINE = 10; // '\n'.charCodeAt(0) | 21 static const NEW_LINE = 10; // '\n'.codeUnitAt(0) |
22 static const LINE_FEED = 13; // '\r'.charCodeAt(0) | 22 static const LINE_FEED = 13; // '\r'.codeUnitAt(0) |
23 static const SPACE = 32; // ' '.charCodeAt(0) | 23 static const SPACE = 32; // ' '.codeUnitAt(0) |
24 static const ZERO = 48; // '0'.charCodeAt(0) | 24 static const ZERO = 48; // '0'.codeUnitAt(0) |
25 static const NINE = 57; // '9'.charCodeAt(0) | 25 static const NINE = 57; // '9'.codeUnitAt(0) |
26 static const DOT = 46; // '.'.charCodeAt(0) | 26 static const DOT = 46; // '.'.codeUnitAt(0) |
27 static const R_PAREN = 41; // ')'.charCodeAt(0) | 27 static const R_PAREN = 41; // ')'.codeUnitAt(0) |
28 | 28 |
29 final String _src; | 29 final String _src; |
30 int _offset; | 30 int _offset; |
31 | 31 |
32 // TODO(jmesserly): should be this._offset = 0, see bug 5332175. | 32 // TODO(jmesserly): should be this._offset = 0, see bug 5332175. |
33 _Parser(this._src) : _offset = 0; | 33 _Parser(this._src) : _offset = 0; |
34 | 34 |
35 // TODO(jmesserly): these should exist in the standard lib. | 35 // TODO(jmesserly): these should exist in the standard lib. |
36 // I took this from dart_json.dart | 36 // I took this from dart_json.dart |
37 static bool _isWhitespace(int c) { | 37 static bool _isWhitespace(int c) { |
(...skipping 16 matching lines...) Expand all Loading... |
54 } | 54 } |
55 | 55 |
56 void _error(String msg) { | 56 void _error(String msg) { |
57 throw new SyntaxErrorException(msg, _src, _offset); | 57 throw new SyntaxErrorException(msg, _src, _offset); |
58 } | 58 } |
59 | 59 |
60 int get length => _src.length; | 60 int get length => _src.length; |
61 | 61 |
62 int get remaining => _src.length - _offset; | 62 int get remaining => _src.length - _offset; |
63 | 63 |
64 int _peekChar() => _src.charCodeAt(_offset); | 64 int _peekChar() => _src.codeUnitAt(_offset); |
65 | 65 |
66 bool get endOfInput => _offset >= _src.length; | 66 bool get endOfInput => _offset >= _src.length; |
67 | 67 |
68 bool _maybeEatWhitespace() { | 68 bool _maybeEatWhitespace() { |
69 int start = _offset; | 69 int start = _offset; |
70 while (_offset < length && _isWhitespace(_peekChar())) { | 70 while (_offset < length && _isWhitespace(_peekChar())) { |
71 _offset++; | 71 _offset++; |
72 } | 72 } |
73 return _offset != start; | 73 return _offset != start; |
74 } | 74 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 } | 106 } |
107 for (int i = 0; i < value.length; i++) { | 107 for (int i = 0; i < value.length; i++) { |
108 if (_src[_offset + i] != value[i]) { | 108 if (_src[_offset + i] != value[i]) { |
109 return false; | 109 return false; |
110 } | 110 } |
111 } | 111 } |
112 | 112 |
113 // If we're eating something that's like a word, make sure | 113 // If we're eating something that's like a word, make sure |
114 // it's not followed by more characters. | 114 // it's not followed by more characters. |
115 // This is ugly. Proper tokenization would make this cleaner. | 115 // This is ugly. Proper tokenization would make this cleaner. |
116 if (_isLetter(value.charCodeAt(value.length - 1))) { | 116 if (_isLetter(value.codeUnitAt(value.length - 1))) { |
117 int i = _offset + value.length; | 117 int i = _offset + value.length; |
118 if (i < _src.length && _isLetter(_src.charCodeAt(i))) { | 118 if (i < _src.length && _isLetter(_src.codeUnitAt(i))) { |
119 return false; | 119 return false; |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 _offset += value.length; | 123 _offset += value.length; |
124 return true; | 124 return true; |
125 } | 125 } |
126 | 126 |
127 void _eat(String value, [bool eatWhitespace = true]) { | 127 void _eat(String value, [bool eatWhitespace = true]) { |
128 if (!_maybeEat(value)) { | 128 if (!_maybeEat(value)) { |
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
479 String toString() { | 479 String toString() { |
480 String location; | 480 String location; |
481 if (_offset < _source.length) { | 481 if (_offset < _source.length) { |
482 location = 'location: ${_source.substring(_offset)}'; | 482 location = 'location: ${_source.substring(_offset)}'; |
483 } else { | 483 } else { |
484 location = 'end of input'; | 484 location = 'end of input'; |
485 } | 485 } |
486 return 'SyntaxErrorException: $_message at $location'; | 486 return 'SyntaxErrorException: $_message at $location'; |
487 } | 487 } |
488 } | 488 } |
OLD | NEW |