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; |
| (...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 } | 848 } |
| 849 | 849 |
| 850 Token parseExpressionStatement(Token token) { | 850 Token parseExpressionStatement(Token token) { |
| 851 listener.beginExpressionStatement(token); | 851 listener.beginExpressionStatement(token); |
| 852 token = parseExpression(token); | 852 token = parseExpression(token); |
| 853 listener.endExpressionStatement(token); | 853 listener.endExpressionStatement(token); |
| 854 return expectSemicolon(token); | 854 return expectSemicolon(token); |
| 855 } | 855 } |
| 856 | 856 |
| 857 Token parseExpression(Token token) { | 857 Token parseExpression(Token token) { |
| 858 return parsePrecedenceExpression(token, CASCADE_PRECEDENCE); | 858 return parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, |
| 859 withoutCascades: false); | |
| 860 } | |
| 861 | |
| 862 Token parseExpressionWithoutCascade(Token token) { | |
| 863 return parsePrecedenceExpression(token, ASSIGNMENT_PRECEDENCE, | |
| 864 withoutCascades: true); | |
| 859 } | 865 } |
| 860 | 866 |
| 861 Token parseConditionalExpressionRest(Token token) { | 867 Token parseConditionalExpressionRest(Token token) { |
| 862 assert(optional('?', token)); | 868 assert(optional('?', token)); |
| 863 Token question = token; | 869 Token question = token; |
| 864 token = parseExpression(token.next); | 870 token = parseExpressionWithoutCascade(token.next); |
| 865 Token colon = token; | 871 Token colon = token; |
| 866 token = expect(':', token); | 872 token = expect(':', token); |
| 867 token = parseExpression(token); | 873 token = parseExpressionWithoutCascade(token); |
| 868 listener.handleConditionalExpression(question, colon); | 874 listener.handleConditionalExpression(question, colon); |
| 869 return token; | 875 return token; |
| 870 } | 876 } |
| 871 | 877 |
| 872 Token parsePrecedenceExpression(Token token, int precedence) { | 878 Token parsePrecedenceExpression(Token token, int precedence, |
| 879 [bool withoutCascades]) { | |
|
ahe
2012/05/01 15:50:50
No optional parameters please. This code is extrem
ahe
2012/09/24 16:49:01
Why was this submitted without addressing my comme
Lasse Reichstein Nielsen
2012/09/24 17:58:09
A really good question. I vaguely remember actuall
| |
| 873 assert(precedence >= 1); | 880 assert(precedence >= 1); |
| 874 assert(precedence <= POSTFIX_PRECEDENCE); | 881 assert(precedence <= POSTFIX_PRECEDENCE); |
| 875 token = parseUnaryExpression(token); | 882 token = parseUnaryExpression(token, withoutCascades); |
|
ahe
2012/05/01 15:50:50
It seems clearer too me if this parameter is named
| |
| 876 PrecedenceInfo info = token.info; | 883 PrecedenceInfo info = token.info; |
| 877 int tokenLevel = info.precedence; | 884 int tokenLevel = info.precedence; |
| 878 for (int level = tokenLevel; level >= precedence; --level) { | 885 for (int level = tokenLevel; level >= precedence; --level) { |
| 879 while (tokenLevel === level) { | 886 while (tokenLevel === level) { |
| 880 Token operator = token; | 887 Token operator = token; |
| 881 if (tokenLevel === CASCADE_PRECEDENCE) { | 888 if (tokenLevel === CASCADE_PRECEDENCE) { |
| 889 if (withoutCascades) { | |
| 890 return token; | |
| 891 } | |
| 882 token = parseCascadeExpression(token); | 892 token = parseCascadeExpression(token); |
| 883 } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) { | 893 } else if (tokenLevel === ASSIGNMENT_PRECEDENCE) { |
| 884 // Right associative, so we recurse at the same precedence | 894 // Right associative, so we recurse at the same precedence |
| 885 // level. | 895 // level. |
| 886 token = parsePrecedenceExpression(token.next, level); | 896 token = parsePrecedenceExpression(token.next, level, withoutCascades); |
| 887 listener.handleAssignmentExpression(operator); | 897 listener.handleAssignmentExpression(operator); |
| 888 } else if (tokenLevel === POSTFIX_PRECEDENCE) { | 898 } else if (tokenLevel === POSTFIX_PRECEDENCE) { |
| 889 if (info === PERIOD_INFO) { | 899 if (info === PERIOD_INFO) { |
| 890 // Left associative, so we recurse at the next higher | 900 // Left associative, so we recurse at the next higher |
| 891 // precedence level. However, POSTFIX_PRECEDENCE is the | 901 // precedence level. However, POSTFIX_PRECEDENCE is the |
| 892 // highest level, so we just call parseUnaryExpression | 902 // highest level, so we just call parseUnaryExpression |
| 893 // directly. | 903 // directly. |
| 894 token = parseUnaryExpression(token.next); | 904 token = parseUnaryExpression(token.next, withoutCascades); |
| 895 listener.handleBinaryExpression(operator); | 905 listener.handleBinaryExpression(operator); |
| 896 } else if ((info === OPEN_PAREN_INFO) || | 906 } else if ((info === OPEN_PAREN_INFO) || |
| 897 (info === OPEN_SQUARE_BRACKET_INFO)) { | 907 (info === OPEN_SQUARE_BRACKET_INFO)) { |
| 898 token = parseArgumentOrIndexStar(token); | 908 token = parseArgumentOrIndexStar(token); |
| 899 } else if ((info === PLUS_PLUS_INFO) || | 909 } else if ((info === PLUS_PLUS_INFO) || |
| 900 (info === MINUS_MINUS_INFO)) { | 910 (info === MINUS_MINUS_INFO)) { |
| 901 listener.handleUnaryPostfixAssignmentExpression(token); | 911 listener.handleUnaryPostfixAssignmentExpression(token); |
| 902 token = token.next; | 912 token = token.next; |
| 903 } else { | 913 } else { |
| 904 token = listener.unexpected(token); | 914 token = listener.unexpected(token); |
| 905 } | 915 } |
| 906 } else if (info === IS_INFO) { | 916 } else if (info === IS_INFO) { |
| 907 token = parseIsOperatorRest(token); | 917 token = parseIsOperatorRest(token); |
| 908 } else if (info === QUESTION_INFO) { | 918 } else if (info === QUESTION_INFO) { |
| 909 token = parseConditionalExpressionRest(token); | 919 token = parseConditionalExpressionRest(token); |
| 910 } else { | 920 } else { |
| 911 // Left associative, so we recurse at the next higher | 921 // Left associative, so we recurse at the next higher |
| 912 // precedence level. | 922 // precedence level. |
| 913 token = parsePrecedenceExpression(token.next, level + 1); | 923 token = parsePrecedenceExpression(token.next, level + 1, |
| 924 withoutCascades); | |
| 914 listener.handleBinaryExpression(operator); | 925 listener.handleBinaryExpression(operator); |
| 915 } | 926 } |
| 916 info = token.info; | 927 info = token.info; |
| 917 tokenLevel = info.precedence; | 928 tokenLevel = info.precedence; |
| 918 } | 929 } |
| 919 } | 930 } |
| 920 return token; | 931 return token; |
| 921 } | 932 } |
| 922 | 933 |
| 923 Token parseCascadeExpression(Token token) { | 934 Token parseCascadeExpression(Token token) { |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 939 if (optional('.', token)) { | 950 if (optional('.', token)) { |
| 940 Token period = token; | 951 Token period = token; |
| 941 token = parseSend(token.next); | 952 token = parseSend(token.next); |
| 942 listener.handleBinaryExpression(period); | 953 listener.handleBinaryExpression(period); |
| 943 } | 954 } |
| 944 token = parseArgumentOrIndexStar(token); | 955 token = parseArgumentOrIndexStar(token); |
| 945 } while (mark !== token); | 956 } while (mark !== token); |
| 946 | 957 |
| 947 if (token.info.precedence === ASSIGNMENT_PRECEDENCE) { | 958 if (token.info.precedence === ASSIGNMENT_PRECEDENCE) { |
| 948 Token assignment = token; | 959 Token assignment = token; |
| 949 token = parsePrecedenceExpression(token.next, CASCADE_PRECEDENCE + 1); | 960 token = parseExpressionWithoutCascade(token.next); |
| 950 listener.handleAssignmentExpression(assignment); | 961 listener.handleAssignmentExpression(assignment); |
| 951 } | 962 } |
| 952 listener.endCascade(); | 963 listener.endCascade(); |
| 953 return token; | 964 return token; |
| 954 } | 965 } |
| 955 | 966 |
| 956 Token parseUnaryExpression(Token token) { | 967 Token parseUnaryExpression(Token token, bool withoutCascades) { |
| 957 String value = token.stringValue; | 968 String value = token.stringValue; |
| 958 // Prefix: | 969 // Prefix: |
| 959 if (value === '+') { | 970 if (value === '+') { |
| 960 // Dart only allows "prefix plus" as an initial part of a | 971 // Dart only allows "prefix plus" as an initial part of a |
| 961 // decimal literal. We scan it as a separate token and let | 972 // decimal literal. We scan it as a separate token and let |
| 962 // the parser listener combine it with the digits. | 973 // the parser listener combine it with the digits. |
| 963 Token next = token.next; | 974 Token next = token.next; |
| 964 if (next.charOffset === token.charOffset + 1) { | 975 if (next.charOffset === token.charOffset + 1) { |
| 965 if (next.kind === INT_TOKEN) { | 976 if (next.kind === INT_TOKEN) { |
| 966 listener.handleLiteralInt(token); | 977 listener.handleLiteralInt(token); |
| 967 return next.next; | 978 return next.next; |
| 968 } | 979 } |
| 969 if (next.kind === DOUBLE_TOKEN) { | 980 if (next.kind === DOUBLE_TOKEN) { |
| 970 listener.handleLiteralDouble(token); | 981 listener.handleLiteralDouble(token); |
| 971 return next.next; | 982 return next.next; |
| 972 } | 983 } |
| 973 } | 984 } |
| 974 listener.recoverableError("Unexpected token '+'", token: token); | 985 listener.recoverableError("Unexpected token '+'", token: token); |
| 975 return parsePrecedenceExpression(next, POSTFIX_PRECEDENCE); | 986 return parsePrecedenceExpression(next, POSTFIX_PRECEDENCE, |
| 987 withoutCascades); | |
| 976 } else if ((value === '!') || | 988 } else if ((value === '!') || |
| 977 (value === '-') || | 989 (value === '-') || |
| 978 (value === '~')) { | 990 (value === '~')) { |
| 979 Token operator = token; | 991 Token operator = token; |
| 980 // Right associative, so we recurse at the same precedence | 992 // Right associative, so we recurse at the same precedence |
| 981 // level. | 993 // level. |
| 982 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE); | 994 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, |
| 995 withoutCascades); | |
| 983 listener.handleUnaryPrefixExpression(operator); | 996 listener.handleUnaryPrefixExpression(operator); |
| 984 } else if ((value === '++') || value === '--') { | 997 } else if ((value === '++') || value === '--') { |
| 985 // TODO(ahe): Validate this is used correctly. | 998 // TODO(ahe): Validate this is used correctly. |
| 986 Token operator = token; | 999 Token operator = token; |
| 987 // Right associative, so we recurse at the same precedence | 1000 // Right associative, so we recurse at the same precedence |
| 988 // level. | 1001 // level. |
| 989 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE); | 1002 token = parsePrecedenceExpression(token.next, POSTFIX_PRECEDENCE, |
| 1003 withoutCascades); | |
| 990 listener.handleUnaryPrefixAssignmentExpression(operator); | 1004 listener.handleUnaryPrefixAssignmentExpression(operator); |
| 991 } else { | 1005 } else { |
| 992 token = parsePrimary(token); | 1006 token = parsePrimary(token); |
| 993 } | 1007 } |
| 994 return token; | 1008 return token; |
| 995 } | 1009 } |
| 996 | 1010 |
| 997 Token parseArgumentOrIndexStar(Token token) { | 1011 Token parseArgumentOrIndexStar(Token token) { |
| 998 while (true) { | 1012 while (true) { |
| 999 if (optional('[', token)) { | 1013 if (optional('[', token)) { |
| (...skipping 619 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1619 } | 1633 } |
| 1620 listener.handleContinueStatement(hasTarget, continueKeyword, token); | 1634 listener.handleContinueStatement(hasTarget, continueKeyword, token); |
| 1621 return expectSemicolon(token); | 1635 return expectSemicolon(token); |
| 1622 } | 1636 } |
| 1623 | 1637 |
| 1624 Token parseEmptyStatement(Token token) { | 1638 Token parseEmptyStatement(Token token) { |
| 1625 listener.handleEmptyStatement(token); | 1639 listener.handleEmptyStatement(token); |
| 1626 return expectSemicolon(token); | 1640 return expectSemicolon(token); |
| 1627 } | 1641 } |
| 1628 } | 1642 } |
| OLD | NEW |