Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610/* * Copyright 2008 Jacek Caban for CodeWeavers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */%{#include "jscript.h"#include "engine.h"#include "parser.h"#include "wine/debug.h"WINE_DEFAULT_DEBUG_CHANNEL(jscript);static int parser_error(parser_ctx_t*,const char*);static void set_error(parser_ctx_t*,UINT);static BOOL explicit_error(parser_ctx_t*,void*,WCHAR);static BOOL allow_auto_semicolon(parser_ctx_t*);static void program_parsed(parser_ctx_t*,source_elements_t*);typedef struct _statement_list_t { statement_t *head; statement_t *tail;} statement_list_t;static literal_t *new_string_literal(parser_ctx_t*,jsstr_t*);static literal_t *new_null_literal(parser_ctx_t*);typedef struct _property_list_t { property_definition_t *head; property_definition_t *tail;} property_list_t;static property_definition_t *new_property_definition(parser_ctx_t *ctx, property_definition_type_t, literal_t *name, expression_t *value);static property_list_t *new_property_list(parser_ctx_t*,property_definition_t*);static property_list_t *property_list_add(parser_ctx_t*,property_list_t*,property_definition_t*);typedef struct _element_list_t { array_element_t *head; array_element_t *tail;} element_list_t;static element_list_t *new_element_list(parser_ctx_t*,int,expression_t*);static element_list_t *element_list_add(parser_ctx_t*,element_list_t*,int,expression_t*);typedef struct _argument_list_t { argument_t *head; argument_t *tail;} argument_list_t;static argument_list_t *new_argument_list(parser_ctx_t*,expression_t*);static argument_list_t *argument_list_add(parser_ctx_t*,argument_list_t*,expression_t*);typedef struct _case_list_t { case_clausule_t *head; case_clausule_t *tail;} case_list_t;static catch_block_t *new_catch_block(parser_ctx_t*,const WCHAR*,statement_t*);static case_clausule_t *new_case_clausule(parser_ctx_t*,expression_t*,statement_list_t*);static case_list_t *new_case_list(parser_ctx_t*,case_clausule_t*);static case_list_t *case_list_add(parser_ctx_t*,case_list_t*,case_clausule_t*);static case_clausule_t *new_case_block(parser_ctx_t*,case_list_t*,case_clausule_t*,case_list_t*);typedef struct _variable_list_t { variable_declaration_t *head; variable_declaration_t *tail;} variable_list_t;static variable_declaration_t *new_variable_declaration(parser_ctx_t*,const WCHAR*,expression_t*);static variable_list_t *new_variable_list(parser_ctx_t*,variable_declaration_t*);static variable_list_t *variable_list_add(parser_ctx_t*,variable_list_t*,variable_declaration_t*);static void *new_statement(parser_ctx_t*,statement_type_t,size_t);static statement_t *new_block_statement(parser_ctx_t*,statement_list_t*);static statement_t *new_var_statement(parser_ctx_t*,variable_list_t*);static statement_t *new_expression_statement(parser_ctx_t*,expression_t*);static statement_t *new_if_statement(parser_ctx_t*,expression_t*,statement_t*,statement_t*);static statement_t *new_while_statement(parser_ctx_t*,BOOL,expression_t*,statement_t*);static statement_t *new_for_statement(parser_ctx_t*,variable_list_t*,expression_t*,expression_t*, expression_t*,statement_t*);static statement_t *new_forin_statement(parser_ctx_t*,variable_declaration_t*,expression_t*,expression_t*,statement_t*);static statement_t *new_continue_statement(parser_ctx_t*,const WCHAR*);static statement_t *new_break_statement(parser_ctx_t*,const WCHAR*);static statement_t *new_return_statement(parser_ctx_t*,expression_t*);static statement_t *new_with_statement(parser_ctx_t*,expression_t*,statement_t*);static statement_t *new_labelled_statement(parser_ctx_t*,const WCHAR*,statement_t*);static statement_t *new_switch_statement(parser_ctx_t*,expression_t*,case_clausule_t*);static statement_t *new_throw_statement(parser_ctx_t*,expression_t*);static statement_t *new_try_statement(parser_ctx_t*,statement_t*,catch_block_t*,statement_t*);struct statement_list_t { statement_t *head; statement_t *tail;};static statement_list_t *new_statement_list(parser_ctx_t*,statement_t*);static statement_list_t *statement_list_add(statement_list_t*,statement_t*);typedef struct _parameter_list_t { parameter_t *head; parameter_t *tail;} parameter_list_t;static parameter_list_t *new_parameter_list(parser_ctx_t*,const WCHAR*);static parameter_list_t *parameter_list_add(parser_ctx_t*,parameter_list_t*,const WCHAR*);static void *new_expression(parser_ctx_t *ctx,expression_type_t,size_t);static expression_t *new_function_expression(parser_ctx_t*,const WCHAR*,parameter_list_t*, source_elements_t*,const WCHAR*,const WCHAR*,DWORD);static expression_t *new_binary_expression(parser_ctx_t*,expression_type_t,expression_t*,expression_t*);static expression_t *new_unary_expression(parser_ctx_t*,expression_type_t,expression_t*);static expression_t *new_conditional_expression(parser_ctx_t*,expression_t*,expression_t*,expression_t*);static expression_t *new_member_expression(parser_ctx_t*,expression_t*,const WCHAR*);static expression_t *new_new_expression(parser_ctx_t*,expression_t*,argument_list_t*);static expression_t *new_call_expression(parser_ctx_t*,expression_t*,argument_list_t*);static expression_t *new_identifier_expression(parser_ctx_t*,const WCHAR*);static expression_t *new_literal_expression(parser_ctx_t*,literal_t*);static expression_t *new_array_literal_expression(parser_ctx_t*,element_list_t*,int);static expression_t *new_prop_and_value_expression(parser_ctx_t*,property_list_t*);static source_elements_t *new_source_elements(parser_ctx_t*);static source_elements_t *source_elements_add_statement(source_elements_t*,statement_t*);%}%lex-param { parser_ctx_t *ctx }%parse-param { parser_ctx_t *ctx }%define api.pure%start Program%union { int ival; const WCHAR *srcptr; jsstr_t *str; literal_t *literal; struct _argument_list_t *argument_list; case_clausule_t *case_clausule; struct _case_list_t *case_list; catch_block_t *catch_block; struct _element_list_t *element_list; expression_t *expr; const WCHAR *identifier; struct _parameter_list_t *parameter_list; struct _property_list_t *property_list; property_definition_t *property_definition; source_elements_t *source_elements; statement_t *statement; struct _statement_list_t *statement_list; struct _variable_list_t *variable_list; variable_declaration_t *variable_declaration;}/* keywords */%token <identifier> kBREAK kCASE kCATCH kCONTINUE kDEFAULT kDELETE kDO kELSE kFUNCTION kIF kFINALLY kFOR kGET kIN kSET%token <identifier> kINSTANCEOF kNEW kNULL kRETURN kSWITCH kTHIS kTHROW kTRUE kFALSE kTRY kTYPEOF kVAR kVOID kWHILE kWITH%token tANDAND tOROR tINC tDEC tHTMLCOMMENT kDIVEQ kDCOL%token <srcptr> '}'/* tokens */%token <identifier> tIdentifier%token <ival> tAssignOper tEqOper tShiftOper tRelOper%token <literal> tNumericLiteral tBooleanLiteral%token <str> tStringLiteral%token tEOF%type <source_elements> SourceElements%type <source_elements> FunctionBody%type <statement> Statement%type <statement> Block%type <statement> VariableStatement%type <statement> EmptyStatement%type <statement> ExpressionStatement%type <statement> IfStatement%type <statement> IterationStatement%type <statement> ContinueStatement%type <statement> BreakStatement%type <statement> ReturnStatement%type <statement> WithStatement%type <statement> LabelledStatement%type <statement> SwitchStatement%type <statement> ThrowStatement%type <statement> TryStatement%type <statement> Finally%type <statement_list> StatementList StatementList_opt%type <parameter_list> FormalParameterList FormalParameterList_opt%type <expr> Expression Expression_opt Expression_err%type <expr> ExpressionNoIn ExpressionNoIn_opt%type <expr> FunctionExpression%type <expr> AssignmentExpression AssignmentExpressionNoIn%type <expr> ConditionalExpression ConditionalExpressionNoIn%type <expr> LeftHandSideExpression%type <expr> LogicalORExpression LogicalORExpressionNoIn%type <expr> LogicalANDExpression LogicalANDExpressionNoIn%type <expr> BitwiseORExpression BitwiseORExpressionNoIn%type <expr> BitwiseXORExpression BitwiseXORExpressionNoIn%type <expr> BitwiseANDExpression BitwiseANDExpressionNoIn%type <expr> EqualityExpression EqualityExpressionNoIn%type <expr> RelationalExpression RelationalExpressionNoIn%type <expr> ShiftExpression%type <expr> AdditiveExpression%type <expr> MultiplicativeExpression%type <expr> Initialiser_opt Initialiser%type <expr> InitialiserNoIn_opt InitialiserNoIn%type <expr> UnaryExpression%type <expr> PostfixExpression%type <expr> NewExpression%type <expr> CallExpression%type <expr> MemberExpression%type <expr> PrimaryExpression%type <expr> GetterSetterMethod%type <identifier> Identifier_opt%type <variable_list> VariableDeclarationList%type <variable_list> VariableDeclarationListNoIn%type <variable_declaration> VariableDeclaration%type <variable_declaration> VariableDeclarationNoIn%type <case_list> CaseClausules CaseClausules_opt%type <case_clausule> CaseClausule DefaultClausule CaseBlock%type <catch_block> Catch%type <argument_list> Arguments%type <argument_list> ArgumentList%type <literal> Literal%type <expr> ArrayLiteral%type <expr> ObjectLiteral%type <ival> Elision Elision_opt%type <element_list> ElementList%type <property_list> PropertyNameAndValueList%type <property_definition> PropertyDefinition%type <literal> PropertyName%type <literal> BooleanLiteral%type <srcptr> KFunction left_bracket%type <ival> AssignOper%type <identifier> IdentifierName ReservedAsIdentifier%nonassoc LOWER_THAN_ELSE%nonassoc kELSE%%/* ECMA-262 3rd Edition 14 */Program : SourceElements HtmlComment tEOF { program_parsed(ctx, $1); }HtmlComment : tHTMLCOMMENT {} | /* empty */ {}/* ECMA-262 3rd Edition 14 */SourceElements : /* empty */ { $$ = new_source_elements(ctx); } | SourceElements Statement { $$ = source_elements_add_statement($1, $2); }/* ECMA-262 3rd Edition 13 */FunctionExpression : KFunction left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, NULL, $3, $6, NULL, $1, $7-$1+1); } | KFunction tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, $2, $4, $7, NULL, $1, $8-$1+1); } | KFunction tIdentifier kDCOL tIdentifier left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, $4, $6, $9, $2, $1, $10-$1+1); }KFunction : kFUNCTION { $$ = ctx->ptr - 8; }/* ECMA-262 3rd Edition 13 */FunctionBody : SourceElements { $$ = $1; }/* ECMA-262 3rd Edition 13 */FormalParameterList : tIdentifier { $$ = new_parameter_list(ctx, $1); } | FormalParameterList ',' tIdentifier { $$ = parameter_list_add(ctx, $1, $3); }/* ECMA-262 3rd Edition 13 */FormalParameterList_opt : /* empty */ { $$ = NULL; } | FormalParameterList { $$ = $1; }/* ECMA-262 3rd Edition 12 */Statement : Block { $$ = $1; } | VariableStatement { $$ = $1; } | EmptyStatement { $$ = $1; } | FunctionExpression { $$ = new_expression_statement(ctx, $1); } | ExpressionStatement { $$ = $1; } | IfStatement { $$ = $1; } | IterationStatement { $$ = $1; } | ContinueStatement { $$ = $1; } | BreakStatement { $$ = $1; } | ReturnStatement { $$ = $1; } | WithStatement { $$ = $1; } | LabelledStatement { $$ = $1; } | SwitchStatement { $$ = $1; } | ThrowStatement { $$ = $1; } | TryStatement { $$ = $1; }/* ECMA-262 3rd Edition 12.2 */StatementList : Statement { $$ = new_statement_list(ctx, $1); } | StatementList Statement { $$ = statement_list_add($1, $2); }/* ECMA-262 3rd Edition 12.2 */StatementList_opt : /* empty */ { $$ = NULL; } | StatementList { $$ = $1; }/* ECMA-262 3rd Edition 12.1 */Block : '{' StatementList '}' { $$ = new_block_statement(ctx, $2); } | '{' '}' { $$ = new_block_statement(ctx, NULL); }/* ECMA-262 3rd Edition 12.2 */VariableStatement : kVAR VariableDeclarationList semicolon_opt { $$ = new_var_statement(ctx, $2); }/* ECMA-262 3rd Edition 12.2 */VariableDeclarationList : VariableDeclaration { $$ = new_variable_list(ctx, $1); } | VariableDeclarationList ',' VariableDeclaration { $$ = variable_list_add(ctx, $1, $3); }/* ECMA-262 3rd Edition 12.2 */VariableDeclarationListNoIn : VariableDeclarationNoIn { $$ = new_variable_list(ctx, $1); } | VariableDeclarationListNoIn ',' VariableDeclarationNoIn { $$ = variable_list_add(ctx, $1, $3); }/* ECMA-262 3rd Edition 12.2 */VariableDeclaration : tIdentifier Initialiser_opt { $$ = new_variable_declaration(ctx, $1, $2); }/* ECMA-262 3rd Edition 12.2 */VariableDeclarationNoIn : tIdentifier InitialiserNoIn_opt { $$ = new_variable_declaration(ctx, $1, $2); }/* ECMA-262 3rd Edition 12.2 */Initialiser_opt : /* empty */ { $$ = NULL; } | Initialiser { $$ = $1; }/* ECMA-262 3rd Edition 12.2 */Initialiser : '=' AssignmentExpression { $$ = $2; }/* ECMA-262 3rd Edition 12.2 */InitialiserNoIn_opt : /* empty */ { $$ = NULL; } | InitialiserNoIn { $$ = $1; }/* ECMA-262 3rd Edition 12.2 */InitialiserNoIn : '=' AssignmentExpressionNoIn { $$ = $2; }/* ECMA-262 3rd Edition 12.3 */EmptyStatement : ';' { $$ = new_statement(ctx, STAT_EMPTY, 0); }/* ECMA-262 3rd Edition 12.4 */ExpressionStatement : Expression semicolon_opt { $$ = new_expression_statement(ctx, $1); }/* ECMA-262 3rd Edition 12.5 */IfStatement : kIF left_bracket Expression_err right_bracket Statement kELSE Statement { $$ = new_if_statement(ctx, $3, $5, $7); } | kIF left_bracket Expression_err right_bracket Statement %prec LOWER_THAN_ELSE { $$ = new_if_statement(ctx, $3, $5, NULL); }/* ECMA-262 3rd Edition 12.6 */IterationStatement : kDO Statement kWHILE left_bracket Expression_err right_bracket semicolon_opt { $$ = new_while_statement(ctx, TRUE, $5, $2); } | kWHILE left_bracket Expression_err right_bracket Statement { $$ = new_while_statement(ctx, FALSE, $3, $5); } | kFOR left_bracket ExpressionNoIn_opt { if(!explicit_error(ctx, $3, ';')) YYABORT; } semicolon Expression_opt { if(!explicit_error(ctx, $6, ';')) YYABORT; } semicolon Expression_opt right_bracket Statement { $$ = new_for_statement(ctx, NULL, $3, $6, $9, $11); } | kFOR left_bracket kVAR VariableDeclarationListNoIn { if(!explicit_error(ctx, $4, ';')) YYABORT; } semicolon Expression_opt { if(!explicit_error(ctx, $7, ';')) YYABORT; } semicolon Expression_opt right_bracket Statement { $$ = new_for_statement(ctx, $4, NULL, $7, $10, $12); } | kFOR left_bracket LeftHandSideExpression kIN Expression_err right_bracket Statement { $$ = new_forin_statement(ctx, NULL, $3, $5, $7); } | kFOR left_bracket kVAR VariableDeclarationNoIn kIN Expression_err right_bracket Statement { $$ = new_forin_statement(ctx, $4, NULL, $6, $8); }/* ECMA-262 3rd Edition 12.7 */ContinueStatement : kCONTINUE /* NONL */ Identifier_opt semicolon_opt { $$ = new_continue_statement(ctx, $2); }/* ECMA-262 3rd Edition 12.8 */BreakStatement : kBREAK /* NONL */ Identifier_opt semicolon_opt { $$ = new_break_statement(ctx, $2); }/* ECMA-262 3rd Edition 12.9 */ReturnStatement : kRETURN /* NONL */ Expression_opt semicolon_opt { $$ = new_return_statement(ctx, $2); }/* ECMA-262 3rd Edition 12.10 */WithStatement : kWITH left_bracket Expression right_bracket Statement { $$ = new_with_statement(ctx, $3, $5); }/* ECMA-262 3rd Edition 12.12 */LabelledStatement : tIdentifier ':' Statement { $$ = new_labelled_statement(ctx, $1, $3); }/* ECMA-262 3rd Edition 12.11 */SwitchStatement : kSWITCH left_bracket Expression right_bracket CaseBlock { $$ = new_switch_statement(ctx, $3, $5); }/* ECMA-262 3rd Edition 12.11 */CaseBlock : '{' CaseClausules_opt '}' { $$ = new_case_block(ctx, $2, NULL, NULL); } | '{' CaseClausules_opt DefaultClausule CaseClausules_opt '}' { $$ = new_case_block(ctx, $2, $3, $4); }/* ECMA-262 3rd Edition 12.11 */CaseClausules_opt : /* empty */ { $$ = NULL; } | CaseClausules { $$ = $1; }/* ECMA-262 3rd Edition 12.11 */CaseClausules : CaseClausule { $$ = new_case_list(ctx, $1); } | CaseClausules CaseClausule { $$ = case_list_add(ctx, $1, $2); }/* ECMA-262 3rd Edition 12.11 */CaseClausule : kCASE Expression ':' StatementList_opt { $$ = new_case_clausule(ctx, $2, $4); }/* ECMA-262 3rd Edition 12.11 */DefaultClausule : kDEFAULT ':' StatementList_opt { $$ = new_case_clausule(ctx, NULL, $3); }/* ECMA-262 3rd Edition 12.13 */ThrowStatement : kTHROW /* NONL */ Expression semicolon_opt { $$ = new_throw_statement(ctx, $2); }/* ECMA-262 3rd Edition 12.14 */TryStatement : kTRY Block Catch { $$ = new_try_statement(ctx, $2, $3, NULL); } | kTRY Block Finally { $$ = new_try_statement(ctx, $2, NULL, $3); } | kTRY Block Catch Finally { $$ = new_try_statement(ctx, $2, $3, $4); }/* ECMA-262 3rd Edition 12.14 */Catch : kCATCH left_bracket tIdentifier right_bracket Block { $$ = new_catch_block(ctx, $3, $5); }/* ECMA-262 3rd Edition 12.14 */Finally : kFINALLY Block { $$ = $2; }/* ECMA-262 3rd Edition 11.14 */Expression_opt : /* empty */ { $$ = NULL; } | Expression { $$ = $1; }Expression_err : Expression { $$ = $1; } | error { set_error(ctx, JS_E_SYNTAX); YYABORT; }/* ECMA-262 3rd Edition 11.14 */Expression : AssignmentExpression { $$ = $1; } | Expression ',' AssignmentExpression { $$ = new_binary_expression(ctx, EXPR_COMMA, $1, $3); }/* ECMA-262 3rd Edition 11.14 */ExpressionNoIn_opt : /* empty */ { $$ = NULL; } | ExpressionNoIn { $$ = $1; }/* ECMA-262 3rd Edition 11.14 */ExpressionNoIn : AssignmentExpressionNoIn { $$ = $1; } | ExpressionNoIn ',' AssignmentExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_COMMA, $1, $3); }AssignOper : tAssignOper { $$ = $1; } | kDIVEQ { $$ = EXPR_ASSIGNDIV; }/* ECMA-262 3rd Edition 11.13 */AssignmentExpression : ConditionalExpression { $$ = $1; } | LeftHandSideExpression '=' AssignmentExpression { $$ = new_binary_expression(ctx, EXPR_ASSIGN, $1, $3); } | LeftHandSideExpression AssignOper AssignmentExpression { $$ = new_binary_expression(ctx, $2, $1, $3); }/* ECMA-262 3rd Edition 11.13 */AssignmentExpressionNoIn : ConditionalExpressionNoIn { $$ = $1; } | LeftHandSideExpression '=' AssignmentExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_ASSIGN, $1, $3); } | LeftHandSideExpression AssignOper AssignmentExpressionNoIn { $$ = new_binary_expression(ctx, $2, $1, $3); }/* ECMA-262 3rd Edition 11.12 */ConditionalExpression : LogicalORExpression { $$ = $1; } | LogicalORExpression '?' AssignmentExpression ':' AssignmentExpression { $$ = new_conditional_expression(ctx, $1, $3, $5); }/* ECMA-262 3rd Edition 11.12 */ConditionalExpressionNoIn : LogicalORExpressionNoIn { $$ = $1; } | LogicalORExpressionNoIn '?' AssignmentExpressionNoIn ':' AssignmentExpressionNoIn { $$ = new_conditional_expression(ctx, $1, $3, $5); }/* ECMA-262 3rd Edition 11.11 */LogicalORExpression : LogicalANDExpression { $$ = $1; } | LogicalORExpression tOROR LogicalANDExpression { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); }/* ECMA-262 3rd Edition 11.11 */LogicalORExpressionNoIn : LogicalANDExpressionNoIn { $$ = $1; } | LogicalORExpressionNoIn tOROR LogicalANDExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_OR, $1, $3); }/* ECMA-262 3rd Edition 11.11 */LogicalANDExpression : BitwiseORExpression { $$ = $1; } | LogicalANDExpression tANDAND BitwiseORExpression { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); }/* ECMA-262 3rd Edition 11.11 */LogicalANDExpressionNoIn : BitwiseORExpressionNoIn { $$ = $1; } | LogicalANDExpressionNoIn tANDAND BitwiseORExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_AND, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseORExpression : BitwiseXORExpression { $$ = $1; } | BitwiseORExpression '|' BitwiseXORExpression { $$ = new_binary_expression(ctx, EXPR_BOR, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseORExpressionNoIn : BitwiseXORExpressionNoIn { $$ = $1; } | BitwiseORExpressionNoIn '|' BitwiseXORExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_BOR, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseXORExpression : BitwiseANDExpression { $$ = $1; } | BitwiseXORExpression '^' BitwiseANDExpression { $$ = new_binary_expression(ctx, EXPR_BXOR, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseXORExpressionNoIn : BitwiseANDExpressionNoIn { $$ = $1; } | BitwiseXORExpressionNoIn '^' BitwiseANDExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_BXOR, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseANDExpression : EqualityExpression { $$ = $1; } | BitwiseANDExpression '&' EqualityExpression { $$ = new_binary_expression(ctx, EXPR_BAND, $1, $3); }/* ECMA-262 3rd Edition 11.10 */BitwiseANDExpressionNoIn : EqualityExpressionNoIn { $$ = $1; } | BitwiseANDExpressionNoIn '&' EqualityExpressionNoIn { $$ = new_binary_expression(ctx, EXPR_BAND, $1, $3); }/* ECMA-262 3rd Edition 11.9 */EqualityExpression : RelationalExpression { $$ = $1; } | EqualityExpression tEqOper RelationalExpression { $$ = new_binary_expression(ctx, $2, $1, $3); }/* ECMA-262 3rd Edition 11.9 */EqualityExpressionNoIn : RelationalExpressionNoIn { $$ = $1; } | EqualityExpressionNoIn tEqOper RelationalExpressionNoIn { $$ = new_binary_expression(ctx, $2, $1, $3); }/* ECMA-262 3rd Edition 11.8 */RelationalExpression : ShiftExpression { $$ = $1; } | RelationalExpression tRelOper ShiftExpression { $$ = new_binary_expression(ctx, $2, $1, $3); } | RelationalExpression kINSTANCEOF ShiftExpression { $$ = new_binary_expression(ctx, EXPR_INSTANCEOF, $1, $3); } | RelationalExpression kIN ShiftExpression { $$ = new_binary_expression(ctx, EXPR_IN, $1, $3); }/* ECMA-262 3rd Edition 11.8 */RelationalExpressionNoIn : ShiftExpression { $$ = $1; } | RelationalExpressionNoIn tRelOper ShiftExpression { $$ = new_binary_expression(ctx, $2, $1, $3); } | RelationalExpressionNoIn kINSTANCEOF ShiftExpression { $$ = new_binary_expression(ctx, EXPR_INSTANCEOF, $1, $3); }/* ECMA-262 3rd Edition 11.7 */ShiftExpression : AdditiveExpression { $$ = $1; } | ShiftExpression tShiftOper AdditiveExpression { $$ = new_binary_expression(ctx, $2, $1, $3); }/* ECMA-262 3rd Edition 11.6 */AdditiveExpression : MultiplicativeExpression { $$ = $1; } | AdditiveExpression '+' MultiplicativeExpression { $$ = new_binary_expression(ctx, EXPR_ADD, $1, $3); } | AdditiveExpression '-' MultiplicativeExpression { $$ = new_binary_expression(ctx, EXPR_SUB, $1, $3); }/* ECMA-262 3rd Edition 11.5 */MultiplicativeExpression : UnaryExpression { $$ = $1; } | MultiplicativeExpression '*' UnaryExpression { $$ = new_binary_expression(ctx, EXPR_MUL, $1, $3); } | MultiplicativeExpression '/' UnaryExpression { $$ = new_binary_expression(ctx, EXPR_DIV, $1, $3); } | MultiplicativeExpression '%' UnaryExpression { $$ = new_binary_expression(ctx, EXPR_MOD, $1, $3); }/* ECMA-262 3rd Edition 11.4 */UnaryExpression : PostfixExpression { $$ = $1; } | kDELETE UnaryExpression { $$ = new_unary_expression(ctx, EXPR_DELETE, $2); } | kVOID UnaryExpression { $$ = new_unary_expression(ctx, EXPR_VOID, $2); } | kTYPEOF UnaryExpression { $$ = new_unary_expression(ctx, EXPR_TYPEOF, $2); } | tINC UnaryExpression { $$ = new_unary_expression(ctx, EXPR_PREINC, $2); } | tDEC UnaryExpression { $$ = new_unary_expression(ctx, EXPR_PREDEC, $2); } | '+' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_PLUS, $2); } | '-' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_MINUS, $2); } | '~' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_BITNEG, $2); } | '!' UnaryExpression { $$ = new_unary_expression(ctx, EXPR_LOGNEG, $2); }/* ECMA-262 3rd Edition 11.2 */PostfixExpression : LeftHandSideExpression { $$ = $1; } | LeftHandSideExpression /* NONL */ tINC { $$ = new_unary_expression(ctx, EXPR_POSTINC, $1); } | LeftHandSideExpression /* NONL */ tDEC { $$ = new_unary_expression(ctx, EXPR_POSTDEC, $1); }/* ECMA-262 3rd Edition 11.2 */LeftHandSideExpression : NewExpression { $$ = $1; } | CallExpression { $$ = $1; }/* ECMA-262 3rd Edition 11.2 */NewExpression : MemberExpression { $$ = $1; } | kNEW NewExpression { $$ = new_new_expression(ctx, $2, NULL); }/* ECMA-262 3rd Edition 11.2 */MemberExpression : PrimaryExpression { $$ = $1; } | FunctionExpression { $$ = $1; } | MemberExpression '[' Expression ']' { $$ = new_binary_expression(ctx, EXPR_ARRAY, $1, $3); } | MemberExpression '.' IdentifierName { $$ = new_member_expression(ctx, $1, $3); } | kNEW MemberExpression Arguments { $$ = new_new_expression(ctx, $2, $3); }/* ECMA-262 3rd Edition 11.2 */CallExpression : MemberExpression Arguments { $$ = new_call_expression(ctx, $1, $2); } | CallExpression Arguments { $$ = new_call_expression(ctx, $1, $2); } | CallExpression '[' Expression ']' { $$ = new_binary_expression(ctx, EXPR_ARRAY, $1, $3); } | CallExpression '.' IdentifierName { $$ = new_member_expression(ctx, $1, $3); }/* ECMA-262 3rd Edition 11.2 */Arguments : '(' ')' { $$ = NULL; } | '(' ArgumentList ')' { $$ = $2; }/* ECMA-262 3rd Edition 11.2 */ArgumentList : AssignmentExpression { $$ = new_argument_list(ctx, $1); } | ArgumentList ',' AssignmentExpression { $$ = argument_list_add(ctx, $1, $3); }/* ECMA-262 3rd Edition 11.1 */PrimaryExpression : kTHIS { $$ = new_expression(ctx, EXPR_THIS, 0); } | tIdentifier { $$ = new_identifier_expression(ctx, $1); } | Literal { $$ = new_literal_expression(ctx, $1); } | ArrayLiteral { $$ = $1; } | ObjectLiteral { $$ = $1; } | '(' Expression ')' { $$ = $2; }/* ECMA-262 3rd Edition 11.1.4 */ArrayLiteral : '[' ']' { $$ = new_array_literal_expression(ctx, NULL, 0); } | '[' Elision ']' { $$ = new_array_literal_expression(ctx, NULL, $2+1); } | '[' ElementList ']' { $$ = new_array_literal_expression(ctx, $2, 0); } | '[' ElementList ',' Elision_opt ']' { $$ = new_array_literal_expression(ctx, $2, $4+1); }/* ECMA-262 3rd Edition 11.1.4 */ElementList : Elision_opt AssignmentExpression { $$ = new_element_list(ctx, $1, $2); } | ElementList ',' Elision_opt AssignmentExpression { $$ = element_list_add(ctx, $1, $3, $4); }/* ECMA-262 3rd Edition 11.1.4 */Elision : ',' { $$ = 1; } | Elision ',' { $$ = $1 + 1; }/* ECMA-262 3rd Edition 11.1.4 */Elision_opt : /* empty */ { $$ = 0; } | Elision { $$ = $1; }/* ECMA-262 3rd Edition 11.1.5 */ObjectLiteral : '{' '}' { $$ = new_prop_and_value_expression(ctx, NULL); } | '{' PropertyNameAndValueList '}' { $$ = new_prop_and_value_expression(ctx, $2); } | '{' PropertyNameAndValueList ',' '}' { if(ctx->script->version < 2) { WARN("Trailing comma in object literal is illegal in legacy mode.\n"); YYABORT; } $$ = new_prop_and_value_expression(ctx, $2); }/* ECMA-262 3rd Edition 11.1.5 */PropertyNameAndValueList : PropertyDefinition { $$ = new_property_list(ctx, $1); } | PropertyNameAndValueList ',' PropertyDefinition { $$ = property_list_add(ctx, $1, $3); }/* ECMA-262 5.1 Edition 12.2.6 */PropertyDefinition : PropertyName ':' AssignmentExpression { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_VALUE, $1, $3); } | kGET PropertyName GetterSetterMethod { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_GETTER, $2, $3); } | kSET PropertyName GetterSetterMethod { $$ = new_property_definition(ctx, PROPERTY_DEFINITION_SETTER, $2, $3); }GetterSetterMethod : left_bracket FormalParameterList_opt right_bracket '{' FunctionBody '}' { $$ = new_function_expression(ctx, NULL, $2, $5, NULL, $1, $6-$1); }/* Ecma-262 3rd Edition 11.1.5 */PropertyName : IdentifierName { $$ = new_string_literal(ctx, compiler_alloc_string_len(ctx->compiler, $1, lstrlenW($1))); } | tStringLiteral { $$ = new_string_literal(ctx, $1); } | tNumericLiteral { $$ = $1; }/* ECMA-262 3rd Edition 7.6 */Identifier_opt : /* empty*/ { $$ = NULL; } | tIdentifier { $$ = $1; }/* ECMA-262 5.1 Edition 7.6 */IdentifierName : tIdentifier { $$ = $1; } | ReservedAsIdentifier { if(ctx->script->version < SCRIPTLANGUAGEVERSION_ES5) { WARN("%s keyword used as an identifier in legacy mode.\n", debugstr_w($1)); YYABORT; } $$ = $1; }ReservedAsIdentifier : kBREAK { $$ = $1; } | kCASE { $$ = $1; } | kCATCH { $$ = $1; } | kCONTINUE { $$ = $1; } | kDEFAULT { $$ = $1; } | kDELETE { $$ = $1; } | kDO { $$ = $1; } | kELSE { $$ = $1; } | kFALSE { $$ = $1; } | kFINALLY { $$ = $1; } | kFOR { $$ = $1; } | kFUNCTION { $$ = $1; } | kGET { $$ = $1; } | kIF { $$ = $1; } | kIN { $$ = $1; } | kINSTANCEOF { $$ = $1; } | kNEW { $$ = $1; } | kNULL { $$ = $1; } | kRETURN { $$ = $1; } | kSET { $$ = $1; } | kSWITCH { $$ = $1; } | kTHIS { $$ = $1; } | kTHROW { $$ = $1; } | kTRUE { $$ = $1; } | kTRY { $$ = $1; } | kTYPEOF { $$ = $1; } | kVAR { $$ = $1; } | kVOID { $$ = $1; } | kWHILE { $$ = $1; } | kWITH { $$ = $1; }/* ECMA-262 3rd Edition 7.8 */Literal : kNULL { $$ = new_null_literal(ctx); } | BooleanLiteral { $$ = $1; } | tNumericLiteral { $$ = $1; } | tStringLiteral { $$ = new_string_literal(ctx, $1); } | '/' { $$ = parse_regexp(ctx); if(!$$) YYABORT; } | kDIVEQ { $$ = parse_regexp(ctx); if(!$$) YYABORT; }/* ECMA-262 3rd Edition 7.8.2 */BooleanLiteral : kTRUE { $$ = new_boolean_literal(ctx, VARIANT_TRUE); } | kFALSE { $$ = new_boolean_literal(ctx, VARIANT_FALSE); } | tBooleanLiteral { $$ = $1; }semicolon_opt : ';' | error { if(!allow_auto_semicolon(ctx)) {YYABORT;} }left_bracket : '(' { $$ = ctx->ptr; } | error { set_error(ctx, JS_E_MISSING_LBRACKET); YYABORT; }right_bracket : ')' | error { set_error(ctx, JS_E_MISSING_RBRACKET); YYABORT; }semicolon : ';' | error { set_error(ctx, JS_E_MISSING_SEMICOLON); YYABORT; }%%static BOOL allow_auto_semicolon(parser_ctx_t *ctx){ return ctx->nl || ctx->ptr == ctx->end || *(ctx->ptr-1) == '}';}static void *new_statement(parser_ctx_t *ctx, statement_type_t type, size_t size){ statement_t *stat; stat = parser_alloc(ctx, size ? size : sizeof(*stat)); if(!stat) return NULL; stat->type = type; stat->next = NULL; return stat;}static literal_t *new_string_literal(parser_ctx_t *ctx, jsstr_t *str){ literal_t *ret = parser_alloc(ctx, sizeof(literal_t)); ret->type = LT_STRING; ret->u.str = str; return ret;}static literal_t *new_null_literal(parser_ctx_t *ctx){ literal_t *ret = parser_alloc(ctx, sizeof(literal_t)); ret->type = LT_NULL; return ret;}static property_definition_t *new_property_definition(parser_ctx_t *ctx, property_definition_type_t type, literal_t *name, expression_t *value){ property_definition_t *ret = parser_alloc(ctx, sizeof(property_definition_t)); ret->type = type; ret->name = name; ret->value = value; ret->next = NULL; return ret;}static property_list_t *new_property_list(parser_ctx_t *ctx, property_definition_t *prop){ property_list_t *ret = parser_alloc_tmp(ctx, sizeof(property_list_t)); ret->head = ret->tail = prop; return ret;}static property_list_t *property_list_add(parser_ctx_t *ctx, property_list_t *list, property_definition_t *prop){ list->tail = list->tail->next = prop; return list;}static array_element_t *new_array_element(parser_ctx_t *ctx, int elision, expression_t *expr){ array_element_t *ret = parser_alloc(ctx, sizeof(array_element_t)); ret->elision = elision; ret->expr = expr; ret->next = NULL; return ret;}static element_list_t *new_element_list(parser_ctx_t *ctx, int elision, expression_t *expr){ element_list_t *ret = parser_alloc_tmp(ctx, sizeof(element_list_t)); ret->head = ret->tail = new_array_element(ctx, elision, expr); return ret;}static element_list_t *element_list_add(parser_ctx_t *ctx, element_list_t *list, int elision, expression_t *expr){ list->tail = list->tail->next = new_array_element(ctx, elision, expr); return list;}static argument_t *new_argument(parser_ctx_t *ctx, expression_t *expr){ argument_t *ret = parser_alloc(ctx, sizeof(argument_t)); ret->expr = expr; ret->next = NULL; return ret;}static argument_list_t *new_argument_list(parser_ctx_t *ctx, expression_t *expr){ argument_list_t *ret = parser_alloc_tmp(ctx, sizeof(argument_list_t)); ret->head = ret->tail = new_argument(ctx, expr); return ret;}static argument_list_t *argument_list_add(parser_ctx_t *ctx, argument_list_t *list, expression_t *expr){ list->tail = list->tail->next = new_argument(ctx, expr); return list;}static catch_block_t *new_catch_block(parser_ctx_t *ctx, const WCHAR *identifier, statement_t *statement){ catch_block_t *ret = parser_alloc(ctx, sizeof(catch_block_t)); ret->identifier = identifier; ret->statement = statement; return ret;}static case_clausule_t *new_case_clausule(parser_ctx_t *ctx, expression_t *expr, statement_list_t *stat_list){ case_clausule_t *ret = parser_alloc(ctx, sizeof(case_clausule_t)); ret->expr = expr; ret->stat = stat_list ? stat_list->head : NULL; ret->next = NULL; return ret;}static case_list_t *new_case_list(parser_ctx_t *ctx, case_clausule_t *case_clausule){ case_list_t *ret = parser_alloc_tmp(ctx, sizeof(case_list_t)); ret->head = ret->tail = case_clausule; return ret;}static case_list_t *case_list_add(parser_ctx_t *ctx, case_list_t *list, case_clausule_t *case_clausule){ list->tail = list->tail->next = case_clausule; return list;}static case_clausule_t *new_case_block(parser_ctx_t *ctx, case_list_t *case_list1, case_clausule_t *default_clausule, case_list_t *case_list2){ case_clausule_t *ret = NULL, *iter = NULL, *iter2; statement_t *stat = NULL; if(case_list1) { ret = case_list1->head; iter = case_list1->tail; } if(default_clausule) { if(ret) iter = iter->next = default_clausule; else ret = iter = default_clausule; } if(case_list2) { if(ret) iter->next = case_list2->head; else ret = case_list2->head; } if(!ret) return NULL; for(iter = ret; iter; iter = iter->next) { for(iter2 = iter; iter2 && !iter2->stat; iter2 = iter2->next); if(!iter2) break; while(iter != iter2) { iter->stat = iter2->stat; iter = iter->next; } if(stat) { while(stat->next) stat = stat->next; stat->next = iter->stat; }else { stat = iter->stat; } } return ret;}static statement_t *new_block_statement(parser_ctx_t *ctx, statement_list_t *list){ block_statement_t *ret; ret = new_statement(ctx, STAT_BLOCK, sizeof(*ret)); if(!ret) return NULL; ret->stat_list = list ? list->head : NULL; return &ret->stat;}static variable_declaration_t *new_variable_declaration(parser_ctx_t *ctx, const WCHAR *identifier, expression_t *expr){ variable_declaration_t *ret = parser_alloc(ctx, sizeof(variable_declaration_t)); ret->identifier = identifier; ret->expr = expr; ret->next = NULL; ret->global_next = NULL; return ret;}static variable_list_t *new_variable_list(parser_ctx_t *ctx, variable_declaration_t *decl){ variable_list_t *ret = parser_alloc_tmp(ctx, sizeof(variable_list_t)); ret->head = ret->tail = decl; return ret;}static variable_list_t *variable_list_add(parser_ctx_t *ctx, variable_list_t *list, variable_declaration_t *decl){ list->tail = list->tail->next = decl; return list;}static statement_t *new_var_statement(parser_ctx_t *ctx, variable_list_t *variable_list){ var_statement_t *ret; ret = new_statement(ctx, STAT_VAR, sizeof(*ret)); if(!ret) return NULL; ret->variable_list = variable_list->head; return &ret->stat;}static statement_t *new_expression_statement(parser_ctx_t *ctx, expression_t *expr){ expression_statement_t *ret; ret = new_statement(ctx, STAT_EXPR, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; return &ret->stat;}static statement_t *new_if_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *if_stat, statement_t *else_stat){ if_statement_t *ret; ret = new_statement(ctx, STAT_IF, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; ret->if_stat = if_stat; ret->else_stat = else_stat; return &ret->stat;}static statement_t *new_while_statement(parser_ctx_t *ctx, BOOL dowhile, expression_t *expr, statement_t *stat){ while_statement_t *ret; ret = new_statement(ctx, STAT_WHILE, sizeof(*ret)); if(!ret) return NULL; ret->do_while = dowhile; ret->expr = expr; ret->statement = stat; return &ret->stat;}static statement_t *new_for_statement(parser_ctx_t *ctx, variable_list_t *variable_list, expression_t *begin_expr, expression_t *expr, expression_t *end_expr, statement_t *statement){ for_statement_t *ret; ret = new_statement(ctx, STAT_FOR, sizeof(*ret)); if(!ret) return NULL; ret->variable_list = variable_list ? variable_list->head : NULL; ret->begin_expr = begin_expr; ret->expr = expr; ret->end_expr = end_expr; ret->statement = statement; return &ret->stat;}static statement_t *new_forin_statement(parser_ctx_t *ctx, variable_declaration_t *variable, expression_t *expr, expression_t *in_expr, statement_t *statement){ forin_statement_t *ret; ret = new_statement(ctx, STAT_FORIN, sizeof(*ret)); if(!ret) return NULL; ret->variable = variable; ret->expr = expr; ret->in_expr = in_expr; ret->statement = statement; return &ret->stat;}static statement_t *new_continue_statement(parser_ctx_t *ctx, const WCHAR *identifier){ branch_statement_t *ret; ret = new_statement(ctx, STAT_CONTINUE, sizeof(*ret)); if(!ret) return NULL; ret->identifier = identifier; return &ret->stat;}static statement_t *new_break_statement(parser_ctx_t *ctx, const WCHAR *identifier){ branch_statement_t *ret; ret = new_statement(ctx, STAT_BREAK, sizeof(*ret)); if(!ret) return NULL; ret->identifier = identifier; return &ret->stat;}static statement_t *new_return_statement(parser_ctx_t *ctx, expression_t *expr){ expression_statement_t *ret; ret = new_statement(ctx, STAT_RETURN, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; return &ret->stat;}static statement_t *new_with_statement(parser_ctx_t *ctx, expression_t *expr, statement_t *statement){ with_statement_t *ret; ret = new_statement(ctx, STAT_WITH, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; ret->statement = statement; return &ret->stat;}static statement_t *new_labelled_statement(parser_ctx_t *ctx, const WCHAR *identifier, statement_t *statement){ labelled_statement_t *ret; ret = new_statement(ctx, STAT_LABEL, sizeof(*ret)); if(!ret) return NULL; ret->identifier = identifier; ret->statement = statement; return &ret->stat;}static statement_t *new_switch_statement(parser_ctx_t *ctx, expression_t *expr, case_clausule_t *case_list){ switch_statement_t *ret; ret = new_statement(ctx, STAT_SWITCH, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; ret->case_list = case_list; return &ret->stat;}static statement_t *new_throw_statement(parser_ctx_t *ctx, expression_t *expr){ expression_statement_t *ret; ret = new_statement(ctx, STAT_THROW, sizeof(*ret)); if(!ret) return NULL; ret->expr = expr; return &ret->stat;}static statement_t *new_try_statement(parser_ctx_t *ctx, statement_t *try_statement, catch_block_t *catch_block, statement_t *finally_statement){ try_statement_t *ret; ret = new_statement(ctx, STAT_TRY, sizeof(*ret)); if(!ret) return NULL; ret->try_statement = try_statement; ret->catch_block = catch_block; ret->finally_statement = finally_statement; return &ret->stat;}static parameter_t *new_parameter(parser_ctx_t *ctx, const WCHAR *identifier){ parameter_t *ret = parser_alloc(ctx, sizeof(parameter_t)); ret->identifier = identifier; ret->next = NULL; return ret;}static parameter_list_t *new_parameter_list(parser_ctx_t *ctx, const WCHAR *identifier){ parameter_list_t *ret = parser_alloc_tmp(ctx, sizeof(parameter_list_t)); ret->head = ret->tail = new_parameter(ctx, identifier); return ret;}static parameter_list_t *parameter_list_add(parser_ctx_t *ctx, parameter_list_t *list, const WCHAR *identifier){ list->tail = list->tail->next = new_parameter(ctx, identifier); return list;}static expression_t *new_function_expression(parser_ctx_t *ctx, const WCHAR *identifier, parameter_list_t *parameter_list, source_elements_t *source_elements, const WCHAR *event_target, const WCHAR *src_str, DWORD src_len){ function_expression_t *ret = new_expression(ctx, EXPR_FUNC, sizeof(*ret)); ret->identifier = identifier; ret->parameter_list = parameter_list ? parameter_list->head : NULL; ret->source_elements = source_elements; ret->event_target = event_target; ret->src_str = src_str; ret->src_len = src_len; ret->next = NULL; return &ret->expr;}static void *new_expression(parser_ctx_t *ctx, expression_type_t type, size_t size){ expression_t *ret = parser_alloc(ctx, size ? size : sizeof(*ret)); ret->type = type; return ret;}static expression_t *new_binary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *expression1, expression_t *expression2){ binary_expression_t *ret = new_expression(ctx, type, sizeof(*ret)); ret->expression1 = expression1; ret->expression2 = expression2; return &ret->expr;}static expression_t *new_unary_expression(parser_ctx_t *ctx, expression_type_t type, expression_t *expression){ unary_expression_t *ret = new_expression(ctx, type, sizeof(*ret)); ret->expression = expression; return &ret->expr;}static expression_t *new_conditional_expression(parser_ctx_t *ctx, expression_t *expression, expression_t *true_expression, expression_t *false_expression){ conditional_expression_t *ret = new_expression(ctx, EXPR_COND, sizeof(*ret)); ret->expression = expression; ret->true_expression = true_expression; ret->false_expression = false_expression; return &ret->expr;}static expression_t *new_member_expression(parser_ctx_t *ctx, expression_t *expression, const WCHAR *identifier){ member_expression_t *ret = new_expression(ctx, EXPR_MEMBER, sizeof(*ret)); ret->expression = expression; ret->identifier = identifier; return &ret->expr;}static expression_t *new_new_expression(parser_ctx_t *ctx, expression_t *expression, argument_list_t *argument_list){ call_expression_t *ret = new_expression(ctx, EXPR_NEW, sizeof(*ret)); ret->expression = expression; ret->argument_list = argument_list ? argument_list->head : NULL; return &ret->expr;}static expression_t *new_call_expression(parser_ctx_t *ctx, expression_t *expression, argument_list_t *argument_list){ call_expression_t *ret = new_expression(ctx, EXPR_CALL, sizeof(*ret)); ret->expression = expression; ret->argument_list = argument_list ? argument_list->head : NULL; return &ret->expr;}static int parser_error(parser_ctx_t *ctx, const char *str){ return 0;}static void set_error(parser_ctx_t *ctx, UINT error){ ctx->hres = error;}static BOOL explicit_error(parser_ctx_t *ctx, void *obj, WCHAR next){ if(obj || *(ctx->ptr-1)==next) return TRUE; set_error(ctx, JS_E_SYNTAX); return FALSE;}static expression_t *new_identifier_expression(parser_ctx_t *ctx, const WCHAR *identifier){ identifier_expression_t *ret = new_expression(ctx, EXPR_IDENT, sizeof(*ret)); ret->identifier = identifier; return &ret->expr;}static expression_t *new_array_literal_expression(parser_ctx_t *ctx, element_list_t *element_list, int length){ array_literal_expression_t *ret = new_expression(ctx, EXPR_ARRAYLIT, sizeof(*ret)); ret->element_list = element_list ? element_list->head : NULL; ret->length = length; return &ret->expr;}static expression_t *new_prop_and_value_expression(parser_ctx_t *ctx, property_list_t *property_list){ property_value_expression_t *ret = new_expression(ctx, EXPR_PROPVAL, sizeof(*ret)); ret->property_list = property_list ? property_list->head : NULL; return &ret->expr;}static expression_t *new_literal_expression(parser_ctx_t *ctx, literal_t *literal){ literal_expression_t *ret = new_expression(ctx, EXPR_LITERAL, sizeof(*ret)); ret->literal = literal; return &ret->expr;}static source_elements_t *new_source_elements(parser_ctx_t *ctx){ source_elements_t *ret = parser_alloc(ctx, sizeof(source_elements_t)); memset(ret, 0, sizeof(*ret)); return ret;}static source_elements_t *source_elements_add_statement(source_elements_t *source_elements, statement_t *statement){ if(source_elements->statement_tail) source_elements->statement_tail = source_elements->statement_tail->next = statement; else source_elements->statement = source_elements->statement_tail = statement; return source_elements;}static statement_list_t *new_statement_list(parser_ctx_t *ctx, statement_t *statement){ statement_list_t *ret = parser_alloc_tmp(ctx, sizeof(statement_list_t)); ret->head = ret->tail = statement; return ret;}static statement_list_t *statement_list_add(statement_list_t *list, statement_t *statement){ list->tail = list->tail->next = statement; return list;}static void program_parsed(parser_ctx_t *ctx, source_elements_t *source){ ctx->source = source; if(!ctx->lexer_error) ctx->hres = S_OK;}void parser_release(parser_ctx_t *ctx){ script_release(ctx->script); heap_pool_free(&ctx->heap); heap_free(ctx);}HRESULT script_parse(script_ctx_t *ctx, struct _compiler_ctx_t *compiler, const WCHAR *code, const WCHAR *delimiter, BOOL from_eval, parser_ctx_t **ret){ parser_ctx_t *parser_ctx; heap_pool_t *mark; HRESULT hres; const WCHAR html_tagW[] = {'<','/','s','c','r','i','p','t','>',0}; parser_ctx = heap_alloc_zero(sizeof(parser_ctx_t)); if(!parser_ctx) return E_OUTOFMEMORY; parser_ctx->hres = JS_E_SYNTAX; parser_ctx->is_html = delimiter && !wcsicmp(delimiter, html_tagW); parser_ctx->begin = parser_ctx->ptr = code; parser_ctx->end = parser_ctx->begin + lstrlenW(parser_ctx->begin); script_addref(ctx); parser_ctx->script = ctx; mark = heap_pool_mark(&ctx->tmp_heap); heap_pool_init(&parser_ctx->heap); parser_ctx->compiler = compiler; parser_parse(parser_ctx); parser_ctx->compiler = NULL; heap_pool_clear(mark); hres = parser_ctx->hres; if(FAILED(hres)) { WARN("parser failed around %s\n", debugstr_w(parser_ctx->begin+20 > parser_ctx->ptr ? parser_ctx->begin : parser_ctx->ptr-20)); parser_release(parser_ctx); return hres; } *ret = parser_ctx; return S_OK;}