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