Index: lib/compiler/implementation/scanner/parser.dart |
diff --git a/lib/compiler/implementation/scanner/parser.dart b/lib/compiler/implementation/scanner/parser.dart |
index aad8ee44c54f71f6d39cf3940c7f7cb29830128a..08dd46e5e740f0d69d878b73e94d200983198a14 100644 |
--- a/lib/compiler/implementation/scanner/parser.dart |
+++ b/lib/compiler/implementation/scanner/parser.dart |
@@ -236,7 +236,6 @@ class Parser { |
return token.next; |
} |
- |
Token parseStringPart(Token token) { |
if (token.kind === STRING_TOKEN) { |
listener.handleStringPart(token); |
@@ -856,7 +855,7 @@ class Parser { |
} |
Token parseExpression(Token token) { |
- return parsePrecedenceExpression(token, 2); |
+ return parsePrecedenceExpression(token, SEQUENCE_PRECEDENCE); |
} |
Token parseConditionalExpressionRest(Token token) { |
@@ -871,7 +870,7 @@ class Parser { |
} |
Token parsePrecedenceExpression(Token token, int precedence) { |
- assert(precedence >= 2); |
+ assert(precedence >= 1); |
assert(precedence <= POSTFIX_PRECEDENCE); |
token = parseUnaryExpression(token); |
PrecedenceInfo info = token.info; |
@@ -879,7 +878,9 @@ class Parser { |
for (int level = tokenLevel; level >= precedence; --level) { |
while (tokenLevel === level) { |
Token operator = token; |
- if (tokenLevel === ASSIGNMENT_PRECEDENCE) { |
+ if (tokenLevel === SEQUENCE_PRECEDENCE) { |
+ token = parseCascadeExpression(token); |
+ } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) { |
// Right associative, so we recurse at the same precedence |
// level. |
token = parsePrecedenceExpression(token.next, level); |
@@ -919,6 +920,37 @@ class Parser { |
return token; |
} |
+ Token parseCascadeExpression(Token token) { |
+ 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.
|
+ 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.
|
+ if (optional('[', next)) { |
+ 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.
|
+ } 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.
|
+ next = parseSend(next); |
+ 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.
|
+ } else { |
+ return listener.unexpected(next); |
+ } |
+ Token mark; |
+ do { |
+ mark = next; |
+ if (optional('.', next)) { |
+ 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.
|
+ next = parseSend(dot.next); |
+ listener.handleBinaryExpression(dot); |
+ } |
+ next = parseArgumentOrIndexStar(next); |
+ } while (mark != next); |
ahe
2012/04/16 08:55:23
!==
Lasse Reichstein Nielsen
2012/04/16 12:41:38
Done.
|
+ |
+ if (next.info.precedence == ASSIGNMENT_PRECEDENCE) { |
ahe
2012/04/16 08:55:23
===
Lasse Reichstein Nielsen
2012/04/16 12:41:38
Done.
|
+ Token assignment = next; |
+ 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
|
+ listener.handleAssignmentExpression(assignment); |
+ } |
+ listener.endCascade(); |
+ return next; |
+ } |
+ |
Token parseUnaryExpression(Token token) { |
String value = token.stringValue; |
// Prefix: |