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

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

Issue 74543003: Split out Index AST node from Invoke (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Split out Getter too Created 7 years, 1 month 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) 2013, the Dart project authors. Please see the AUTHORS file 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 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 library polymer_expressions.parser; 5 library polymer_expressions.parser;
6 6
7 import 'tokenizer.dart'; 7 import 'tokenizer.dart';
8 import 'expression.dart'; 8 import 'expression.dart';
9 9
10 const _UNARY_OPERATORS = const ['+', '-', '!']; 10 const _UNARY_OPERATORS = const ['+', '-', '!'];
11 11
12 Expression parse(String expr) => new Parser(expr).parse(); 12 Expression parse(String expr) => new Parser(expr).parse();
13 13
14 class Parser { 14 class Parser {
15 final AstFactory _astFactory; 15 final AstFactory _astFactory;
16 final Tokenizer _tokenizer; 16 final Tokenizer _tokenizer;
17 List<Token> _tokens; 17 List<Token> _tokens;
18 Iterator _iterator; 18 Iterator _iterator;
19 Token _token; 19 Token get _token => _iterator.current;
20 20
21 Parser(String input, {AstFactory astFactory}) 21 Parser(String input, {AstFactory astFactory})
22 : _tokenizer = new Tokenizer(input), 22 : _tokenizer = new Tokenizer(input),
23 _astFactory = (astFactory == null) ? new AstFactory() : astFactory; 23 _astFactory = (astFactory == null) ? new AstFactory() : astFactory;
24 24
25 Expression parse() { 25 Expression parse() {
26 _tokens = _tokenizer.tokenize(); 26 _tokens = _tokenizer.tokenize();
27 _iterator = _tokens.iterator; 27 _iterator = _tokens.iterator;
28 _advance(); 28 _advance();
29 return _parseExpression(); 29 return _parseExpression();
30 } 30 }
31 31
32 _advance([int kind, String value]) { 32 _advance([int kind, String value]) {
33 if ((kind != null && _token.kind != kind) 33 if ((kind != null && _token.kind != kind)
34 || (value != null && _token.value != value)) { 34 || (value != null && _token.value != value)) {
35 throw new ParseException("Expected $value: $_token"); 35 throw new ParseException("Expected $value: $_token");
36 } 36 }
37 _token = _iterator.moveNext() ? _iterator.current : null; 37 _iterator.moveNext();
38 } 38 }
39 39
40 Expression _parseExpression() { 40 Expression _parseExpression() {
41 if (_token == null) return _astFactory.empty(); 41 if (_token == null) return _astFactory.empty();
42 var expr = _parseUnary(); 42 var expr = _parseUnary();
43 return (expr == null) ? null : _parsePrecedence(expr, 0); 43 return (expr == null) ? null : _parsePrecedence(expr, 0);
44 } 44 }
45 45
46 // _parsePrecedence and _parseBinary implement the precedence climbing 46 // _parsePrecedence and _parseBinary implement the precedence climbing
47 // algorithm as described in: 47 // algorithm as described in:
48 // http://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing _method 48 // http://en.wikipedia.org/wiki/Operator-precedence_parser#Precedence_climbing _method
49 Expression _parsePrecedence(Expression left, int precedence) { 49 Expression _parsePrecedence(Expression left, int precedence) {
50 assert(left != null); 50 assert(left != null);
51 while (_token != null) { 51 while (_token != null) {
52 if (_token.kind == GROUPER_TOKEN) { 52 if (_token.kind == GROUPER_TOKEN) {
53 if (_token.value == '(') { 53 if (_token.value == '(') {
54 var args = _parseArguments(); 54 var args = _parseArguments();
55 assert(args != null);
55 left = _astFactory.invoke(left, null, args); 56 left = _astFactory.invoke(left, null, args);
56 } else if (_token.value == '[') { 57 } else if (_token.value == '[') {
57 var indexExpr = _parseIndex(); 58 var indexExpr = _parseIndex();
58 var args = indexExpr == null ? [] : [indexExpr]; 59 left = _astFactory.index(left, indexExpr);
59 left = _astFactory.invoke(left, '[]', args);
60 } else { 60 } else {
61 break; 61 break;
62 } 62 }
63 } else if (_token.kind == DOT_TOKEN) { 63 } else if (_token.kind == DOT_TOKEN) {
64 _advance(); 64 _advance();
65 var right = _parseUnary(); 65 var right = _parseUnary();
66 left = _makeInvoke(left, right); 66 left = _makeInvokeOrGetter(left, right);
67 } else if (_token.kind == KEYWORD_TOKEN && _token.value == 'in') { 67 } else if (_token.kind == KEYWORD_TOKEN && _token.value == 'in') {
68 left = _parseComprehension(left); 68 left = _parseComprehension(left);
69 } else if (_token.kind == OPERATOR_TOKEN 69 } else if (_token.kind == OPERATOR_TOKEN
70 && _token.precedence >= precedence) { 70 && _token.precedence >= precedence) {
71 left = _parseBinary(left); 71 left = _parseBinary(left);
72 } else { 72 } else {
73 break; 73 break;
74 } 74 }
75 } 75 }
76 return left; 76 return left;
77 } 77 }
78 78
79 Invoke _makeInvoke(left, right) { 79 // invoke or getter
80 Expression _makeInvokeOrGetter(left, right) {
80 if (right is Identifier) { 81 if (right is Identifier) {
81 return _astFactory.invoke(left, right.value); 82 return _astFactory.getter(left, right.value);
82 } else if (right is Invoke && right.receiver is Identifier) { 83 } else if (right is Invoke && right.receiver is Identifier) {
83 Identifier method = right.receiver; 84 Identifier method = right.receiver;
84 return _astFactory.invoke(left, method.value, right.arguments); 85 return _astFactory.invoke(left, method.value, right.arguments);
85 } else { 86 } else {
86 throw new ParseException("expected identifier: $right"); 87 throw new ParseException("expected identifier: $right");
87 } 88 }
88 } 89 }
89 90
90 Expression _parseBinary(left) { 91 Expression _parseBinary(left) {
91 var op = _token; 92 var op = _token;
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 } 203 }
203 var identifier = _parseIdentifier(); 204 var identifier = _parseIdentifier();
204 var args = _parseArguments(); 205 var args = _parseArguments();
205 if (args == null) { 206 if (args == null) {
206 return identifier; 207 return identifier;
207 } else { 208 } else {
208 return _astFactory.invoke(identifier, null, args); 209 return _astFactory.invoke(identifier, null, args);
209 } 210 }
210 } 211 }
211 212
212 Invoke _parseInvoke() {
213 var identifier = _parseIdentifier();
214 var args = _parseArguments();
215 return _astFactory.invoke(null, identifier, args);
216 }
217
218 Identifier _parseIdentifier() { 213 Identifier _parseIdentifier() {
219 if (_token.kind != IDENTIFIER_TOKEN) { 214 if (_token.kind != IDENTIFIER_TOKEN) {
220 throw new ParseException("expected identifier: $_token.value"); 215 throw new ParseException("expected identifier: $_token.value");
221 } 216 }
222 var value = _token.value; 217 var value = _token.value;
223 _advance(); 218 _advance();
224 return _astFactory.identifier(value); 219 return _astFactory.identifier(value);
225 } 220 }
226 221
227 List<Expression> _parseArguments() { 222 List<Expression> _parseArguments() {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 return value; 265 return value;
271 } 266 }
272 267
273 Literal<double> _parseDecimal([String prefix = '']) { 268 Literal<double> _parseDecimal([String prefix = '']) {
274 var value = _astFactory.literal(double.parse('$prefix${_token.value}')); 269 var value = _astFactory.literal(double.parse('$prefix${_token.value}'));
275 _advance(); 270 _advance();
276 return value; 271 return value;
277 } 272 }
278 273
279 } 274 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698