Index: src/preparser.cc |
diff --git a/src/preparser.cc b/src/preparser.cc |
index 6759550eb88c5bf9a19943bc828712166dfee88c..fc4481fd868d24b1a13a627db6d961fbdeae5dea 100644 |
--- a/src/preparser.cc |
+++ b/src/preparser.cc |
@@ -1007,12 +1007,7 @@ PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
// LeftHandSideExpression :: |
// (NewExpression | MemberExpression) ... |
- Expression result = Expression::Default(); |
- if (peek() == Token::NEW) { |
- result = ParseNewExpression(CHECK_OK); |
- } else { |
- result = ParseMemberExpression(CHECK_OK); |
- } |
+ Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK); |
while (true) { |
switch (peek()) { |
@@ -1052,39 +1047,38 @@ PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
} |
-PreParser::Expression PreParser::ParseNewExpression(bool* ok) { |
+PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
+ bool* ok) { |
// NewExpression :: |
// ('new')+ MemberExpression |
- // The grammar for new expressions is pretty warped. The keyword |
- // 'new' can either be a part of the new expression (where it isn't |
- // followed by an argument list) or a part of the member expression, |
- // where it must be followed by an argument list. To accommodate |
- // this, we parse the 'new' keywords greedily and keep track of how |
- // many we have parsed. This information is then passed on to the |
- // member expression parser, which is only allowed to match argument |
- // lists as long as it has 'new' prefixes left |
- unsigned new_count = 0; |
- do { |
- Consume(Token::NEW); |
- new_count++; |
- } while (peek() == Token::NEW); |
+ // See Parser::ParseNewExpression. |
- return ParseMemberWithNewPrefixesExpression(new_count, ok); |
+ if (peek() == Token::NEW) { |
+ Consume(Token::NEW); |
+ ParseMemberWithNewPrefixesExpression(CHECK_OK); |
+ if (peek() == Token::LPAREN) { |
+ // NewExpression with arguments. |
+ ParseArguments(CHECK_OK); |
+ // The expression can still continue with . or [ after the arguments. |
+ ParseMemberExpressionContinuation(Expression::Default(), CHECK_OK); |
+ } |
+ return Expression::Default(); |
+ } |
+ // No 'new' keyword. |
+ return ParseMemberExpression(ok); |
} |
PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { |
- return ParseMemberWithNewPrefixesExpression(0, ok); |
-} |
- |
- |
-PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
- unsigned new_count, bool* ok) { |
// MemberExpression :: |
// (PrimaryExpression | FunctionLiteral) |
// ('[' Expression ']' | '.' Identifier | Arguments)* |
+ // The '[' Expression ']' and '.' Identifier parts are parsed by |
+ // ParseMemberExpressionContinuation, and the Arguments part is parsed by the |
+ // caller. |
+ |
// Parse the initial primary or function expression. |
Expression result = Expression::Default(); |
if (peek() == Token::FUNCTION) { |
@@ -1107,42 +1101,44 @@ PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
} else { |
result = ParsePrimaryExpression(CHECK_OK); |
} |
+ result = ParseMemberExpressionContinuation(result, CHECK_OK); |
+ return result; |
+} |
+ |
+PreParser::Expression PreParser::ParseMemberExpressionContinuation( |
+ PreParserExpression expression, bool* ok) { |
+ // Parses this part of MemberExpression: |
+ // ('[' Expression ']' | '.' Identifier)* |
while (true) { |
switch (peek()) { |
case Token::LBRACK: { |
Consume(Token::LBRACK); |
ParseExpression(true, CHECK_OK); |
Expect(Token::RBRACK, CHECK_OK); |
- if (result.IsThis()) { |
- result = Expression::ThisProperty(); |
+ if (expression.IsThis()) { |
+ expression = Expression::ThisProperty(); |
} else { |
- result = Expression::Default(); |
+ expression = Expression::Default(); |
} |
break; |
} |
case Token::PERIOD: { |
Consume(Token::PERIOD); |
ParseIdentifierName(CHECK_OK); |
- if (result.IsThis()) { |
- result = Expression::ThisProperty(); |
+ if (expression.IsThis()) { |
+ expression = Expression::ThisProperty(); |
} else { |
- result = Expression::Default(); |
+ expression = Expression::Default(); |
} |
break; |
} |
- case Token::LPAREN: { |
- if (new_count == 0) return result; |
- // Consume one of the new prefixes (already parsed). |
- ParseArguments(CHECK_OK); |
- new_count--; |
- result = Expression::Default(); |
- break; |
- } |
default: |
- return result; |
+ return expression; |
} |
} |
+ ASSERT(false); |
+ return PreParserExpression::Default(); |
} |