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

Side by Side Diff: lib/compiler/implementation/scanner/parser.dart

Issue 9958009: Implement cascaded calls. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Update tests. Fix scanner. Created 8 years, 8 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 /** 5 /**
6 * An event generating parser of Dart programs. This parser expects 6 * An event generating parser of Dart programs. This parser expects
7 * all tokens in a linked list. 7 * all tokens in a linked list.
8 */ 8 */
9 class Parser { 9 class Parser {
10 final Listener listener; 10 final Listener listener;
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 token = parseType(token.next); 229 token = parseType(token.next);
230 ++interfacesCount; 230 ++interfacesCount;
231 } while (optional(',', token)); 231 } while (optional(',', token));
232 } 232 }
233 token = parseClassBody(token); 233 token = parseClassBody(token);
234 listener.endClassDeclaration(interfacesCount, begin, extendsKeyword, 234 listener.endClassDeclaration(interfacesCount, begin, extendsKeyword,
235 implementsKeyword, token); 235 implementsKeyword, token);
236 return token.next; 236 return token.next;
237 } 237 }
238 238
239
240 Token parseStringPart(Token token) { 239 Token parseStringPart(Token token) {
241 if (token.kind === STRING_TOKEN) { 240 if (token.kind === STRING_TOKEN) {
242 listener.handleStringPart(token); 241 listener.handleStringPart(token);
243 return token.next; 242 return token.next;
244 } else { 243 } else {
245 return listener.expected('string', token); 244 return listener.expected('string', token);
246 } 245 }
247 } 246 }
248 247
249 Token parseIdentifier(Token token) { 248 Token parseIdentifier(Token token) {
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 } 848 }
850 849
851 Token parseExpressionStatement(Token token) { 850 Token parseExpressionStatement(Token token) {
852 listener.beginExpressionStatement(token); 851 listener.beginExpressionStatement(token);
853 token = parseExpression(token); 852 token = parseExpression(token);
854 listener.endExpressionStatement(token); 853 listener.endExpressionStatement(token);
855 return expectSemicolon(token); 854 return expectSemicolon(token);
856 } 855 }
857 856
858 Token parseExpression(Token token) { 857 Token parseExpression(Token token) {
859 return parsePrecedenceExpression(token, 2); 858 return parsePrecedenceExpression(token, SEQUENCE_PRECEDENCE);
860 } 859 }
861 860
862 Token parseConditionalExpressionRest(Token token) { 861 Token parseConditionalExpressionRest(Token token) {
863 assert(optional('?', token)); 862 assert(optional('?', token));
864 Token question = token; 863 Token question = token;
865 token = parseExpression(token.next); 864 token = parseExpression(token.next);
866 Token colon = token; 865 Token colon = token;
867 token = expect(':', token); 866 token = expect(':', token);
868 token = parseExpression(token); 867 token = parseExpression(token);
869 listener.handleConditionalExpression(question, colon); 868 listener.handleConditionalExpression(question, colon);
870 return token; 869 return token;
871 } 870 }
872 871
873 Token parsePrecedenceExpression(Token token, int precedence) { 872 Token parsePrecedenceExpression(Token token, int precedence) {
874 assert(precedence >= 2); 873 assert(precedence >= 1);
875 assert(precedence <= POSTFIX_PRECEDENCE); 874 assert(precedence <= POSTFIX_PRECEDENCE);
876 token = parseUnaryExpression(token); 875 token = parseUnaryExpression(token);
877 PrecedenceInfo info = token.info; 876 PrecedenceInfo info = token.info;
878 int tokenLevel = info.precedence; 877 int tokenLevel = info.precedence;
879 for (int level = tokenLevel; level >= precedence; --level) { 878 for (int level = tokenLevel; level >= precedence; --level) {
880 while (tokenLevel === level) { 879 while (tokenLevel === level) {
881 Token operator = token; 880 Token operator = token;
882 if (tokenLevel === ASSIGNMENT_PRECEDENCE) { 881 if (tokenLevel === SEQUENCE_PRECEDENCE) {
882 token = parseCascadeExpression(token);
883 } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) {
883 // Right associative, so we recurse at the same precedence 884 // Right associative, so we recurse at the same precedence
884 // level. 885 // level.
885 token = parsePrecedenceExpression(token.next, level); 886 token = parsePrecedenceExpression(token.next, level);
886 listener.handleAssignmentExpression(operator); 887 listener.handleAssignmentExpression(operator);
887 } else if (tokenLevel === POSTFIX_PRECEDENCE) { 888 } else if (tokenLevel === POSTFIX_PRECEDENCE) {
888 if (info === PERIOD_INFO) { 889 if (info === PERIOD_INFO) {
889 // Left associative, so we recurse at the next higher 890 // Left associative, so we recurse at the next higher
890 // precedence level. However, POSTFIX_PRECEDENCE is the 891 // precedence level. However, POSTFIX_PRECEDENCE is the
891 // highest level, so we just call parseUnaryExpression 892 // highest level, so we just call parseUnaryExpression
892 // directly. 893 // directly.
(...skipping 19 matching lines...) Expand all
912 token = parsePrecedenceExpression(token.next, level + 1); 913 token = parsePrecedenceExpression(token.next, level + 1);
913 listener.handleBinaryExpression(operator); 914 listener.handleBinaryExpression(operator);
914 } 915 }
915 info = token.info; 916 info = token.info;
916 tokenLevel = info.precedence; 917 tokenLevel = info.precedence;
917 } 918 }
918 } 919 }
919 return token; 920 return token;
920 } 921 }
921 922
923 Token parseCascadeExpression(Token token) {
924 Token next = expect('..', token);
ahe 2012/04/16 08:55:23 I normally use: assert(optional('..', token))
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
925 listener.beginCascade(token);
ahe 2012/04/16 08:55:23 In general, it is best to call the begin method be
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
926 if (optional('[', next)) {
927 next = parseArgumentOrIndexStar(next);
ahe 2012/04/16 08:55:23 Normally, I use this pattern: token = parse... T
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
928 } else if (next.kind == IDENTIFIER_TOKEN) {
ahe 2012/04/16 08:55:23 What if it is a pseudo keyword? Perhaps you should
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
929 next = parseSend(next);
930 listener.handleBinaryExpression(token);
ahe 2012/04/16 08:55:23 For example, this sequence is confusing (to me) be
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Changed to have a more readable name for token.
931 } else {
932 return listener.unexpected(next);
933 }
934 Token mark;
935 do {
936 mark = next;
937 if (optional('.', next)) {
938 Token dot = next;
ahe 2012/04/16 08:55:23 I have used the word "period" instead of "dot" in
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
939 next = parseSend(dot.next);
940 listener.handleBinaryExpression(dot);
941 }
942 next = parseArgumentOrIndexStar(next);
943 } while (mark != next);
ahe 2012/04/16 08:55:23 !==
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
944
945 if (next.info.precedence == ASSIGNMENT_PRECEDENCE) {
ahe 2012/04/16 08:55:23 ===
Lasse Reichstein Nielsen 2012/04/16 12:41:38 Done.
946 Token assignment = next;
947 next = parsePrecedenceExpression(next.next, SEQUENCE_PRECEDENCE + 1);
ahe 2012/04/16 08:55:23 Question to make sure I understand what is going o
Lasse Reichstein Nielsen 2012/04/16 12:41:38 You should be able to write that. It would parse a
948 listener.handleAssignmentExpression(assignment);
949 }
950 listener.endCascade();
951 return next;
952 }
953
922 Token parseUnaryExpression(Token token) { 954 Token parseUnaryExpression(Token token) {
923 String value = token.stringValue; 955 String value = token.stringValue;
924 // Prefix: 956 // Prefix:
925 if (value === '+') { 957 if (value === '+') {
926 // Dart only allows "prefix plus" as an initial part of a 958 // Dart only allows "prefix plus" as an initial part of a
927 // decimal literal. We scan it as a separate token and let 959 // decimal literal. We scan it as a separate token and let
928 // the parser listener combine it with the digits. 960 // the parser listener combine it with the digits.
929 Token next = token.next; 961 Token next = token.next;
930 if (next.charOffset === token.charOffset + 1) { 962 if (next.charOffset === token.charOffset + 1) {
931 if (next.kind === INT_TOKEN) { 963 if (next.kind === INT_TOKEN) {
(...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 } 1615 }
1584 listener.handleContinueStatement(hasTarget, continueKeyword, token); 1616 listener.handleContinueStatement(hasTarget, continueKeyword, token);
1585 return expectSemicolon(token); 1617 return expectSemicolon(token);
1586 } 1618 }
1587 1619
1588 Token parseEmptyStatement(Token token) { 1620 Token parseEmptyStatement(Token token) {
1589 listener.handleEmptyStatement(token); 1621 listener.handleEmptyStatement(token);
1590 return expectSemicolon(token); 1622 return expectSemicolon(token);
1591 } 1623 }
1592 } 1624 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698