| 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 |