From: "Gabriel Ivăncescu" Subject: [PATCH v2 1/2] jscript: Allow ES5 keywords in identifiers. Message-Id: Date: Wed, 1 Sep 2021 16:35:49 +0300 Signed-off-by: Gabriel Ivăncescu --- So, I managed to solve all the extra shift/reduce conflicts, but I'm not entirely happy about how I've done it, and I can't for the life of me figure out WHY, so I'm hoping by sending it some review might help me out of this situation. I tried bison with --report=all and verbose, and I don't know how to solve that conflict. The problem is in LabelledStatement; for some reason I cannot comprehend, I had to duplicate all the ES5 keywords and use tIdentifier as separate rules to avoid any extra shift/reduce conflicts from it. Using just "Identifier" would generate two extra shift/reduce conflicts! Using "tIdentifier | ES5Keyword" would generate only one extra shift/reduce conflict. And using "tIdentifier | kGET | kSET | kLET" generates no extra conflicts (this patch). I think I'm going crazy; isn't it supposed to be the same thing? Why the difference? Any ideas? dlls/jscript/parser.y | 44 ++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y index 0ebdc2b..34ad532 100644 --- a/dlls/jscript/parser.y +++ b/dlls/jscript/parser.y @@ -220,7 +220,7 @@ static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t %type MemberExpression %type PrimaryExpression %type GetterSetterMethod -%type Identifier_opt +%type Identifier Identifier_opt %type VariableDeclarationList %type VariableDeclarationListNoIn %type VariableDeclaration @@ -240,10 +240,11 @@ static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t %type PropertyName %type BooleanLiteral %type AssignOper -%type IdentifierName ReservedAsIdentifier +%type IdentifierName ReservedAsIdentifier ES5Keyword %nonassoc LOWER_THAN_ELSE -%nonassoc kELSE +%nonassoc kELSE kIN kINSTANCEOF ':' +%nonassoc kGET kLET kSET %% @@ -267,9 +268,9 @@ FunctionStatementList FunctionExpression : kFUNCTION left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, NULL, $3, $6, NULL, ctx->begin + @1, @7 - @1 + 1); } - | kFUNCTION tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + | kFUNCTION Identifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, $2, $4, $7, NULL, ctx->begin + @1, @8 - @1 + 1); } - | kFUNCTION tIdentifier kDCOL tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' + | kFUNCTION Identifier kDCOL Identifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, $4, $6, $9, $2, ctx->begin + @1, @10 - @1 + 1); } /* ECMA-262 10th Edition 14.1 */ @@ -278,8 +279,8 @@ FunctionBody /* ECMA-262 3rd Edition 13 */ FormalParameterList - : tIdentifier { $$ = new_parameter_list(ctx, $1); } - | FormalParameterList ',' tIdentifier + : Identifier { $$ = new_parameter_list(ctx, $1); } + | FormalParameterList ',' Identifier { $$ = parameter_list_add(ctx, $1, $3); } /* ECMA-262 3rd Edition 13 */ @@ -380,12 +381,12 @@ VariableDeclarationListNoIn /* ECMA-262 3rd Edition 12.2 */ VariableDeclaration - : tIdentifier Initialiser_opt + : Identifier Initialiser_opt { $$ = new_variable_declaration(ctx, $1, $2); } /* ECMA-262 3rd Edition 12.2 */ VariableDeclarationNoIn - : tIdentifier InitialiserNoIn_opt + : Identifier InitialiserNoIn_opt { $$ = new_variable_declaration(ctx, $1, $2); } /* ECMA-262 3rd Edition 12.2 */ @@ -478,6 +479,12 @@ WithStatement LabelledStatement : tIdentifier ':' Statement { $$ = new_labelled_statement(ctx, @$, $1, $3); } + | kGET ':' Statement + { $$ = new_labelled_statement(ctx, @$, $1, $3); } + | kSET ':' Statement + { $$ = new_labelled_statement(ctx, @$, $1, $3); } + | kLET ':' Statement + { $$ = new_labelled_statement(ctx, @$, $1, $3); } /* ECMA-262 3rd Edition 12.11 */ SwitchStatement @@ -526,7 +533,7 @@ TryStatement /* ECMA-262 3rd Edition 12.14 */ Catch - : kCATCH left_bracket tIdentifier right_bracket Block + : kCATCH left_bracket Identifier right_bracket Block { $$ = new_catch_block(ctx, $3, $5); } /* ECMA-262 3rd Edition 12.14 */ @@ -785,7 +792,7 @@ ArgumentList /* ECMA-262 3rd Edition 11.1 */ PrimaryExpression : kTHIS { $$ = new_expression(ctx, EXPR_THIS, 0); } - | tIdentifier { $$ = new_identifier_expression(ctx, $1); } + | Identifier { $$ = new_identifier_expression(ctx, $1); } | Literal { $$ = new_literal_expression(ctx, $1); } | ArrayLiteral { $$ = $1; } | ObjectLiteral { $$ = $1; } @@ -859,7 +866,11 @@ PropertyName /* ECMA-262 3rd Edition 7.6 */ Identifier_opt : /* empty*/ { $$ = NULL; } - | tIdentifier { $$ = $1; } + | Identifier { $$ = $1; } + +Identifier + : tIdentifier { $$ = $1; } + | ES5Keyword { $$ = $1; } /* ECMA-262 5.1 Edition 7.6 */ IdentifierName @@ -889,15 +900,12 @@ ReservedAsIdentifier | kFINALLY { $$ = $1; } | kFOR { $$ = $1; } | kFUNCTION { $$ = $1; } - | kGET { $$ = $1; } | kIF { $$ = $1; } | kIN { $$ = $1; } | kINSTANCEOF { $$ = $1; } - | kLET { $$ = $1; } | kNEW { $$ = $1; } | kNULL { $$ = $1; } | kRETURN { $$ = $1; } - | kSET { $$ = $1; } | kSWITCH { $$ = $1; } | kTHIS { $$ = $1; } | kTHROW { $$ = $1; } @@ -908,6 +916,12 @@ ReservedAsIdentifier | kVOID { $$ = $1; } | kWHILE { $$ = $1; } | kWITH { $$ = $1; } + | ES5Keyword { $$ = $1; } + +ES5Keyword + : kGET { $$ = $1; } + | kLET { $$ = $1; } + | kSET { $$ = $1; } /* ECMA-262 3rd Edition 7.8 */ Literal -- 2.31.1