Chromium Code Reviews| OLD | NEW |
|---|---|
| 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; |
| 11 bool mayParseFunctionExpressions = true; | 11 bool mayParseFunctionExpressions = true; |
| 12 bool mayParseCascades = true; | |
|
ahe
2012/04/26 14:33:30
Does this need to be a global flag?
Lasse Reichstein Nielsen
2012/04/27 07:08:31
Actually not. Passing it to just parsePrecedenceEx
| |
| 12 | 13 |
| 13 Parser(Listener this.listener); | 14 Parser(Listener this.listener); |
| 14 | 15 |
| 15 void parseUnit(Token token) { | 16 void parseUnit(Token token) { |
| 16 while (token.kind !== EOF_TOKEN) { | 17 while (token.kind !== EOF_TOKEN) { |
| 17 token = parseTopLevelDeclaration(token); | 18 token = parseTopLevelDeclaration(token); |
| 18 } | 19 } |
| 19 } | 20 } |
| 20 | 21 |
| 21 Token parseTopLevelDeclaration(Token token) { | 22 Token parseTopLevelDeclaration(Token token) { |
| (...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 } | 849 } |
| 849 | 850 |
| 850 Token parseExpressionStatement(Token token) { | 851 Token parseExpressionStatement(Token token) { |
| 851 listener.beginExpressionStatement(token); | 852 listener.beginExpressionStatement(token); |
| 852 token = parseExpression(token); | 853 token = parseExpression(token); |
| 853 listener.endExpressionStatement(token); | 854 listener.endExpressionStatement(token); |
| 854 return expectSemicolon(token); | 855 return expectSemicolon(token); |
| 855 } | 856 } |
| 856 | 857 |
| 857 Token parseExpression(Token token) { | 858 Token parseExpression(Token token) { |
| 858 return parsePrecedenceExpression(token, CASCADE_PRECEDENCE); | 859 bool couldParseCascades = mayParseCascades; |
| 860 mayParseCascades = true; | |
| 861 Token result = parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE); | |
| 862 mayParseCascades = couldParseCascades; | |
| 863 return result; | |
| 864 } | |
| 865 | |
| 866 Token parseExpressionWithoutCascade(Token token) { | |
| 867 bool couldParseCascades = mayParseCascades; | |
| 868 mayParseCascades = false; | |
| 869 Token result = parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE); | |
| 870 mayParseCascades = couldParseCascades; | |
| 871 return result; | |
| 859 } | 872 } |
| 860 | 873 |
| 861 Token parseConditionalExpressionRest(Token token) { | 874 Token parseConditionalExpressionRest(Token token) { |
| 862 assert(optional('?', token)); | 875 assert(optional('?', token)); |
| 863 Token question = token; | 876 Token question = token; |
| 864 token = parseExpression(token.next); | 877 token = parseExpressionWithoutCascade(token.next); |
| 865 Token colon = token; | 878 Token colon = token; |
| 866 token = expect(':', token); | 879 token = expect(':', token); |
| 867 token = parseExpression(token); | 880 token = parseExpressionWithoutCascade(token); |
| 868 listener.handleConditionalExpression(question, colon); | 881 listener.handleConditionalExpression(question, colon); |
| 869 return token; | 882 return token; |
| 870 } | 883 } |
| 871 | 884 |
| 872 Token parsePrecedenceExpression(Token token, int precedence) { | 885 Token parsePrecedenceExpression(Token token, int precedence) { |
| 873 assert(precedence >= 1); | 886 assert(precedence >= 1); |
| 874 assert(precedence <= POSTFIX_PRECEDENCE); | 887 assert(precedence <= POSTFIX_PRECEDENCE); |
| 875 token = parseUnaryExpression(token); | 888 token = parseUnaryExpression(token); |
| 876 PrecedenceInfo info = token.info; | 889 PrecedenceInfo info = token.info; |
| 877 int tokenLevel = info.precedence; | 890 int tokenLevel = info.precedence; |
| 878 for (int level = tokenLevel; level >= precedence; --level) { | 891 for (int level = tokenLevel; level >= precedence; --level) { |
| 879 while (tokenLevel === level) { | 892 while (tokenLevel === level) { |
| 880 Token operator = token; | 893 Token operator = token; |
| 881 if (tokenLevel === CASCADE_PRECEDENCE) { | 894 if (tokenLevel === CASCADE_PRECEDENCE) { |
| 895 if (!mayParseCascades) { | |
|
Lasse Reichstein Nielsen
2012/04/27 07:08:31
Another alternative here is to start the outer for
| |
| 896 return token; | |
| 897 } | |
| 882 token = parseCascadeExpression(token); | 898 token = parseCascadeExpression(token); |
| 883 } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) { | 899 } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) { |
| 884 // Right associative, so we recurse at the same precedence | 900 // Right associative, so we recurse at the same precedence |
| 885 // level. | 901 // level. |
| 886 token = parsePrecedenceExpression(token.next, level); | 902 token = parsePrecedenceExpression(token.next, level); |
| 887 listener.handleAssignmentExpression(operator); | 903 listener.handleAssignmentExpression(operator); |
| 888 } else if (tokenLevel === POSTFIX_PRECEDENCE) { | 904 } else if (tokenLevel === POSTFIX_PRECEDENCE) { |
| 889 if (info === PERIOD_INFO) { | 905 if (info === PERIOD_INFO) { |
| 890 // Left associative, so we recurse at the next higher | 906 // Left associative, so we recurse at the next higher |
| 891 // precedence level. However, POSTFIX_PRECEDENCE is the | 907 // precedence level. However, POSTFIX_PRECEDENCE is the |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 939 if (optional('.', token)) { | 955 if (optional('.', token)) { |
| 940 Token period = token; | 956 Token period = token; |
| 941 token = parseSend(token.next); | 957 token = parseSend(token.next); |
| 942 listener.handleBinaryExpression(period); | 958 listener.handleBinaryExpression(period); |
| 943 } | 959 } |
| 944 token = parseArgumentOrIndexStar(token); | 960 token = parseArgumentOrIndexStar(token); |
| 945 } while (mark !== token); | 961 } while (mark !== token); |
| 946 | 962 |
| 947 if (token.info.precedence === ASSIGNMENT_PRECEDENCE) { | 963 if (token.info.precedence === ASSIGNMENT_PRECEDENCE) { |
| 948 Token assignment = token; | 964 Token assignment = token; |
| 949 token = parsePrecedenceExpression(token.next, CASCADE_PRECEDENCE + 1); | 965 token = parseExpressionWithoutCascade(token.next); |
| 950 listener.handleAssignmentExpression(assignment); | 966 listener.handleAssignmentExpression(assignment); |
| 951 } | 967 } |
| 952 listener.endCascade(); | 968 listener.endCascade(); |
| 953 return token; | 969 return token; |
| 954 } | 970 } |
| 955 | 971 |
| 956 Token parseUnaryExpression(Token token) { | 972 Token parseUnaryExpression(Token token) { |
| 957 String value = token.stringValue; | 973 String value = token.stringValue; |
| 958 // Prefix: | 974 // Prefix: |
| 959 if (value === '+') { | 975 if (value === '+') { |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1619 } | 1635 } |
| 1620 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1636 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1621 return expectSemicolon(token); | 1637 return expectSemicolon(token); |
| 1622 } | 1638 } |
| 1623 | 1639 |
| 1624 Token parseEmptyStatement(Token token) { | 1640 Token parseEmptyStatement(Token token) { |
| 1625 listener.handleEmptyStatement(token); | 1641 listener.handleEmptyStatement(token); |
| 1626 return expectSemicolon(token); | 1642 return expectSemicolon(token); |
| 1627 } | 1643 } |
| 1628 } | 1644 } |
| OLD | NEW |