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