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