xref: /reactos/dll/win32/vbscript/parser.y (revision 40462c92)
1 /*
2  * Copyright 2011 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 %{
20 
21 #include "vbscript.h"
22 #include "parse.h"
23 
24 #include "wine/debug.h"
25 
26 WINE_DEFAULT_DEBUG_CHANNEL(vbscript);
27 
28 static int parser_error(parser_ctx_t *,const char*);
29 
30 static void parse_complete(parser_ctx_t*,BOOL);
31 static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr);
32 
33 static void source_add_statement(parser_ctx_t*,statement_t*);
34 static void source_add_class(parser_ctx_t*,class_decl_t*);
35 
36 static void *new_expression(parser_ctx_t*,expression_type_t,size_t);
37 static expression_t *new_bool_expression(parser_ctx_t*,VARIANT_BOOL);
38 static expression_t *new_string_expression(parser_ctx_t*,const WCHAR*);
39 static expression_t *new_long_expression(parser_ctx_t*,expression_type_t,LONG);
40 static expression_t *new_double_expression(parser_ctx_t*,double);
41 static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*);
42 static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*);
43 static expression_t *new_new_expression(parser_ctx_t*,const WCHAR*);
44 
45 static member_expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);
46 
47 static void *new_statement(parser_ctx_t*,statement_type_t,size_t);
48 static statement_t *new_call_statement(parser_ctx_t*,BOOL,member_expression_t*);
49 static statement_t *new_assign_statement(parser_ctx_t*,member_expression_t*,expression_t*);
50 static statement_t *new_set_statement(parser_ctx_t*,member_expression_t*,expression_t*);
51 static statement_t *new_dim_statement(parser_ctx_t*,dim_decl_t*);
52 static statement_t *new_while_statement(parser_ctx_t*,statement_type_t,expression_t*,statement_t*);
53 static statement_t *new_forto_statement(parser_ctx_t*,const WCHAR*,expression_t*,expression_t*,expression_t*,statement_t*);
54 static statement_t *new_foreach_statement(parser_ctx_t*,const WCHAR*,expression_t*,statement_t*);
55 static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,elseif_decl_t*,statement_t*);
56 static statement_t *new_function_statement(parser_ctx_t*,function_decl_t*);
57 static statement_t *new_onerror_statement(parser_ctx_t*,BOOL);
58 static statement_t *new_const_statement(parser_ctx_t*,const_decl_t*);
59 static statement_t *new_select_statement(parser_ctx_t*,expression_t*,case_clausule_t*);
60 
61 static dim_decl_t *new_dim_decl(parser_ctx_t*,const WCHAR*,BOOL,dim_list_t*);
62 static dim_list_t *new_dim(parser_ctx_t*,unsigned,dim_list_t*);
63 static elseif_decl_t *new_elseif_decl(parser_ctx_t*,expression_t*,statement_t*);
64 static function_decl_t *new_function_decl(parser_ctx_t*,const WCHAR*,function_type_t,unsigned,arg_decl_t*,statement_t*);
65 static arg_decl_t *new_argument_decl(parser_ctx_t*,const WCHAR*,BOOL);
66 static const_decl_t *new_const_decl(parser_ctx_t*,const WCHAR*,expression_t*);
67 static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_t*,case_clausule_t*);
68 
69 static class_decl_t *new_class_decl(parser_ctx_t*);
70 static class_decl_t *add_class_function(parser_ctx_t*,class_decl_t*,function_decl_t*);
71 static class_decl_t *add_dim_prop(parser_ctx_t*,class_decl_t*,dim_decl_t*,unsigned);
72 
73 static statement_t *link_statements(statement_t*,statement_t*);
74 
75 #define STORAGE_IS_PRIVATE    1
76 #define STORAGE_IS_DEFAULT    2
77 
78 #define CHECK_ERROR if(((parser_ctx_t*)ctx)->hres != S_OK) YYABORT
79 
80 %}
81 
82 %lex-param { parser_ctx_t *ctx }
83 %parse-param { parser_ctx_t *ctx }
84 %pure-parser
85 %start Program
86 
87 %union {
88     const WCHAR *string;
89     statement_t *statement;
90     expression_t *expression;
91     member_expression_t *member;
92     elseif_decl_t *elseif;
93     dim_decl_t *dim_decl;
94     dim_list_t *dim_list;
95     function_decl_t *func_decl;
96     arg_decl_t *arg_decl;
97     class_decl_t *class_decl;
98     const_decl_t *const_decl;
99     case_clausule_t *case_clausule;
100     unsigned uint;
101     LONG integer;
102     BOOL boolean;
103     double dbl;
104 }
105 
106 %token tEXPRESSION tEOF tNL tEMPTYBRACKETS
107 %token tLTEQ tGTEQ tNEQ
108 %token tSTOP tME tREM
109 %token <string> tTRUE tFALSE
110 %token <string> tNOT tAND tOR tXOR tEQV tIMP
111 %token <string> tIS tMOD
112 %token <string> tCALL tDIM tSUB tFUNCTION tGET tLET tCONST
113 %token <string> tIF tELSE tELSEIF tEND tTHEN tEXIT
114 %token <string> tWHILE tWEND tDO tLOOP tUNTIL tFOR tTO tEACH tIN
115 %token <string> tSELECT tCASE
116 %token <string> tBYREF tBYVAL
117 %token <string> tOPTION
118 %token <string> tNOTHING tEMPTY tNULL
119 %token <string> tCLASS tSET tNEW tPUBLIC tPRIVATE
120 %token <string> tNEXT tON tRESUME tGOTO
121 %token <string> tIdentifier tString
122 %token <string> tDEFAULT tERROR tEXPLICIT tPROPERTY tSTEP
123 %token <integer> tInt
124 %token <dbl> tDouble
125 
126 %type <statement> Statement SimpleStatement StatementNl StatementsNl StatementsNl_opt BodyStatements IfStatement Else_opt
127 %type <expression> Expression LiteralExpression PrimaryExpression EqualityExpression CallExpression ExpressionNl_opt
128 %type <expression> ConcatExpression AdditiveExpression ModExpression IntdivExpression MultiplicativeExpression ExpExpression
129 %type <expression> NotExpression UnaryExpression AndExpression OrExpression XorExpression EqvExpression
130 %type <expression> ConstExpression NumericLiteralExpression
131 %type <member> MemberExpression
132 %type <expression> Arguments_opt ArgumentList ArgumentList_opt Step_opt ExpressionList
133 %type <boolean> OptionExplicit_opt DoType
134 %type <arg_decl> ArgumentsDecl_opt ArgumentDeclList ArgumentDecl
135 %type <func_decl> FunctionDecl PropertyDecl
136 %type <elseif> ElseIfs_opt ElseIfs ElseIf
137 %type <class_decl> ClassDeclaration ClassBody
138 %type <uint> Storage Storage_opt IntegerValue
139 %type <dim_decl> DimDeclList DimDecl
140 %type <dim_list> DimList
141 %type <const_decl> ConstDecl ConstDeclList
142 %type <string> Identifier DotIdentifier
143 %type <case_clausule> CaseClausules
144 
145 %%
146 
147 Program
148     : OptionExplicit_opt SourceElements tEOF    { parse_complete(ctx, $1); }
149     | tEXPRESSION ExpressionNl_opt tEOF         { handle_isexpression_script(ctx, $2); }
150 
151 OptionExplicit_opt
152     : /* empty */                { $$ = FALSE; }
153     | tOPTION tEXPLICIT StSep    { $$ = TRUE; }
154 
155 SourceElements
156     : /* empty */
157     | SourceElements StatementNl            { source_add_statement(ctx, $2); }
158     | SourceElements ClassDeclaration       { source_add_class(ctx, $2); }
159 
160 ExpressionNl_opt
161     : /* empty */                           { $$ = NULL; }
162     | Expression tNL                        { $$ = $1; }
163 
164 BodyStatements
165     : /* empty */                           { $$ = NULL; }
166     | Statement                             { $$ = $1; }
167     | StatementNl BodyStatements            { $$ = link_statements($1, $2); }
168 
169 StatementsNl_opt
170     : /* empty */                           { $$ = NULL; }
171     | StatementsNl                          { $$ = $1; }
172 
173 StatementsNl
174     : StatementNl                           { $$ = $1; }
175     | StatementNl StatementsNl              { $$ = link_statements($1, $2); }
176 
177 StatementNl
178     : Statement tNL                         { $$ = $1; }
179 
180 Statement
181     : ':'                                   { $$ = NULL; }
182     | ':' Statement                         { $$ = $2; }
183     | SimpleStatement                       { $$ = $1; }
184     | SimpleStatement ':' Statement         { $1->next = $3; $$ = $1; }
185     | SimpleStatement ':'                   { $$ = $1; }
186 
187 SimpleStatement
188     : MemberExpression ArgumentList_opt     { $1->args = $2; $$ = new_call_statement(ctx, FALSE, $1); CHECK_ERROR; }
189     | tCALL MemberExpression Arguments_opt  { $2->args = $3; $$ = new_call_statement(ctx, TRUE, $2); CHECK_ERROR; }
190     | MemberExpression Arguments_opt '=' Expression
191                                             { $1->args = $2; $$ = new_assign_statement(ctx, $1, $4); CHECK_ERROR; }
192     | tDIM DimDeclList                      { $$ = new_dim_statement(ctx, $2); CHECK_ERROR; }
193     | IfStatement                           { $$ = $1; }
194     | tWHILE Expression StSep StatementsNl_opt tWEND
195                                             { $$ = new_while_statement(ctx, STAT_WHILE, $2, $4); CHECK_ERROR; }
196     | tDO DoType Expression StSep StatementsNl_opt tLOOP
197                                             { $$ = new_while_statement(ctx, $2 ? STAT_WHILELOOP : STAT_UNTIL, $3, $5);
198                                               CHECK_ERROR; }
199     | tDO StSep StatementsNl_opt tLOOP DoType Expression
200                                             { $$ = new_while_statement(ctx, $5 ? STAT_DOWHILE : STAT_DOUNTIL, $6, $3);
201                                               CHECK_ERROR; }
202     | tDO StSep StatementsNl_opt tLOOP      { $$ = new_while_statement(ctx, STAT_DOWHILE, NULL, $3); CHECK_ERROR; }
203     | FunctionDecl                          { $$ = new_function_statement(ctx, $1); CHECK_ERROR; }
204     | tEXIT tDO                             { $$ = new_statement(ctx, STAT_EXITDO, 0); CHECK_ERROR; }
205     | tEXIT tFOR                            { $$ = new_statement(ctx, STAT_EXITFOR, 0); CHECK_ERROR; }
206     | tEXIT tFUNCTION                       { $$ = new_statement(ctx, STAT_EXITFUNC, 0); CHECK_ERROR; }
207     | tEXIT tPROPERTY                       { $$ = new_statement(ctx, STAT_EXITPROP, 0); CHECK_ERROR; }
208     | tEXIT tSUB                            { $$ = new_statement(ctx, STAT_EXITSUB, 0); CHECK_ERROR; }
209     | tSET MemberExpression Arguments_opt '=' Expression
210                                             { $2->args = $3; $$ = new_set_statement(ctx, $2, $5); CHECK_ERROR; }
211     | tSTOP                                 { $$ = new_statement(ctx, STAT_STOP, 0); CHECK_ERROR; }
212     | tON tERROR tRESUME tNEXT              { $$ = new_onerror_statement(ctx, TRUE); CHECK_ERROR; }
213     | tON tERROR tGOTO '0'                  { $$ = new_onerror_statement(ctx, FALSE); CHECK_ERROR; }
214     | tCONST ConstDeclList                  { $$ = new_const_statement(ctx, $2); CHECK_ERROR; }
215     | tFOR Identifier '=' Expression tTO Expression Step_opt StSep StatementsNl_opt tNEXT
216                                             { $$ = new_forto_statement(ctx, $2, $4, $6, $7, $9); CHECK_ERROR; }
217     | tFOR tEACH Identifier tIN Expression StSep StatementsNl_opt tNEXT
218                                             { $$ = new_foreach_statement(ctx, $3, $5, $7); }
219     | tSELECT tCASE Expression StSep CaseClausules tEND tSELECT
220                                             { $$ = new_select_statement(ctx, $3, $5); }
221 
222 MemberExpression
223     : Identifier                            { $$ = new_member_expression(ctx, NULL, $1); CHECK_ERROR; }
224     | CallExpression '.' DotIdentifier      { $$ = new_member_expression(ctx, $1, $3); CHECK_ERROR; }
225 
226 DimDeclList
227     : DimDecl                               { $$ = $1; }
228     | DimDecl ',' DimDeclList               { $1->next = $3; $$ = $1; }
229 
230 DimDecl
231     : Identifier                            { $$ = new_dim_decl(ctx, $1, FALSE, NULL); CHECK_ERROR; }
232     | Identifier '(' DimList ')'            { $$ = new_dim_decl(ctx, $1, TRUE, $3); CHECK_ERROR; }
233     | Identifier tEMPTYBRACKETS             { $$ = new_dim_decl(ctx, $1, TRUE, NULL); CHECK_ERROR; }
234 
235 DimList
236     : IntegerValue                          { $$ = new_dim(ctx, $1, NULL); }
237     | IntegerValue ',' DimList              { $$ = new_dim(ctx, $1, $3); }
238 
239 ConstDeclList
240     : ConstDecl                             { $$ = $1; }
241     | ConstDecl ',' ConstDeclList           { $1->next = $3; $$ = $1; }
242 
243 ConstDecl
244     : Identifier '=' ConstExpression        { $$ = new_const_decl(ctx, $1, $3); CHECK_ERROR; }
245 
246 ConstExpression
247     : LiteralExpression                     { $$ = $1; }
248     | '-' NumericLiteralExpression          { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
249 
250 DoType
251     : tWHILE        { $$ = TRUE; }
252     | tUNTIL        { $$ = FALSE; }
253 
254 Step_opt
255     : /* empty */                           { $$ = NULL;}
256     | tSTEP Expression                      { $$ = $2; }
257 
258 IfStatement
259     : tIF Expression tTHEN tNL StatementsNl_opt ElseIfs_opt Else_opt tEND tIF
260                                                { $$ = new_if_statement(ctx, $2, $5, $6, $7); CHECK_ERROR; }
261     | tIF Expression tTHEN Statement EndIf_opt { $$ = new_if_statement(ctx, $2, $4, NULL, NULL); CHECK_ERROR; }
262     | tIF Expression tTHEN Statement tELSE Statement EndIf_opt
263                                                { $$ = new_if_statement(ctx, $2, $4, NULL, $6); CHECK_ERROR; }
264 
265 EndIf_opt
266     : /* empty */
267     | tEND tIF
268 
269 ElseIfs_opt
270     : /* empty */                           { $$ = NULL; }
271     | ElseIfs                               { $$ = $1; }
272 
273 ElseIfs
274     : ElseIf                                { $$ = $1; }
275     | ElseIf ElseIfs                        { $1->next = $2; $$ = $1; }
276 
277 ElseIf
278     : tELSEIF Expression tTHEN tNL StatementsNl_opt
279                                             { $$ = new_elseif_decl(ctx, $2, $5); }
280 
281 Else_opt
282     : /* empty */                           { $$ = NULL; }
283     | tELSE tNL StatementsNl_opt            { $$ = $3; }
284 
285 CaseClausules
286     : /* empty */                          { $$ = NULL; }
287     | tCASE tELSE StSep StatementsNl       { $$ = new_case_clausule(ctx, NULL, $4, NULL); }
288     | tCASE ExpressionList StSep StatementsNl_opt CaseClausules
289                                            { $$ = new_case_clausule(ctx, $2, $4, $5); }
290 
291 Arguments_opt
292     : EmptyBrackets_opt             { $$ = NULL; }
293     | '(' ArgumentList ')'          { $$ = $2; }
294 
295 ArgumentList_opt
296     : EmptyBrackets_opt             { $$ = NULL; }
297     | ArgumentList                  { $$ = $1; }
298 
299 ArgumentList
300     : Expression                    { $$ = $1; }
301     | Expression ',' ArgumentList   { $1->next = $3; $$ = $1; }
302     | ',' ArgumentList              { $$ = new_expression(ctx, EXPR_NOARG, 0); CHECK_ERROR; $$->next = $2; }
303 
304 EmptyBrackets_opt
305     : /* empty */
306     | tEMPTYBRACKETS
307 
308 ExpressionList
309     : Expression                    { $$ = $1; }
310     | Expression ',' ExpressionList { $1->next = $3; $$ = $1; }
311 
312 Expression
313     : EqvExpression                             { $$ = $1; }
314     | Expression tIMP EqvExpression             { $$ = new_binary_expression(ctx, EXPR_IMP, $1, $3); CHECK_ERROR; }
315 
316 EqvExpression
317     : XorExpression                             { $$ = $1; }
318     | EqvExpression tEQV XorExpression          { $$ = new_binary_expression(ctx, EXPR_EQV, $1, $3); CHECK_ERROR; }
319 
320 XorExpression
321     : OrExpression                              { $$ = $1; }
322     | XorExpression tXOR OrExpression           { $$ = new_binary_expression(ctx, EXPR_XOR, $1, $3); CHECK_ERROR; }
323 
324 OrExpression
325     : AndExpression                             { $$ = $1; }
326     | OrExpression tOR AndExpression            { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); CHECK_ERROR; }
327 
328 AndExpression
329     : NotExpression                             { $$ = $1; }
330     | AndExpression tAND NotExpression          { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); CHECK_ERROR; }
331 
332 NotExpression
333     : EqualityExpression            { $$ = $1; }
334     | tNOT NotExpression            { $$ = new_unary_expression(ctx, EXPR_NOT, $2); CHECK_ERROR; }
335 
336 EqualityExpression
337     : ConcatExpression                          { $$ = $1; }
338     | EqualityExpression '=' ConcatExpression   { $$ = new_binary_expression(ctx, EXPR_EQUAL, $1, $3); CHECK_ERROR; }
339     | EqualityExpression tNEQ ConcatExpression  { $$ = new_binary_expression(ctx, EXPR_NEQUAL, $1, $3); CHECK_ERROR; }
340     | EqualityExpression '>' ConcatExpression   { $$ = new_binary_expression(ctx, EXPR_GT, $1, $3); CHECK_ERROR; }
341     | EqualityExpression '<' ConcatExpression   { $$ = new_binary_expression(ctx, EXPR_LT, $1, $3); CHECK_ERROR; }
342     | EqualityExpression tGTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_GTEQ, $1, $3); CHECK_ERROR; }
343     | EqualityExpression tLTEQ ConcatExpression { $$ = new_binary_expression(ctx, EXPR_LTEQ, $1, $3); CHECK_ERROR; }
344     | EqualityExpression tIS ConcatExpression   { $$ = new_binary_expression(ctx, EXPR_IS, $1, $3); CHECK_ERROR; }
345 
346 ConcatExpression
347     : AdditiveExpression                        { $$ = $1; }
348     | ConcatExpression '&' AdditiveExpression   { $$ = new_binary_expression(ctx, EXPR_CONCAT, $1, $3); CHECK_ERROR; }
349 
350 AdditiveExpression
351     : ModExpression                             { $$ = $1; }
352     | AdditiveExpression '+' ModExpression      { $$ = new_binary_expression(ctx, EXPR_ADD, $1, $3); CHECK_ERROR; }
353     | AdditiveExpression '-' ModExpression      { $$ = new_binary_expression(ctx, EXPR_SUB, $1, $3); CHECK_ERROR; }
354 
355 ModExpression
356     : IntdivExpression                          { $$ = $1; }
357     | ModExpression tMOD IntdivExpression       { $$ = new_binary_expression(ctx, EXPR_MOD, $1, $3); CHECK_ERROR; }
358 
359 IntdivExpression
360     : MultiplicativeExpression                  { $$ = $1; }
361     | IntdivExpression '\\' MultiplicativeExpression
362                                                 { $$ = new_binary_expression(ctx, EXPR_IDIV, $1, $3); CHECK_ERROR; }
363 
364 MultiplicativeExpression
365     : ExpExpression                             { $$ = $1; }
366     | MultiplicativeExpression '*' ExpExpression
367                                                 { $$ = new_binary_expression(ctx, EXPR_MUL, $1, $3); CHECK_ERROR; }
368     | MultiplicativeExpression '/' ExpExpression
369                                                 { $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); CHECK_ERROR; }
370 
371 ExpExpression
372     : UnaryExpression                           { $$ = $1; }
373     | ExpExpression '^' UnaryExpression         { $$ = new_binary_expression(ctx, EXPR_EXP, $1, $3); CHECK_ERROR; }
374 
375 UnaryExpression
376     : LiteralExpression             { $$ = $1; }
377     | CallExpression                { $$ = $1; }
378     | tNEW Identifier               { $$ = new_new_expression(ctx, $2); CHECK_ERROR; }
379     | '-' UnaryExpression           { $$ = new_unary_expression(ctx, EXPR_NEG, $2); CHECK_ERROR; }
380     | '+' UnaryExpression           { $$ = $2; }
381 
382 CallExpression
383     : PrimaryExpression                 { $$ = $1; }
384     | MemberExpression Arguments_opt    { $1->args = $2; $$ = &$1->expr; }
385 
386 LiteralExpression
387     : tTRUE                         { $$ = new_bool_expression(ctx, VARIANT_TRUE); CHECK_ERROR; }
388     | tFALSE                        { $$ = new_bool_expression(ctx, VARIANT_FALSE); CHECK_ERROR; }
389     | tString                       { $$ = new_string_expression(ctx, $1); CHECK_ERROR; }
390     | NumericLiteralExpression      { $$ = $1; }
391     | tEMPTY                        { $$ = new_expression(ctx, EXPR_EMPTY, 0); CHECK_ERROR; }
392     | tNULL                         { $$ = new_expression(ctx, EXPR_NULL, 0); CHECK_ERROR; }
393     | tNOTHING                      { $$ = new_expression(ctx, EXPR_NOTHING, 0); CHECK_ERROR; }
394 
395 NumericLiteralExpression
396     : '0'                           { $$ = new_long_expression(ctx, EXPR_INT, 0); CHECK_ERROR; }
397     | tInt                          { $$ = new_long_expression(ctx, EXPR_INT, $1); CHECK_ERROR; }
398     | tDouble                       { $$ = new_double_expression(ctx, $1); CHECK_ERROR; }
399 
400 IntegerValue
401     : '0'                           { $$ = 0; }
402     | tInt                          { $$ = $1; }
403 
404 PrimaryExpression
405     : '(' Expression ')'            { $$ = new_unary_expression(ctx, EXPR_BRACKETS, $2); }
406     | tME                           { $$ = new_expression(ctx, EXPR_ME, 0); CHECK_ERROR; }
407 
408 ClassDeclaration
409     : tCLASS Identifier StSep ClassBody tEND tCLASS StSep       { $4->name = $2; $$ = $4; }
410 
411 ClassBody
412     : /* empty */                                 { $$ = new_class_decl(ctx); }
413     | FunctionDecl                                { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
414     | FunctionDecl StSep ClassBody                { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
415     /* FIXME: We should use DimDecl here to support arrays, but that conflicts with PropertyDecl. */
416     | Storage tIdentifier                         { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
417                                                   $$ = add_dim_prop(ctx, new_class_decl(ctx), dim_decl, $1); CHECK_ERROR; }
418     | Storage tIdentifier StSep ClassBody         { dim_decl_t *dim_decl = new_dim_decl(ctx, $2, FALSE, NULL); CHECK_ERROR;
419                                                   $$ = add_dim_prop(ctx, $4, dim_decl, $1); CHECK_ERROR; }
420     | tDIM DimDecl                                { $$ = add_dim_prop(ctx, new_class_decl(ctx), $2, 0); CHECK_ERROR; }
421     | tDIM DimDecl StSep ClassBody                { $$ = add_dim_prop(ctx, $4, $2, 0); CHECK_ERROR; }
422     | PropertyDecl                                { $$ = add_class_function(ctx, new_class_decl(ctx), $1); CHECK_ERROR; }
423     | PropertyDecl StSep ClassBody                { $$ = add_class_function(ctx, $3, $1); CHECK_ERROR; }
424 
425 PropertyDecl
426     : Storage_opt tPROPERTY tGET tIdentifier ArgumentsDecl_opt StSep BodyStatements tEND tPROPERTY
427                                     { $$ = new_function_decl(ctx, $4, FUNC_PROPGET, $1, $5, $7); CHECK_ERROR; }
428     | Storage_opt tPROPERTY tLET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
429                                     { $$ = new_function_decl(ctx, $4, FUNC_PROPLET, $1, $6, $9); CHECK_ERROR; }
430     | Storage_opt tPROPERTY tSET tIdentifier '(' ArgumentDecl ')' StSep BodyStatements tEND tPROPERTY
431                                     { $$ = new_function_decl(ctx, $4, FUNC_PROPSET, $1, $6, $9); CHECK_ERROR; }
432 
433 FunctionDecl
434     : Storage_opt tSUB Identifier ArgumentsDecl_opt StSep BodyStatements tEND tSUB
435                                     { $$ = new_function_decl(ctx, $3, FUNC_SUB, $1, $4, $6); CHECK_ERROR; }
436     | Storage_opt tFUNCTION Identifier ArgumentsDecl_opt StSep BodyStatements tEND tFUNCTION
437                                     { $$ = new_function_decl(ctx, $3, FUNC_FUNCTION, $1, $4, $6); CHECK_ERROR; }
438 
439 Storage_opt
440     : /* empty*/                    { $$ = 0; }
441     | Storage                       { $$ = $1; }
442 
443 Storage
444     : tPUBLIC tDEFAULT              { $$ = STORAGE_IS_DEFAULT; }
445     | tPUBLIC                       { $$ = 0; }
446     | tPRIVATE                      { $$ = STORAGE_IS_PRIVATE; }
447 
448 ArgumentsDecl_opt
449     : EmptyBrackets_opt                         { $$ = NULL; }
450     | '(' ArgumentDeclList ')'                  { $$ = $2; }
451 
452 ArgumentDeclList
453     : ArgumentDecl                              { $$ = $1; }
454     | ArgumentDecl ',' ArgumentDeclList         { $1->next = $3; $$ = $1; }
455 
456 ArgumentDecl
457     : Identifier EmptyBrackets_opt              { $$ = new_argument_decl(ctx, $1, TRUE); }
458     | tBYREF Identifier EmptyBrackets_opt       { $$ = new_argument_decl(ctx, $2, TRUE); }
459     | tBYVAL Identifier EmptyBrackets_opt       { $$ = new_argument_decl(ctx, $2, FALSE); }
460 
461 /* these keywords may also be an identifier, depending on context */
462 Identifier
463     : tIdentifier    { $$ = $1; }
464     | tDEFAULT       { $$ = $1; }
465     | tERROR         { $$ = $1; }
466     | tEXPLICIT      { $$ = $1; }
467     | tPROPERTY      { $$ = $1; }
468     | tSTEP          { $$ = $1; }
469 
470 /* most keywords can be an identifier after a dot */
471 DotIdentifier
472     : Identifier     { $$ = $1; }
473     | tTRUE          { $$ = $1; }
474     | tFALSE         { $$ = $1; }
475     | tNOT           { $$ = $1; }
476     | tAND           { $$ = $1; }
477     | tOR            { $$ = $1; }
478     | tXOR           { $$ = $1; }
479     | tEQV           { $$ = $1; }
480     | tIMP           { $$ = $1; }
481     | tIS            { $$ = $1; }
482     | tMOD           { $$ = $1; }
483     | tCALL          { $$ = $1; }
484     | tDIM           { $$ = $1; }
485     | tSUB           { $$ = $1; }
486     | tFUNCTION      { $$ = $1; }
487     | tGET           { $$ = $1; }
488     | tLET           { $$ = $1; }
489     | tCONST         { $$ = $1; }
490     | tIF            { $$ = $1; }
491     | tELSE          { $$ = $1; }
492     | tELSEIF        { $$ = $1; }
493     | tEND           { $$ = $1; }
494     | tTHEN          { $$ = $1; }
495     | tEXIT          { $$ = $1; }
496     | tWHILE         { $$ = $1; }
497     | tWEND          { $$ = $1; }
498     | tDO            { $$ = $1; }
499     | tLOOP          { $$ = $1; }
500     | tUNTIL         { $$ = $1; }
501     | tFOR           { $$ = $1; }
502     | tTO            { $$ = $1; }
503     | tEACH          { $$ = $1; }
504     | tIN            { $$ = $1; }
505     | tSELECT        { $$ = $1; }
506     | tCASE          { $$ = $1; }
507     | tBYREF         { $$ = $1; }
508     | tBYVAL         { $$ = $1; }
509     | tOPTION        { $$ = $1; }
510     | tNOTHING       { $$ = $1; }
511     | tEMPTY         { $$ = $1; }
512     | tNULL          { $$ = $1; }
513     | tCLASS         { $$ = $1; }
514     | tSET           { $$ = $1; }
515     | tNEW           { $$ = $1; }
516     | tPUBLIC        { $$ = $1; }
517     | tPRIVATE       { $$ = $1; }
518     | tNEXT          { $$ = $1; }
519     | tON            { $$ = $1; }
520     | tRESUME        { $$ = $1; }
521     | tGOTO          { $$ = $1; }
522 
523 /* Most statements accept both new line and ':' as separators */
524 StSep
525     : tNL
526     | ':'
527     | tNL StSep
528     | ':' StSep
529 
530 %%
531 
532 static int parser_error(parser_ctx_t *ctx, const char *str)
533 {
534     return 0;
535 }
536 
537 static void source_add_statement(parser_ctx_t *ctx, statement_t *stat)
538 {
539     if(!stat)
540         return;
541 
542     if(ctx->stats) {
543         ctx->stats_tail->next = stat;
544         ctx->stats_tail = stat;
545     }else {
546         ctx->stats = ctx->stats_tail = stat;
547     }
548 }
549 
550 static void source_add_class(parser_ctx_t *ctx, class_decl_t *class_decl)
551 {
552     class_decl->next = ctx->class_decls;
553     ctx->class_decls = class_decl;
554 }
555 
556 static void parse_complete(parser_ctx_t *ctx, BOOL option_explicit)
557 {
558     ctx->parse_complete = TRUE;
559     ctx->option_explicit = option_explicit;
560 }
561 
562 static void handle_isexpression_script(parser_ctx_t *ctx, expression_t *expr)
563 {
564     retval_statement_t *stat;
565 
566     ctx->parse_complete = TRUE;
567     if(!expr)
568         return;
569 
570     stat = new_statement(ctx, STAT_RETVAL, sizeof(*stat));
571     if(!stat)
572         return;
573 
574     stat->expr = expr;
575     ctx->stats = &stat->stat;
576 }
577 
578 static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size)
579 {
580     expression_t *expr;
581 
582     expr = parser_alloc(ctx, size ? size : sizeof(*expr));
583     if(expr) {
584         expr->type = type;
585         expr->next = NULL;
586     }
587 
588     return expr;
589 }
590 
591 static expression_t *new_bool_expression(parser_ctx_t *ctx, VARIANT_BOOL value)
592 {
593     bool_expression_t *expr;
594 
595     expr = new_expression(ctx, EXPR_BOOL, sizeof(*expr));
596     if(!expr)
597         return NULL;
598 
599     expr->value = value;
600     return &expr->expr;
601 }
602 
603 static expression_t *new_string_expression(parser_ctx_t *ctx, const WCHAR *value)
604 {
605     string_expression_t *expr;
606 
607     expr = new_expression(ctx, EXPR_STRING, sizeof(*expr));
608     if(!expr)
609         return NULL;
610 
611     expr->value = value;
612     return &expr->expr;
613 }
614 
615 static expression_t *new_long_expression(parser_ctx_t *ctx, expression_type_t type, LONG value)
616 {
617     int_expression_t *expr;
618 
619     expr = new_expression(ctx, type, sizeof(*expr));
620     if(!expr)
621         return NULL;
622 
623     expr->value = value;
624     return &expr->expr;
625 }
626 
627 static expression_t *new_double_expression(parser_ctx_t *ctx, double value)
628 {
629     double_expression_t *expr;
630 
631     expr = new_expression(ctx, EXPR_DOUBLE, sizeof(*expr));
632     if(!expr)
633         return NULL;
634 
635     expr->value = value;
636     return &expr->expr;
637 }
638 
639 static expression_t *new_unary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *subexpr)
640 {
641     unary_expression_t *expr;
642 
643     expr = new_expression(ctx, type, sizeof(*expr));
644     if(!expr)
645         return NULL;
646 
647     expr->subexpr = subexpr;
648     return &expr->expr;
649 }
650 
651 static expression_t *new_binary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *left, expression_t *right)
652 {
653     binary_expression_t *expr;
654 
655     expr = new_expression(ctx, type, sizeof(*expr));
656     if(!expr)
657         return NULL;
658 
659     expr->left = left;
660     expr->right = right;
661     return &expr->expr;
662 }
663 
664 static member_expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *obj_expr, const WCHAR *identifier)
665 {
666     member_expression_t *expr;
667 
668     expr = new_expression(ctx, EXPR_MEMBER, sizeof(*expr));
669     if(!expr)
670         return NULL;
671 
672     expr->obj_expr = obj_expr;
673     expr->identifier = identifier;
674     expr->args = NULL;
675     return expr;
676 }
677 
678 static expression_t *new_new_expression(parser_ctx_t *ctx, const WCHAR *identifier)
679 {
680     string_expression_t *expr;
681 
682     expr = new_expression(ctx, EXPR_NEW, sizeof(*expr));
683     if(!expr)
684         return NULL;
685 
686     expr->value = identifier;
687     return &expr->expr;
688 }
689 
690 static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size)
691 {
692     statement_t *stat;
693 
694     stat = parser_alloc(ctx, size ? size : sizeof(*stat));
695     if(stat) {
696         stat->type = type;
697         stat->next = NULL;
698     }
699 
700     return stat;
701 }
702 
703 static statement_t *new_call_statement(parser_ctx_t *ctx, BOOL is_strict, member_expression_t *expr)
704 {
705     call_statement_t *stat;
706 
707     stat = new_statement(ctx, STAT_CALL, sizeof(*stat));
708     if(!stat)
709         return NULL;
710 
711     stat->expr = expr;
712     stat->is_strict = is_strict;
713     return &stat->stat;
714 }
715 
716 static statement_t *new_assign_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
717 {
718     assign_statement_t *stat;
719 
720     stat = new_statement(ctx, STAT_ASSIGN, sizeof(*stat));
721     if(!stat)
722         return NULL;
723 
724     stat->member_expr = left;
725     stat->value_expr = right;
726     return &stat->stat;
727 }
728 
729 static statement_t *new_set_statement(parser_ctx_t *ctx, member_expression_t *left, expression_t *right)
730 {
731     assign_statement_t *stat;
732 
733     stat = new_statement(ctx, STAT_SET, sizeof(*stat));
734     if(!stat)
735         return NULL;
736 
737     stat->member_expr = left;
738     stat->value_expr = right;
739     return &stat->stat;
740 }
741 
742 static dim_decl_t *new_dim_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL is_array, dim_list_t *dims)
743 {
744     dim_decl_t *decl;
745 
746     decl = parser_alloc(ctx, sizeof(*decl));
747     if(!decl)
748         return NULL;
749 
750     decl->name = name;
751     decl->is_array = is_array;
752     decl->dims = dims;
753     decl->next = NULL;
754     return decl;
755 }
756 
757 static dim_list_t *new_dim(parser_ctx_t *ctx, unsigned val, dim_list_t *next)
758 {
759     dim_list_t *ret;
760 
761     ret = parser_alloc(ctx, sizeof(*ret));
762     if(!ret)
763         return NULL;
764 
765     ret->val = val;
766     ret->next = next;
767     return ret;
768 }
769 
770 static statement_t *new_dim_statement(parser_ctx_t *ctx, dim_decl_t *decls)
771 {
772     dim_statement_t *stat;
773 
774     stat = new_statement(ctx, STAT_DIM, sizeof(*stat));
775     if(!stat)
776         return NULL;
777 
778     stat->dim_decls = decls;
779     return &stat->stat;
780 }
781 
782 static elseif_decl_t *new_elseif_decl(parser_ctx_t *ctx, expression_t *expr, statement_t *stat)
783 {
784     elseif_decl_t *decl;
785 
786     decl = parser_alloc(ctx, sizeof(*decl));
787     if(!decl)
788         return NULL;
789 
790     decl->expr = expr;
791     decl->stat = stat;
792     decl->next = NULL;
793     return decl;
794 }
795 
796 static statement_t *new_while_statement(parser_ctx_t *ctx, statement_type_t type, expression_t *expr, statement_t *body)
797 {
798     while_statement_t *stat;
799 
800     stat = new_statement(ctx, type, sizeof(*stat));
801     if(!stat)
802         return NULL;
803 
804     stat->expr = expr;
805     stat->body = body;
806     return &stat->stat;
807 }
808 
809 static statement_t *new_forto_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *from_expr,
810         expression_t *to_expr, expression_t *step_expr, statement_t *body)
811 {
812     forto_statement_t *stat;
813 
814     stat = new_statement(ctx, STAT_FORTO, sizeof(*stat));
815     if(!stat)
816         return NULL;
817 
818     stat->identifier = identifier;
819     stat->from_expr = from_expr;
820     stat->to_expr = to_expr;
821     stat->step_expr = step_expr;
822     stat->body = body;
823     return &stat->stat;
824 }
825 
826 static statement_t *new_foreach_statement(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *group_expr,
827         statement_t *body)
828 {
829     foreach_statement_t *stat;
830 
831     stat = new_statement(ctx, STAT_FOREACH, sizeof(*stat));
832     if(!stat)
833         return NULL;
834 
835     stat->identifier = identifier;
836     stat->group_expr = group_expr;
837     stat->body = body;
838     return &stat->stat;
839 }
840 
841 static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, elseif_decl_t *elseif_decl,
842         statement_t *else_stat)
843 {
844     if_statement_t *stat;
845 
846     stat = new_statement(ctx, STAT_IF, sizeof(*stat));
847     if(!stat)
848         return NULL;
849 
850     stat->expr = expr;
851     stat->if_stat = if_stat;
852     stat->elseifs = elseif_decl;
853     stat->else_stat = else_stat;
854     return &stat->stat;
855 }
856 
857 static statement_t *new_select_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_clausules)
858 {
859     select_statement_t *stat;
860 
861     stat = new_statement(ctx, STAT_SELECT, sizeof(*stat));
862     if(!stat)
863         return NULL;
864 
865     stat->expr = expr;
866     stat->case_clausules = case_clausules;
867     return &stat->stat;
868 }
869 
870 static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_t *stat, case_clausule_t *next)
871 {
872     case_clausule_t *ret;
873 
874     ret = parser_alloc(ctx, sizeof(*ret));
875     if(!ret)
876         return NULL;
877 
878     ret->expr = expr;
879     ret->stat = stat;
880     ret->next = next;
881     return ret;
882 }
883 
884 static statement_t *new_onerror_statement(parser_ctx_t *ctx, BOOL resume_next)
885 {
886     onerror_statement_t *stat;
887 
888     stat = new_statement(ctx, STAT_ONERROR, sizeof(*stat));
889     if(!stat)
890         return NULL;
891 
892     stat->resume_next = resume_next;
893     return &stat->stat;
894 }
895 
896 static arg_decl_t *new_argument_decl(parser_ctx_t *ctx, const WCHAR *name, BOOL by_ref)
897 {
898     arg_decl_t *arg_decl;
899 
900     arg_decl = parser_alloc(ctx, sizeof(*arg_decl));
901     if(!arg_decl)
902         return NULL;
903 
904     arg_decl->name = name;
905     arg_decl->by_ref = by_ref;
906     arg_decl->next = NULL;
907     return arg_decl;
908 }
909 
910 static function_decl_t *new_function_decl(parser_ctx_t *ctx, const WCHAR *name, function_type_t type,
911         unsigned storage_flags, arg_decl_t *arg_decl, statement_t *body)
912 {
913     function_decl_t *decl;
914 
915     if(storage_flags & STORAGE_IS_DEFAULT) {
916         if(type == FUNC_PROPGET) {
917             type = FUNC_DEFGET;
918         }else {
919             FIXME("Invalid default property\n");
920             ctx->hres = E_FAIL;
921             return NULL;
922         }
923     }
924 
925     decl = parser_alloc(ctx, sizeof(*decl));
926     if(!decl)
927         return NULL;
928 
929     decl->name = name;
930     decl->type = type;
931     decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
932     decl->args = arg_decl;
933     decl->body = body;
934     decl->next = NULL;
935     decl->next_prop_func = NULL;
936     return decl;
937 }
938 
939 static statement_t *new_function_statement(parser_ctx_t *ctx, function_decl_t *decl)
940 {
941     function_statement_t *stat;
942 
943     stat = new_statement(ctx, STAT_FUNC, sizeof(*stat));
944     if(!stat)
945         return NULL;
946 
947     stat->func_decl = decl;
948     return &stat->stat;
949 }
950 
951 static class_decl_t *new_class_decl(parser_ctx_t *ctx)
952 {
953     class_decl_t *class_decl;
954 
955     class_decl = parser_alloc(ctx, sizeof(*class_decl));
956     if(!class_decl)
957         return NULL;
958 
959     class_decl->funcs = NULL;
960     class_decl->props = NULL;
961     class_decl->next = NULL;
962     return class_decl;
963 }
964 
965 static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_decl, function_decl_t *decl)
966 {
967     function_decl_t *iter;
968 
969     for(iter = class_decl->funcs; iter; iter = iter->next) {
970         if(!wcsicmp(iter->name, decl->name)) {
971             if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) {
972                 FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
973                 ctx->hres = E_FAIL;
974                 return NULL;
975             }
976 
977             while(1) {
978                 if(iter->type == decl->type) {
979                     FIXME("Redefinition of %s::%s\n", debugstr_w(class_decl->name), debugstr_w(decl->name));
980                     ctx->hres = E_FAIL;
981                     return NULL;
982                 }
983                 if(!iter->next_prop_func)
984                     break;
985                 iter = iter->next_prop_func;
986             }
987 
988             iter->next_prop_func = decl;
989             return class_decl;
990         }
991     }
992 
993     decl->next = class_decl->funcs;
994     class_decl->funcs = decl;
995     return class_decl;
996 }
997 
998 static class_decl_t *add_dim_prop(parser_ctx_t *ctx, class_decl_t *class_decl, dim_decl_t *dim_decl, unsigned storage_flags)
999 {
1000     if(storage_flags & STORAGE_IS_DEFAULT) {
1001         FIXME("variant prop van't be default value\n");
1002         ctx->hres = E_FAIL;
1003         return NULL;
1004     }
1005 
1006     dim_decl->is_public = !(storage_flags & STORAGE_IS_PRIVATE);
1007     dim_decl->next = class_decl->props;
1008     class_decl->props = dim_decl;
1009     return class_decl;
1010 }
1011 
1012 static const_decl_t *new_const_decl(parser_ctx_t *ctx, const WCHAR *name, expression_t *expr)
1013 {
1014     const_decl_t *decl;
1015 
1016     decl = parser_alloc(ctx, sizeof(*decl));
1017     if(!decl)
1018         return NULL;
1019 
1020     decl->name = name;
1021     decl->value_expr = expr;
1022     decl->next = NULL;
1023     return decl;
1024 }
1025 
1026 static statement_t *new_const_statement(parser_ctx_t *ctx, const_decl_t *decls)
1027 {
1028     const_statement_t *stat;
1029 
1030     stat = new_statement(ctx, STAT_CONST, sizeof(*stat));
1031     if(!stat)
1032         return NULL;
1033 
1034     stat->decls = decls;
1035     return &stat->stat;
1036 }
1037 
1038 static statement_t *link_statements(statement_t *head, statement_t *tail)
1039 {
1040     statement_t *iter;
1041 
1042     for(iter = head; iter->next; iter = iter->next);
1043     iter->next = tail;
1044 
1045     return head;
1046 }
1047 
1048 void *parser_alloc(parser_ctx_t *ctx, size_t size)
1049 {
1050     void *ret;
1051 
1052     ret = heap_pool_alloc(&ctx->heap, size);
1053     if(!ret)
1054         ctx->hres = E_OUTOFMEMORY;
1055     return ret;
1056 }
1057 
1058 HRESULT parse_script(parser_ctx_t *ctx, const WCHAR *code, const WCHAR *delimiter, DWORD flags)
1059 {
1060     static const WCHAR html_delimiterW[] = {'<','/','s','c','r','i','p','t','>',0};
1061 
1062     ctx->code = ctx->ptr = code;
1063     ctx->end = ctx->code + lstrlenW(ctx->code);
1064 
1065     heap_pool_init(&ctx->heap);
1066 
1067     ctx->parse_complete = FALSE;
1068     ctx->hres = S_OK;
1069 
1070     ctx->last_token = tNL;
1071     ctx->last_nl = 0;
1072     ctx->stats = ctx->stats_tail = NULL;
1073     ctx->class_decls = NULL;
1074     ctx->option_explicit = FALSE;
1075     ctx->is_html = delimiter && !wcsicmp(delimiter, html_delimiterW);
1076 
1077     if(flags & SCRIPTTEXT_ISEXPRESSION)
1078         ctx->last_token = tEXPRESSION;
1079 
1080     parser_parse(ctx);
1081 
1082     if(FAILED(ctx->hres))
1083         return ctx->hres;
1084     if(!ctx->parse_complete) {
1085         FIXME("parser failed around %s\n", debugstr_w(ctx->code+20 > ctx->ptr ? ctx->code : ctx->ptr-20));
1086         return E_FAIL;
1087     }
1088 
1089     return S_OK;
1090 }
1091 
1092 void parser_release(parser_ctx_t *ctx)
1093 {
1094     heap_pool_free(&ctx->heap);
1095 }
1096