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

Side by Side Diff: pkg/polymer_expressions/lib/tokenizer.dart

Issue 22950008: move fancy_syntax into Dart SVN (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 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
« no previous file with comments | « pkg/polymer_expressions/lib/src/mirrors.dart ('k') | pkg/polymer_expressions/lib/visitor.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
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.
4
5 library polymer_expressions.tokenizer;
6
7 const int _TAB = 9;
8 const int _LF = 10;
9 const int _VTAB = 11;
10 const int _FF = 12;
11 const int _CR = 13;
12 const int _SPACE = 32;
13 const int _BANG = 33;
14 const int _DQ = 34;
15 const int _$ = 36;
16 const int _AMPERSAND = 38;
17 const int _SQ = 39;
18 const int _OPEN_PAREN = 40;
19 const int _CLOSE_PAREN = 41;
20 const int _STAR = 42;
21 const int _PLUS = 43;
22 const int _COMMA = 44;
23 const int _MINUS = 45;
24 const int _PERIOD = 46;
25 const int _SLASH = 47;
26 const int _0 = 48;
27 const int _9 = 57;
28 const int _COLON = 58;
29 const int _LT = 60;
30 const int _EQ = 61;
31 const int _GT = 62;
32 const int _QUESTION = 63;
33 const int _A = 65;
34 const int _Z = 90;
35 const int _OPEN_SQUARE_BRACKET = 91;
36 const int _BACKSLASH = 92;
37 const int _CLOSE_SQUARE_BRACKET = 93;
38 const int _CARET = 94;
39 const int _US = 95;
40 const int _a = 97;
41 const int _f = 102;
42 const int _n = 110;
43 const int _r = 114;
44 const int _t = 116;
45 const int _v = 118;
46 const int _z = 122;
47 const int _OPEN_CURLY_BRACKET = 123;
48 const int _BAR = 124;
49 const int _CLOSE_CURLY_BRACKET = 125;
50 const int _NBSP = 160;
51
52 const _OPERATORS = const [_PLUS, _MINUS, _STAR, _SLASH, _BANG, _AMPERSAND,
53 /*_COMMA,*/ _LT, _EQ, _GT, _QUESTION, _CARET, _BAR];
54
55 const _GROUPERS = const [_OPEN_PAREN, _CLOSE_PAREN,
56 _OPEN_SQUARE_BRACKET, _CLOSE_SQUARE_BRACKET,
57 _OPEN_CURLY_BRACKET, _CLOSE_CURLY_BRACKET];
58
59 const _TWO_CHAR_OPS = const ['==', '!=', '<=', '>=', '||', '&&'];
60
61 const _KEYWORDS = const ['in', 'this'];
62
63 const _PRECEDENCE = const {
64 '!': 0,
65 ':': 0,
66 ',': 0,
67 ')': 0,
68 ']': 0,
69 '}': 0, // ?
70 '?': 1,
71 '||': 2,
72 '&&': 3,
73 '|': 4,
74 '^': 5,
75 '&': 6,
76
77 // equality
78 '!=': 7,
79 '==': 7,
80
81 // relational
82 '>=': 8,
83 '>': 8,
84 '<=': 8,
85 '<': 8,
86
87 // additive
88 '+': 9,
89 '-': 9,
90
91 // multiplicative
92 '%': 10,
93 '/': 10,
94 '*': 10,
95
96 // postfix
97 '(': 11,
98 '[': 11,
99 '.': 11,
100 '{': 11, //not sure this is correct
101 };
102
103 const POSTFIX_PRECEDENCE = 11;
104
105 const int STRING_TOKEN = 1;
106 const int IDENTIFIER_TOKEN = 2;
107 const int DOT_TOKEN = 3;
108 const int COMMA_TOKEN = 4;
109 const int COLON_TOKEN = 5;
110 const int INTEGER_TOKEN = 6;
111 const int DECIMAL_TOKEN = 7;
112 const int OPERATOR_TOKEN = 8;
113 const int GROUPER_TOKEN = 9;
114 const int KEYWORD_TOKEN = 10;
115
116 bool isWhitespace(int next) => next == _SPACE || next == _TAB || next == _NBSP;
117
118 bool isIdentifierOrKeywordStart(int next) => (_a <= next && next <= _z) ||
119 (_A <= next && next <= _Z) || next == _US || next == _$ || next > 127;
120
121 bool isIdentifier(int next) => (_a <= next && next <= _z) ||
122 (_A <= next && next <= _Z) || (_0 <= next && next <= _9) ||
123 next == _US || next == _$ || next > 127;
124
125 bool isQuote(int next) => next == _DQ || next == _SQ;
126
127 bool isNumber(int next) => _0 <= next && next <= _9;
128
129 bool isOperator(int next) => _OPERATORS.contains(next);
130
131 bool isGrouper(int next) => _GROUPERS.contains(next);
132
133 int escape(int c) {
134 switch (c) {
135 case _f: return _FF; break;
136 case _n: return _LF; break;
137 case _r: return _CR; break;
138 case _t: return _TAB; break;
139 case _v: return _VTAB; break;
140 default: return c;
141 }
142 }
143
144 class Token {
145 final int kind;
146 final String value;
147 final int precedence;
148
149 Token(this.kind, this.value, [this.precedence = 0]);
150
151 String toString() => "($kind, '$value')";
152 }
153
154 class Tokenizer {
155 final List<Token> _tokens = <Token>[];
156 final StringBuffer _sb = new StringBuffer();
157 final RuneIterator _iterator;
158
159 int _next;
160
161 Tokenizer(String input) : _iterator = new RuneIterator(input);
162
163 _advance() {
164 _next = _iterator.moveNext() ? _iterator.current : null;
165 }
166
167 List<Token> tokenize() {
168 _advance();
169 while(_next != null) {
170 if (isWhitespace(_next)) {
171 _advance();
172 } else if (isQuote(_next)) {
173 tokenizeString();
174 } else if (isIdentifierOrKeywordStart(_next)) {
175 tokenizeIdentifierOrKeyword();
176 } else if (isNumber(_next)) {
177 tokenizeNumber();
178 } else if (_next == _PERIOD) {
179 tokenizeDot();
180 } else if (_next == _COMMA) {
181 tokenizeComma();
182 } else if (_next == _COLON) {
183 tokenizeColon();
184 } else if (isOperator(_next)) {
185 tokenizeOperator();
186 } else if (isGrouper(_next)) {
187 tokenizeGrouper();
188 } else {
189 _advance();
190 }
191 }
192 return _tokens;
193 }
194
195 tokenizeString() {
196 int quoteChar = _next;
197 _advance();
198 while (_next != quoteChar) {
199 if (_next == null) throw new ParseException("unterminated string");
200 if (_next == _BACKSLASH) {
201 _advance();
202 if (_next == null) throw new ParseException("unterminated string");
203 _sb.writeCharCode(escape(_next));
204 } else {
205 _sb.writeCharCode(_next);
206 }
207 _advance();
208 }
209 _tokens.add(new Token(STRING_TOKEN, _sb.toString()));
210 _sb.clear();
211 _advance();
212 }
213
214 tokenizeIdentifierOrKeyword() {
215 while (_next != null && isIdentifier(_next)) {
216 _sb.writeCharCode(_next);
217 _advance();
218 }
219 var value = _sb.toString();
220 if (_KEYWORDS.contains(value)) {
221 _tokens.add(new Token(KEYWORD_TOKEN, value));
222 } else {
223 _tokens.add(new Token(IDENTIFIER_TOKEN, value));
224 }
225 _sb.clear();
226 }
227
228 tokenizeNumber() {
229 while (_next != null && isNumber(_next)) {
230 _sb.writeCharCode(_next);
231 _advance();
232 }
233 if (_next == _PERIOD) {
234 tokenizeDot();
235 } else {
236 _tokens.add(new Token(INTEGER_TOKEN, _sb.toString()));
237 _sb.clear();
238 }
239 }
240
241 tokenizeDot() {
242 _advance();
243 if (isNumber(_next)) {
244 tokenizeFraction();
245 } else {
246 _tokens.add(new Token(DOT_TOKEN, '.', POSTFIX_PRECEDENCE));
247 }
248 }
249
250 tokenizeComma() {
251 _advance();
252 _tokens.add(new Token(COMMA_TOKEN, ','));
253 }
254
255 tokenizeColon() {
256 _advance();
257 _tokens.add(new Token(COLON_TOKEN, ':'));
258 }
259
260 tokenizeFraction() {
261 _sb.writeCharCode(_PERIOD);
262 while (_next != null && isNumber(_next)) {
263 _sb.writeCharCode(_next);
264 _advance();
265 }
266 _tokens.add(new Token(DECIMAL_TOKEN, _sb.toString()));
267 _sb.clear();
268 }
269
270 tokenizeOperator() {
271 int startChar = _next;
272 _advance();
273 var op;
274 // check for 2 character operators
275 if (isOperator(_next)) {
276 var op2 = new String.fromCharCodes([startChar, _next]);
277 if (_TWO_CHAR_OPS.contains(op2)) {
278 op = op2;
279 _advance();
280 } else {
281 op = new String.fromCharCode(startChar);
282 }
283 } else {
284 op = new String.fromCharCode(startChar);
285 }
286 _tokens.add(new Token(OPERATOR_TOKEN, op, _PRECEDENCE[op]));
287 }
288
289 tokenizeGrouper() {
290 var value = new String.fromCharCode(_next);
291 _tokens.add(new Token(GROUPER_TOKEN, value, _PRECEDENCE[value]));
292 _advance();
293 }
294 }
295
296 class ParseException implements Exception {
297 final String message;
298 ParseException(this.message);
299 String toString() => "ParseException: $message";
300 }
OLDNEW
« no previous file with comments | « pkg/polymer_expressions/lib/src/mirrors.dart ('k') | pkg/polymer_expressions/lib/visitor.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698