vbscript: 'property' may be both keyword and identifier.
This commit is contained in:
parent
474f1152b2
commit
d856d7cd11
|
@ -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 <uint> Storage Storage_opt
|
||||
%type <dim_decl> DimDeclList
|
||||
%type <const_decl> ConstDecl ConstDeclList
|
||||
%type <string> 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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue