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

Side by Side Diff: frog/parser.dart

Issue 9143001: Fixes 2 tests and a crash (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 11 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
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 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 1059
1060 case TokenKind.SUPER: 1060 case TokenKind.SUPER:
1061 _eat(TokenKind.SUPER); 1061 _eat(TokenKind.SUPER);
1062 return new SuperExpression(_makeSpan(start)); 1062 return new SuperExpression(_makeSpan(start));
1063 1063
1064 case TokenKind.CONST: 1064 case TokenKind.CONST:
1065 _eat(TokenKind.CONST); 1065 _eat(TokenKind.CONST);
1066 if (_peekKind(TokenKind.LBRACK) || _peekKind(TokenKind.INDEX)) { 1066 if (_peekKind(TokenKind.LBRACK) || _peekKind(TokenKind.INDEX)) {
1067 return finishListLiteral(start, true, null); 1067 return finishListLiteral(start, true, null);
1068 } else if (_peekKind(TokenKind.LBRACE)) { 1068 } else if (_peekKind(TokenKind.LBRACE)) {
1069 return finishMapLiteral(start, true, null); 1069 return finishMapLiteral(start, true, null, null);
1070 } else if (_peekKind(TokenKind.LT)) { 1070 } else if (_peekKind(TokenKind.LT)) {
1071 return finishTypedLiteral(start, true); 1071 return finishTypedLiteral(start, true);
1072 } else { 1072 } else {
1073 return finishNewExpression(start, true); 1073 return finishNewExpression(start, true);
1074 } 1074 }
1075 1075
1076 case TokenKind.NEW: 1076 case TokenKind.NEW:
1077 _eat(TokenKind.NEW); 1077 _eat(TokenKind.NEW);
1078 return finishNewExpression(start, false); 1078 return finishNewExpression(start, false);
1079 1079
1080 case TokenKind.LPAREN: 1080 case TokenKind.LPAREN:
1081 return _parenOrLambda(); 1081 return _parenOrLambda();
1082 1082
1083 case TokenKind.LBRACK: 1083 case TokenKind.LBRACK:
1084 case TokenKind.INDEX: 1084 case TokenKind.INDEX:
1085 return finishListLiteral(start, false, null); 1085 return finishListLiteral(start, false, null);
1086 case TokenKind.LBRACE: 1086 case TokenKind.LBRACE:
1087 return finishMapLiteral(start, false, null); 1087 return finishMapLiteral(start, false, null, null);
1088 1088
1089 // Literals 1089 // Literals
1090 case TokenKind.NULL: 1090 case TokenKind.NULL:
1091 _eat(TokenKind.NULL); 1091 _eat(TokenKind.NULL);
1092 return _makeLiteral(Value.fromNull(_makeSpan(start))); 1092 return _makeLiteral(Value.fromNull(_makeSpan(start)));
1093 1093
1094 // TODO(jimhug): Make Literal creation less wasteful - no dup span/text. 1094 // TODO(jimhug): Make Literal creation less wasteful - no dup span/text.
1095 case TokenKind.TRUE: 1095 case TokenKind.TRUE:
1096 _eat(TokenKind.TRUE); 1096 _eat(TokenKind.TRUE);
1097 return _makeLiteral(Value.fromBool(true, _makeSpan(start))); 1097 return _makeLiteral(Value.fromBool(true, _makeSpan(start)));
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 finishNewExpression(int start, bool isConst) { 1337 finishNewExpression(int start, bool isConst) {
1338 var type = type(); 1338 var type = type();
1339 var name = null; 1339 var name = null;
1340 if (_maybeEat(TokenKind.DOT)) { 1340 if (_maybeEat(TokenKind.DOT)) {
1341 name = identifier(); 1341 name = identifier();
1342 } 1342 }
1343 var args = arguments(); 1343 var args = arguments();
1344 return new NewExpression(isConst, type, name, args, _makeSpan(start)); 1344 return new NewExpression(isConst, type, name, args, _makeSpan(start));
1345 } 1345 }
1346 1346
1347 finishListLiteral(int start, bool isConst, TypeReference type) { 1347 finishListLiteral(int start, bool isConst, TypeReference itemType) {
1348 if (_maybeEat(TokenKind.INDEX)) { 1348 if (_maybeEat(TokenKind.INDEX)) {
1349 // This is an empty array. 1349 // This is an empty array.
1350 return new ListExpression(isConst, type, [], _makeSpan(start)); 1350 return new ListExpression(isConst, itemType, [], _makeSpan(start));
1351 } 1351 }
1352 1352
1353 var values = []; 1353 var values = [];
1354 _eat(TokenKind.LBRACK); 1354 _eat(TokenKind.LBRACK);
1355 while (!_maybeEat(TokenKind.RBRACK)) { 1355 while (!_maybeEat(TokenKind.RBRACK)) {
1356 values.add(expression()); 1356 values.add(expression());
1357 if (_recover && !_recoverTo(TokenKind.RBRACK, TokenKind.COMMA)) break; 1357 if (_recover && !_recoverTo(TokenKind.RBRACK, TokenKind.COMMA)) break;
1358 if (!_maybeEat(TokenKind.COMMA)) { 1358 if (!_maybeEat(TokenKind.COMMA)) {
1359 _eat(TokenKind.RBRACK); 1359 _eat(TokenKind.RBRACK);
1360 break; 1360 break;
1361 } 1361 }
1362 } 1362 }
1363 return new ListExpression(isConst, type, values, _makeSpan(start)); 1363 return new ListExpression(isConst, itemType, values, _makeSpan(start));
1364 } 1364 }
1365 1365
1366 finishMapLiteral(int start, bool isConst, TypeReference type) { 1366 finishMapLiteral(int start, bool isConst,
1367 TypeReference keyType, TypeReference valueType) {
1367 var items = []; 1368 var items = [];
1368 _eat(TokenKind.LBRACE); 1369 _eat(TokenKind.LBRACE);
1369 while (!_maybeEat(TokenKind.RBRACE)) { 1370 while (!_maybeEat(TokenKind.RBRACE)) {
1370 // This is deliberately overly permissive - checked in later pass. 1371 // This is deliberately overly permissive - checked in later pass.
1371 items.add(expression()); 1372 items.add(expression());
1372 _eat(TokenKind.COLON); 1373 _eat(TokenKind.COLON);
1373 items.add(expression()); 1374 items.add(expression());
1374 if (_recover && !_recoverTo(TokenKind.RBRACE, TokenKind.COMMA)) break; 1375 if (_recover && !_recoverTo(TokenKind.RBRACE, TokenKind.COMMA)) break;
1375 if (!_maybeEat(TokenKind.COMMA)) { 1376 if (!_maybeEat(TokenKind.COMMA)) {
1376 _eat(TokenKind.RBRACE); 1377 _eat(TokenKind.RBRACE);
1377 break; 1378 break;
1378 } 1379 }
1379 } 1380 }
1380 return new MapExpression(isConst, type, items, _makeSpan(start)); 1381 return new MapExpression(isConst, keyType, valueType, items,
1382 _makeSpan(start));
1381 } 1383 }
1382 1384
1383 finishTypedLiteral(int start, bool isConst) { 1385 finishTypedLiteral(int start, bool isConst) {
1384 var span = _makeSpan(start); 1386 var span = _makeSpan(start);
1385 var typeToBeNamedLater = new NameTypeReference(false, null, null, span); 1387
1386 var genericType = addTypeArguments(typeToBeNamedLater, 0); 1388 final typeToBeNamedLater = new NameTypeReference(false, null, null, span);
1389 final genericType = addTypeArguments(typeToBeNamedLater, 0);
1390 final typeArgs = genericType.typeArguments;
1387 1391
1388 if (_peekKind(TokenKind.LBRACK) || _peekKind(TokenKind.INDEX)) { 1392 if (_peekKind(TokenKind.LBRACK) || _peekKind(TokenKind.INDEX)) {
1389 genericType.baseType = new TypeReference(span, world.listType); 1393 if (typeArgs.length != 1) {
1390 return finishListLiteral(start, isConst, genericType); 1394 world.error('exactly one type argument expected for list',
1395 genericType.span);
1396 }
1397 return finishListLiteral(start, isConst, typeArgs[0]);
1391 } else if (_peekKind(TokenKind.LBRACE)) { 1398 } else if (_peekKind(TokenKind.LBRACE)) {
1392 genericType.baseType = new TypeReference(span, world.mapType); 1399 var keyType, valueType;
1393 final typeArgs = genericType.typeArguments;
1394 // TODO(sigmund): Would be nice to allow arbitrary keys here (this is
1395 // currently not allowed by the spec).
1396 if (typeArgs.length == 1) { 1400 if (typeArgs.length == 1) {
1397 genericType.typeArguments = 1401 keyType = null;
1398 [new TypeReference(span, world.stringType), typeArgs[0]]; 1402 valueType = typeArgs[0];
1399 } else if (typeArgs.length == 2) { 1403 } else if (typeArgs.length == 2) {
1400 var keyType = typeArgs[0]; 1404 var keyType = typeArgs[0];
1401 if (keyType is! NameTypeReference || keyType.name.name != "String") { 1405 // making key explicit is just a warning.
1402 world.error('the key type of a map literal is implicitly "String"', 1406 world.warning(
1403 keyType.span); 1407 'a map literal takes one type argument specifying the value type',
1404 } else { 1408 keyType.span);
1405 // making key explicit is just a warning. 1409 valueType = typeArgs[1];
1406 world.warning(
1407 'a map literal takes one type argument specifying the value type',
1408 keyType.span);
1409 }
1410 } // o.w. the type system will detect the mismatch in type arguments. 1410 } // o.w. the type system will detect the mismatch in type arguments.
1411 return finishMapLiteral(start, isConst, genericType); 1411 return finishMapLiteral(start, isConst, keyType, valueType);
1412 } else { 1412 } else {
1413 _errorExpected('array or map literal'); 1413 _errorExpected('array or map literal');
1414 } 1414 }
1415 } 1415 }
1416 1416
1417 /////////////////////////////////////////////////////////////////// 1417 ///////////////////////////////////////////////////////////////////
1418 // Some auxilary productions. 1418 // Some auxilary productions.
1419 /////////////////////////////////////////////////////////////////// 1419 ///////////////////////////////////////////////////////////////////
1420 _readModifiers() { 1420 _readModifiers() {
1421 var modifiers = null; 1421 var modifiers = null;
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 int _pos = 0; 1699 int _pos = 0;
1700 next() { 1700 next() {
1701 var token = tokens[_pos]; 1701 var token = tokens[_pos];
1702 ++_pos; 1702 ++_pos;
1703 if (_pos == tokens.length) { 1703 if (_pos == tokens.length) {
1704 parser.tokenizer = previousTokenizer; 1704 parser.tokenizer = previousTokenizer;
1705 } 1705 }
1706 return token; 1706 return token;
1707 } 1707 }
1708 } 1708 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698