| 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;
|
| }
|
|
|