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