From: Jacek Caban Subject: vbscript: 'property' may be both keyword and identifier Message-Id: <4F97C34A.9070700@codeweavers.com> Date: Wed, 25 Apr 2012 11:26:34 +0200 --- dlls/vbscript/parser.y | 37 ++++++++++++++++++++++--------------- dlls/vbscript/tests/lang.vbs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 15 deletions(-) diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 2a85272..a5f7405 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -71,6 +71,8 @@ static class_decl_t *add_variant_prop(parser_ctx_t*,class_decl_t*,const WCHAR*,u static statement_t *link_statements(statement_t*,statement_t*); +static const WCHAR propertyW[] = {'p','r','o','p','e','r','t','y',0}; + #define STORAGE_IS_PRIVATE 1 #define STORAGE_IS_DEFAULT 2 @@ -129,6 +131,7 @@ static statement_t *link_statements(statement_t*,statement_t*); %type Storage Storage_opt %type DimDeclList %type ConstDecl ConstDeclList +%type Identifier %% @@ -189,25 +192,25 @@ SimpleStatement | tON tERROR tRESUME tNEXT { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; } | tON tERROR tGOTO '0' { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; } | tCONST ConstDeclList { $$ = new_const_statement(ctx, $2); CHECK_ERROR; } - | tFOR tIdentifier '=' Expression tTO Expression Step_opt tNL StatementsNl_opt tNEXT + | tFOR Identifier '=' Expression tTO Expression Step_opt tNL StatementsNl_opt tNEXT { $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; } - | tFOR tEACH tIdentifier tIN Expression tNL StatementsNl_opt tNEXT + | tFOR tEACH Identifier tIN Expression tNL StatementsNl_opt tNEXT { $$ = new_foreach_statement(ctx, $3, $5, $7); } MemberExpression - : tIdentifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } - | CallExpression '.' tIdentifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; } + : Identifier { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; } + | CallExpression '.' Identifier { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; } DimDeclList /* FIXME: Support arrays */ - : tIdentifier { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; } - | tIdentifier ',' DimDeclList { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; } + : Identifier { $$ = new_dim_decl(ctx, $1, NULL); CHECK_ERROR; } + | Identifier ',' DimDeclList { $$ = new_dim_decl(ctx, $1, $3); CHECK_ERROR; } ConstDeclList : ConstDecl { $$ = $1; } | ConstDecl ',' ConstDeclList { $1->next = $3; $$ = $1; } ConstDecl - : tIdentifier '=' LiteralExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; } + : Identifier '=' LiteralExpression { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; } DoType : tWHILE { $$ = TRUE; } @@ -326,7 +329,7 @@ ExpExpression UnaryExpression : LiteralExpression { $$ = $1; } | CallExpression { $$ = $1; } - | tNEW tIdentifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; } + | tNEW Identifier { $$ = new_new_expression(ctx, $2); CHECK_ERROR; } | '-' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; } CallExpression @@ -350,7 +353,7 @@ PrimaryExpression | tME { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; } ClassDeclaration - : tCLASS tIdentifier tNL ClassBody tEND tCLASS tNL { $4->name = $2; $$ = $4; } + : tCLASS Identifier tNL ClassBody tEND tCLASS tNL { $4->name = $2; $$ = $4; } ClassBody : /* empty */ { $$ = new_class_decl(ctx); } @@ -367,9 +370,9 @@ PropertyDecl { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; } FunctionDecl - : Storage_opt tSUB tIdentifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB + : Storage_opt tSUB Identifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tSUB { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; } - | Storage_opt tFUNCTION tIdentifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tFUNCTION + | Storage_opt tFUNCTION Identifier ArgumentsDecl_opt tNL StatementsNl_opt tEND tFUNCTION { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; } Storage_opt @@ -390,10 +393,14 @@ ArgumentDeclList | ArgumentDecl ',' ArgumentDeclList { $1->next = $3; $$ = $1; } ArgumentDecl - : tIdentifier { $$ = new_argument_decl(ctx, $1, TRUE); } - | tBYREF tIdentifier { $$ = new_argument_decl(ctx, $2, TRUE); } - | tBYVAL tIdentifier { $$ = new_argument_decl(ctx, $2, FALSE); } - + : Identifier { $$ = new_argument_decl(ctx, $1, TRUE); } + | tBYREF Identifier { $$ = new_argument_decl(ctx, $2, TRUE); } + | tBYVAL Identifier { $$ = new_argument_decl(ctx, $2, FALSE); } + +/* 'property' may be both keyword and identifier, depending on context */ +Identifier + : tIdentifier { $$ = $1; } + | tPROPERTY { $$ = propertyW; } %% static int parser_error(const char *str) diff --git a/dlls/vbscript/tests/lang.vbs b/dlls/vbscript/tests/lang.vbs index 4380432..1015e34 100644 --- a/dlls/vbscript/tests/lang.vbs +++ b/dlls/vbscript/tests/lang.vbs @@ -781,4 +781,36 @@ End Sub Call ConstTestSub Dim funcconst +' Property may be used as an identifier (although it's a keyword) +Sub TestProperty + Dim Property + PROPERTY = true + Call ok(property, "property = " & property) + + for property = 1 to 2 + next +End Sub + +Call TestProperty + +Class Property + Public Sub Property() + End Sub + + Sub Test(byref property) + End Sub +End Class + +Class Property2 + Function Property() + End Function + + + Sub Test(property) + End Sub + + Sub Test2(byval property) + End Sub +End Class + reportSuccess()