Index: src/preparser.cc |
diff --git a/src/preparser.cc b/src/preparser.cc |
index 018f99d2b47b24dbfa7be11e9ba7dc6911db1644..6759550eb88c5bf9a19943bc828712166dfee88c 100644 |
--- a/src/preparser.cc |
+++ b/src/preparser.cc |
@@ -1007,7 +1007,12 @@ PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
// LeftHandSideExpression :: |
// (NewExpression | MemberExpression) ... |
- Expression result = ParseMemberWithNewPrefixesExpression(CHECK_OK); |
+ Expression result = Expression::Default(); |
+ if (peek() == Token::NEW) { |
+ result = ParseNewExpression(CHECK_OK); |
+ } else { |
+ result = ParseMemberExpression(CHECK_OK); |
+ } |
while (true) { |
switch (peek()) { |
@@ -1047,28 +1052,35 @@ PreParser::Expression PreParser::ParseLeftHandSideExpression(bool* ok) { |
} |
-PreParser::Expression PreParser::ParseMemberWithNewPrefixesExpression( |
- bool* ok) { |
+PreParser::Expression PreParser::ParseNewExpression(bool* ok) { |
// NewExpression :: |
// ('new')+ MemberExpression |
- // See Parser::ParseNewExpression. |
- |
- if (peek() == Token::NEW) { |
+ // 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); |
- ParseMemberWithNewPrefixesExpression(CHECK_OK); |
- if (peek() == Token::LPAREN) { |
- // NewExpression with arguments. |
- ParseArguments(CHECK_OK); |
- } |
- return Expression::Default(); |
- } |
- // No 'new' keyword. |
- return ParseMemberExpression(ok); |
+ new_count++; |
+ } while (peek() == Token::NEW); |
+ |
+ return ParseMemberWithNewPrefixesExpression(new_count, 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)* |
@@ -1119,6 +1131,14 @@ PreParser::Expression PreParser::ParseMemberExpression(bool* ok) { |
} |
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; |
} |