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

Side by Side Diff: frog/parser.dart

Issue 8774039: Fix for Issue 622 (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: frogsh Created 9 years 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 | « frog/gen.dart ('k') | tests/language/language.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 4
5 // TODO(jimhug): Error recovery needs major work! 5 // TODO(jimhug): Error recovery needs major work!
6 /** 6 /**
7 * A simple recursive descent parser for the dart language. 7 * A simple recursive descent parser for the dart language.
8 * 8 *
9 * This parser is designed to be more permissive than the official 9 * This parser is designed to be more permissive than the official
10 * Dart grammar. It is expected that many grammar errors would be 10 * Dart grammar. It is expected that many grammar errors would be
(...skipping 16 matching lines...) Expand all
27 /** Allow semicolons to be omitted at the end of lines. */ 27 /** Allow semicolons to be omitted at the end of lines. */
28 // TODO(nweiz): make this work for more than just end-of-file 28 // TODO(nweiz): make this work for more than just end-of-file
29 final bool optionalSemicolons; 29 final bool optionalSemicolons;
30 30
31 /** 31 /**
32 * Allow the await keyword, when the await transformation is available (see 32 * Allow the await keyword, when the await transformation is available (see
33 * await/awaitc.dart). 33 * await/awaitc.dart).
34 */ 34 */
35 bool get enableAwait() => experimentalAwaitPhase != null; 35 bool get enableAwait() => experimentalAwaitPhase != null;
36 36
37 /** To prevent conflicts in initializers */ 37 /**
38 bool _inInitializers; 38 * To resolve ambiguity in initializers between constructor body and lambda
39 * expression.
40 */
41 bool _inhibitLambda;
39 42
40 Token _previousToken; 43 Token _previousToken;
41 Token _peekToken; 44 Token _peekToken;
42 45
43 // When we encounter '(' in a method body we need to find the ')' to know it 46 // When we encounter '(' in a method body we need to find the ')' to know it
44 // we're parsing a lambda, paren-expr, or argument list. Closure formals are 47 // we're parsing a lambda, paren-expr, or argument list. Closure formals are
45 // followed by '=>' or '{'. This list is used to cache the tokens after any 48 // followed by '=>' or '{'. This list is used to cache the tokens after any
46 // nested parenthesis we find while peeking. 49 // nested parenthesis we find while peeking.
47 // TODO(jmesserly): it's simpler and faster to cache this on the Token itself, 50 // TODO(jmesserly): it's simpler and faster to cache this on the Token itself,
48 // but that might add too much complexity for tools that need to invalidate. 51 // but that might add too much complexity for tools that need to invalidate.
49 List<Token> _afterParens; 52 List<Token> _afterParens;
50 int _afterParensIndex = 0; 53 int _afterParensIndex = 0;
51 54
52 Parser(this.source, [this.diet = false, this.throwOnIncomplete = false, 55 Parser(this.source, [this.diet = false, this.throwOnIncomplete = false,
53 this.optionalSemicolons = false, int startOffset = 0]) { 56 this.optionalSemicolons = false, int startOffset = 0]) {
54 tokenizer = new Tokenizer(source, true, startOffset); 57 tokenizer = new Tokenizer(source, true, startOffset);
55 _peekToken = tokenizer.next(); 58 _peekToken = tokenizer.next();
56 _previousToken = null; 59 _previousToken = null;
57 _inInitializers = false; 60 _inhibitLambda = false;
58 _afterParens = <Token>[]; 61 _afterParens = <Token>[];
59 } 62 }
60 63
61 /** Generate an error if [source] has not been completely consumed. */ 64 /** Generate an error if [source] has not been completely consumed. */
62 void checkEndOfFile() { 65 void checkEndOfFile() {
63 _eat(TokenKind.END_OF_FILE); 66 _eat(TokenKind.END_OF_FILE);
64 } 67 }
65 68
66 /** Guard to break out of parser when an unexpected end of file is found. */ 69 /** Guard to break out of parser when an unexpected end of file is found. */
67 // TODO(jimhug): Failure to call this method can lead to inifinite parser 70 // TODO(jimhug): Failure to call this method can lead to inifinite parser
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 var formals = formalParameterList(); 280 var formals = formalParameterList();
278 _eatSemicolon(); 281 _eatSemicolon();
279 282
280 var func = new FunctionDefinition(null, di.type, di.name, formals, 283 var func = new FunctionDefinition(null, di.type, di.name, formals,
281 null, null, null, null, _makeSpan(start)); 284 null, null, null, null, _makeSpan(start));
282 285
283 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start)); 286 return new FunctionTypeDefinition(func, typeParams, _makeSpan(start));
284 } 287 }
285 288
286 initializers() { 289 initializers() {
287 _inInitializers = true; 290 _inhibitLambda = true;
288 var ret = []; 291 var ret = [];
289 do { 292 do {
290 ret.add(expression()); 293 ret.add(expression());
291 } while (_maybeEat(TokenKind.COMMA)); 294 } while (_maybeEat(TokenKind.COMMA));
292 _inInitializers = false; 295 _inhibitLambda = false;
293 return ret; 296 return ret;
294 } 297 }
295 298
296 functionBody(bool inExpression) { 299 functionBody(bool inExpression) {
297 int start = _peekToken.start; 300 int start = _peekToken.start;
298 if (_maybeEat(TokenKind.ARROW)) { 301 if (_maybeEat(TokenKind.ARROW)) {
299 var expr = expression(); 302 var expr = expression();
300 if (!inExpression) { 303 if (!inExpression) {
301 _eatSemicolon(); 304 _eatSemicolon();
302 } 305 }
(...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 if (label === null && _maybeEat(TokenKind.COLON)) { 925 if (label === null && _maybeEat(TokenKind.COLON)) {
923 label = _makeLabel(expr); 926 label = _makeLabel(expr);
924 expr = expression(); 927 expr = expression();
925 } 928 }
926 return new ArgumentNode(label, expr, _makeSpan(start)); 929 return new ArgumentNode(label, expr, _makeSpan(start));
927 } 930 }
928 931
929 arguments() { 932 arguments() {
930 var args = []; 933 var args = [];
931 _eatLeftParen(); 934 _eatLeftParen();
935 var saved = _inhibitLambda;
936 _inhibitLambda = false;
932 if (!_maybeEat(TokenKind.RPAREN)) { 937 if (!_maybeEat(TokenKind.RPAREN)) {
933 do { 938 do {
934 args.add(argument()); 939 args.add(argument());
935 } while (_maybeEat(TokenKind.COMMA)); 940 } while (_maybeEat(TokenKind.COMMA));
936 _eat(TokenKind.RPAREN); 941 _eat(TokenKind.RPAREN);
937 } 942 }
943 _inhibitLambda = saved;
938 return args; 944 return args;
939 } 945 }
940 946
941 finishPostfixExpression(expr) { 947 finishPostfixExpression(expr) {
942 switch(_peek()) { 948 switch(_peek()) {
943 case TokenKind.LPAREN: 949 case TokenKind.LPAREN:
944 return finishCallOrLambdaExpression(expr); 950 return finishCallOrLambdaExpression(expr);
945 case TokenKind.LBRACK: 951 case TokenKind.LBRACK:
946 _eat(TokenKind.LBRACK); 952 _eat(TokenKind.LBRACK);
947 var index = expression(); 953 var index = expression();
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 1178
1173 _parenOrLambda() { 1179 _parenOrLambda() {
1174 int start = _peekToken.start; 1180 int start = _peekToken.start;
1175 if (_atClosureParameters()) { 1181 if (_atClosureParameters()) {
1176 var formals = formalParameterList(); 1182 var formals = formalParameterList();
1177 var body = functionBody(true); 1183 var body = functionBody(true);
1178 var func = new FunctionDefinition(null, null, null, formals, null, null, 1184 var func = new FunctionDefinition(null, null, null, formals, null, null,
1179 null, body, _makeSpan(start)); 1185 null, body, _makeSpan(start));
1180 return new LambdaExpression(func, func.span); 1186 return new LambdaExpression(func, func.span);
1181 } else { 1187 } else {
1182 var saved = _inInitializers; 1188 _eatLeftParen();
1183 _inInitializers = false; 1189 var saved = _inhibitLambda;
1184 var args = arguments(); 1190 _inhibitLambda = false;
1185 _inInitializers = saved; 1191 var expr = expression();
1186 if (args.length == 1) { 1192 _eat(TokenKind.RPAREN);
1187 return new ParenExpression(args[0].value, _makeSpan(start)); 1193 _inhibitLambda = saved;
1188 } else { 1194 return new ParenExpression(expr, _makeSpan(start));
1189 _error('unexpected comma expression');
1190 return args[0].value;
1191 }
1192 } 1195 }
1193 } 1196 }
1194 1197
1195 bool _atClosureParameters() { 1198 bool _atClosureParameters() {
1196 if (_inInitializers) return false; 1199 if (_inhibitLambda) return false;
1197 Token after = _peekAfterCloseParen(); 1200 Token after = _peekAfterCloseParen();
1198 return after.kind == TokenKind.ARROW || after.kind == TokenKind.LBRACE; 1201 return after.kind == TokenKind.ARROW || after.kind == TokenKind.LBRACE;
1199 } 1202 }
1200 1203
1201 /** Eats an LPAREN, and advances our after-RPAREN lookahead. */ 1204 /** Eats an LPAREN, and advances our after-RPAREN lookahead. */
1202 _eatLeftParen() { 1205 _eatLeftParen() {
1203 _eat(TokenKind.LPAREN); 1206 _eat(TokenKind.LPAREN);
1204 _afterParensIndex++; 1207 _afterParensIndex++;
1205 } 1208 }
1206 1209
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 int _pos = 0; 1703 int _pos = 0;
1701 next() { 1704 next() {
1702 var token = tokens[_pos]; 1705 var token = tokens[_pos];
1703 ++_pos; 1706 ++_pos;
1704 if (_pos == tokens.length) { 1707 if (_pos == tokens.length) {
1705 parser.tokenizer = previousTokenizer; 1708 parser.tokenizer = previousTokenizer;
1706 } 1709 }
1707 return token; 1710 return token;
1708 } 1711 }
1709 } 1712 }
OLDNEW
« no previous file with comments | « frog/gen.dart ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698