--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/JavaScriptCore/kjs/grammar.y Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,1016 @@
+%{
+
+/*
+ * This file is part of the KDE libraries
+ * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
+ * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
+ *
+ * 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 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 Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include "value.h"
+#include "object.h"
+#include "types.h"
+#include "interpreter.h"
+#include "nodes.h"
+#include "lexer.h"
+#include "internal.h"
+#include "CommonIdentifiers.h"
+
+// Not sure why, but yacc doesn't add this define along with the others.
+#define yylloc kjsyylloc
+
+#define YYMAXDEPTH 10000
+#define YYENABLE_NLS 0
+
+/* default values for bison */
+#define YYDEBUG 0
+#if !PLATFORM(DARWIN)
+ // avoid triggering warnings in older bison
+#define YYERROR_VERBOSE
+#endif
+
+extern int kjsyylex();
+int kjsyyerror(const char *);
+static bool allowAutomaticSemicolon();
+
+#define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon()) YYABORT; } while (0)
+#define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line)
+
+using namespace KJS;
+
+static Node* makeAssignNode(Node* loc, Operator, Node* expr);
+static Node* makePrefixNode(Node* expr, Operator);
+static Node* makePostfixNode(Node* expr, Operator);
+static bool makeGetterOrSetterPropertyNode(PropertyNode*& result, Identifier &getOrSet, Identifier& name, ParameterNode *params, FunctionBodyNode *body);
+static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args);
+static Node *makeTypeOfNode(Node *expr);
+static Node *makeDeleteNode(Node *expr);
+
+#if COMPILER(MSVC)
+
+#pragma warning(disable: 4065)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4702)
+
+// At least some of the time, the declarations of malloc and free that bison
+// generates are causing warnings. A way to avoid this is to explicitly define
+// the macros so that bison doesn't try to declare malloc and free.
+#define YYMALLOC malloc
+#define YYFREE free
+
+#endif
+
+%}
+
+%union {
+ int ival;
+ double dval;
+ UString *ustr;
+ Identifier *ident;
+ Node *node;
+ StatementNode *stat;
+ ParameterNode *param;
+ FunctionBodyNode *body;
+ FuncDeclNode *func;
+ FuncExprNode *funcExpr;
+ ProgramNode *prog;
+ AssignExprNode *init;
+ SourceElementsNode *srcs;
+ ArgumentsNode *args;
+ ArgumentListNode *alist;
+ VarDeclNode *decl;
+ VarDeclListNode *vlist;
+ CaseBlockNode *cblk;
+ ClauseListNode *clist;
+ CaseClauseNode *ccl;
+ ElementNode *elm;
+ Operator op;
+ PropertyListNode *plist;
+ PropertyNode *pnode;
+ PropertyNameNode *pname;
+}
+
+%start Program
+
+/* literals */
+%token NULLTOKEN TRUETOKEN FALSETOKEN
+
+/* keywords */
+%token BREAK CASE DEFAULT FOR NEW VAR CONSTTOKEN CONTINUE
+%token FUNCTION RETURN VOIDTOKEN DELETETOKEN
+%token IF THISTOKEN DO WHILE INTOKEN INSTANCEOF TYPEOF
+%token SWITCH WITH RESERVED
+%token THROW TRY CATCH FINALLY
+%token DEBUGGER
+
+/* give an if without an else higher precedence than an else to resolve the ambiguity */
+%nonassoc IF_WITHOUT_ELSE
+%nonassoc ELSE
+
+/* punctuators */
+%token EQEQ NE /* == and != */
+%token STREQ STRNEQ /* === and !== */
+%token LE GE /* < and > */
+%token OR AND /* || and && */
+%token PLUSPLUS MINUSMINUS /* ++ and -- */
+%token LSHIFT /* << */
+%token RSHIFT URSHIFT /* >> and >>> */
+%token PLUSEQUAL MINUSEQUAL /* += and -= */
+%token MULTEQUAL DIVEQUAL /* *= and /= */
+%token LSHIFTEQUAL /* <<= */
+%token RSHIFTEQUAL URSHIFTEQUAL /* >>= and >>>= */
+%token ANDEQUAL MODEQUAL /* &= and %= */
+%token XOREQUAL OREQUAL /* ^= and |= */
+
+/* terminal types */
+%token <dval> NUMBER
+%token <ustr> STRING
+%token <ident> IDENT
+
+/* automatically inserted semicolon */
+%token AUTOPLUSPLUS AUTOMINUSMINUS
+
+/* non-terminal types */
+%type <node> Literal ArrayLiteral
+
+%type <node> PrimaryExpr PrimaryExprNoBrace
+%type <node> MemberExpr MemberExprNoBF /* BF => brace or function */
+%type <node> NewExpr NewExprNoBF
+%type <node> CallExpr CallExprNoBF
+%type <node> LeftHandSideExpr LeftHandSideExprNoBF
+%type <node> PostfixExpr PostfixExprNoBF
+%type <node> UnaryExpr UnaryExprNoBF UnaryExprCommon
+%type <node> MultiplicativeExpr MultiplicativeExprNoBF
+%type <node> AdditiveExpr AdditiveExprNoBF
+%type <node> ShiftExpr ShiftExprNoBF
+%type <node> RelationalExpr RelationalExprNoIn RelationalExprNoBF
+%type <node> EqualityExpr EqualityExprNoIn EqualityExprNoBF
+%type <node> BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
+%type <node> BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
+%type <node> BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
+%type <node> LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
+%type <node> LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
+%type <node> ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
+%type <node> AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
+%type <node> Expr ExprNoIn ExprNoBF
+
+%type <node> ExprOpt ExprNoInOpt
+
+%type <stat> Statement Block
+%type <stat> VariableStatement ConstStatement EmptyStatement ExprStatement
+%type <stat> IfStatement IterationStatement ContinueStatement
+%type <stat> BreakStatement ReturnStatement WithStatement
+%type <stat> SwitchStatement LabelledStatement
+%type <stat> ThrowStatement TryStatement
+%type <stat> DebuggerStatement
+%type <stat> SourceElement
+
+%type <init> Initializer InitializerNoIn
+%type <func> FunctionDeclaration
+%type <funcExpr> FunctionExpr
+%type <body> FunctionBody
+%type <srcs> SourceElements
+%type <param> FormalParameterList
+%type <op> AssignmentOperator
+%type <args> Arguments
+%type <alist> ArgumentList
+%type <vlist> VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
+%type <decl> VariableDeclaration VariableDeclarationNoIn ConstDeclaration
+%type <cblk> CaseBlock
+%type <ccl> CaseClause DefaultClause
+%type <clist> CaseClauses CaseClausesOpt
+%type <ival> Elision ElisionOpt
+%type <elm> ElementList
+%type <pname> PropertyName
+%type <pnode> Property
+%type <plist> PropertyList
+%%
+
+Literal:
+ NULLTOKEN { $$ = new NullNode(); }
+ | TRUETOKEN { $$ = new BooleanNode(true); }
+ | FALSETOKEN { $$ = new BooleanNode(false); }
+ | NUMBER { $$ = new NumberNode($1); }
+ | STRING { $$ = new StringNode($1); }
+ | '/' /* regexp */ {
+ Lexer *l = Lexer::curr();
+ if (!l->scanRegExp()) YYABORT;
+ $$ = new RegExpNode(l->pattern, l->flags);
+ }
+ | DIVEQUAL /* regexp with /= */ {
+ Lexer *l = Lexer::curr();
+ if (!l->scanRegExp()) YYABORT;
+ $$ = new RegExpNode("=" + l->pattern, l->flags);
+ }
+;
+
+PropertyName:
+ IDENT { $$ = new PropertyNameNode(*$1); }
+ | STRING { $$ = new PropertyNameNode(Identifier(*$1)); }
+ | NUMBER { $$ = new PropertyNameNode($1); }
+;
+
+Property:
+ PropertyName ':' AssignmentExpr { $$ = new PropertyNode($1, $3, PropertyNode::Constant); }
+ | IDENT IDENT '(' ')' FunctionBody { if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, 0, $5)) YYABORT; }
+ | IDENT IDENT '(' FormalParameterList ')' FunctionBody
+ { if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, $4, $6)) YYABORT; }
+;
+
+PropertyList:
+ Property { $$ = new PropertyListNode($1); }
+ | PropertyList ',' Property { $$ = new PropertyListNode($3, $1); }
+;
+
+PrimaryExpr:
+ PrimaryExprNoBrace
+ | '{' '}' { $$ = new ObjectLiteralNode(); }
+ | '{' PropertyList '}' { $$ = new ObjectLiteralNode($2); }
+ /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
+ | '{' PropertyList ',' '}' { $$ = new ObjectLiteralNode($2); }
+;
+
+PrimaryExprNoBrace:
+ THISTOKEN { $$ = new ThisNode(); }
+ | Literal
+ | ArrayLiteral
+ | IDENT { $$ = new ResolveNode(*$1); }
+ | '(' Expr ')' { $$ = ($2->isResolveNode() || $2->isGroupNode()) ?
+ $2 : new GroupNode($2); }
+;
+
+ArrayLiteral:
+ '[' ElisionOpt ']' { $$ = new ArrayNode($2); }
+ | '[' ElementList ']' { $$ = new ArrayNode($2); }
+ | '[' ElementList ',' ElisionOpt ']' { $$ = new ArrayNode($4, $2); }
+;
+
+ElementList:
+ ElisionOpt AssignmentExpr { $$ = new ElementNode($1, $2); }
+ | ElementList ',' ElisionOpt AssignmentExpr
+ { $$ = new ElementNode($1, $3, $4); }
+;
+
+ElisionOpt:
+ /* nothing */ { $$ = 0; }
+ | Elision
+;
+
+Elision:
+ ',' { $$ = 1; }
+ | Elision ',' { $$ = $1 + 1; }
+;
+
+MemberExpr:
+ PrimaryExpr
+ | FunctionExpr { $$ = $1; }
+ | MemberExpr '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); }
+ | MemberExpr '.' IDENT { $$ = new DotAccessorNode($1, *$3); }
+ | NEW MemberExpr Arguments { $$ = new NewExprNode($2, $3); }
+;
+
+MemberExprNoBF:
+ PrimaryExprNoBrace
+ | MemberExprNoBF '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); }
+ | MemberExprNoBF '.' IDENT { $$ = new DotAccessorNode($1, *$3); }
+ | NEW MemberExpr Arguments { $$ = new NewExprNode($2, $3); }
+;
+
+NewExpr:
+ MemberExpr
+ | NEW NewExpr { $$ = new NewExprNode($2); }
+;
+
+NewExprNoBF:
+ MemberExprNoBF
+ | NEW NewExpr { $$ = new NewExprNode($2); }
+;
+
+CallExpr:
+ MemberExpr Arguments { $$ = makeFunctionCallNode($1, $2); }
+ | CallExpr Arguments { $$ = makeFunctionCallNode($1, $2); }
+ | CallExpr '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); }
+ | CallExpr '.' IDENT { $$ = new DotAccessorNode($1, *$3); }
+;
+
+CallExprNoBF:
+ MemberExprNoBF Arguments { $$ = makeFunctionCallNode($1, $2); }
+ | CallExprNoBF Arguments { $$ = makeFunctionCallNode($1, $2); }
+ | CallExprNoBF '[' Expr ']' { $$ = new BracketAccessorNode($1, $3); }
+ | CallExprNoBF '.' IDENT { $$ = new DotAccessorNode($1, *$3); }
+;
+
+Arguments:
+ '(' ')' { $$ = new ArgumentsNode(); }
+ | '(' ArgumentList ')' { $$ = new ArgumentsNode($2); }
+;
+
+ArgumentList:
+ AssignmentExpr { $$ = new ArgumentListNode($1); }
+ | ArgumentList ',' AssignmentExpr { $$ = new ArgumentListNode($1, $3); }
+;
+
+LeftHandSideExpr:
+ NewExpr
+ | CallExpr
+;
+
+LeftHandSideExprNoBF:
+ NewExprNoBF
+ | CallExprNoBF
+;
+
+PostfixExpr:
+ LeftHandSideExpr
+ | LeftHandSideExpr PLUSPLUS { $$ = makePostfixNode($1, OpPlusPlus); }
+ | LeftHandSideExpr MINUSMINUS { $$ = makePostfixNode($1, OpMinusMinus); }
+;
+
+PostfixExprNoBF:
+ LeftHandSideExprNoBF
+ | LeftHandSideExprNoBF PLUSPLUS { $$ = makePostfixNode($1, OpPlusPlus); }
+ | LeftHandSideExprNoBF MINUSMINUS { $$ = makePostfixNode($1, OpMinusMinus); }
+;
+
+UnaryExprCommon:
+ DELETETOKEN UnaryExpr { $$ = makeDeleteNode($2); }
+ | VOIDTOKEN UnaryExpr { $$ = new VoidNode($2); }
+ | TYPEOF UnaryExpr { $$ = makeTypeOfNode($2); }
+ | PLUSPLUS UnaryExpr { $$ = makePrefixNode($2, OpPlusPlus); }
+ | AUTOPLUSPLUS UnaryExpr { $$ = makePrefixNode($2, OpPlusPlus); }
+ | MINUSMINUS UnaryExpr { $$ = makePrefixNode($2, OpMinusMinus); }
+ | AUTOMINUSMINUS UnaryExpr { $$ = makePrefixNode($2, OpMinusMinus); }
+ | '+' UnaryExpr { $$ = new UnaryPlusNode($2); }
+ | '-' UnaryExpr { $$ = new NegateNode($2); }
+ | '~' UnaryExpr { $$ = new BitwiseNotNode($2); }
+ | '!' UnaryExpr { $$ = new LogicalNotNode($2); }
+
+UnaryExpr:
+ PostfixExpr
+ | UnaryExprCommon
+;
+
+UnaryExprNoBF:
+ PostfixExprNoBF
+ | UnaryExprCommon
+;
+
+MultiplicativeExpr:
+ UnaryExpr
+ | MultiplicativeExpr '*' UnaryExpr { $$ = new MultNode($1, $3, '*'); }
+ | MultiplicativeExpr '/' UnaryExpr { $$ = new MultNode($1, $3, '/'); }
+ | MultiplicativeExpr '%' UnaryExpr { $$ = new MultNode($1, $3,'%'); }
+;
+
+MultiplicativeExprNoBF:
+ UnaryExprNoBF
+ | MultiplicativeExprNoBF '*' UnaryExpr
+ { $$ = new MultNode($1, $3, '*'); }
+ | MultiplicativeExprNoBF '/' UnaryExpr
+ { $$ = new MultNode($1, $3, '/'); }
+ | MultiplicativeExprNoBF '%' UnaryExpr
+ { $$ = new MultNode($1, $3,'%'); }
+;
+
+AdditiveExpr:
+ MultiplicativeExpr
+ | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3, '+'); }
+ | AdditiveExpr '-' MultiplicativeExpr { $$ = new AddNode($1, $3, '-'); }
+;
+
+AdditiveExprNoBF:
+ MultiplicativeExprNoBF
+ | AdditiveExprNoBF '+' MultiplicativeExpr
+ { $$ = new AddNode($1, $3, '+'); }
+ | AdditiveExprNoBF '-' MultiplicativeExpr
+ { $$ = new AddNode($1, $3, '-'); }
+;
+
+ShiftExpr:
+ AdditiveExpr
+ | ShiftExpr LSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpLShift, $3); }
+ | ShiftExpr RSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpRShift, $3); }
+ | ShiftExpr URSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpURShift, $3); }
+;
+
+ShiftExprNoBF:
+ AdditiveExprNoBF
+ | ShiftExprNoBF LSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpLShift, $3); }
+ | ShiftExprNoBF RSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpRShift, $3); }
+ | ShiftExprNoBF URSHIFT AdditiveExpr { $$ = new ShiftNode($1, OpURShift, $3); }
+;
+
+RelationalExpr:
+ ShiftExpr
+ | RelationalExpr '<' ShiftExpr { $$ = new RelationalNode($1, OpLess, $3); }
+ | RelationalExpr '>' ShiftExpr { $$ = new RelationalNode($1, OpGreater, $3); }
+ | RelationalExpr LE ShiftExpr { $$ = new RelationalNode($1, OpLessEq, $3); }
+ | RelationalExpr GE ShiftExpr { $$ = new RelationalNode($1, OpGreaterEq, $3); }
+ | RelationalExpr INSTANCEOF ShiftExpr { $$ = new RelationalNode($1, OpInstanceOf, $3); }
+ | RelationalExpr INTOKEN ShiftExpr { $$ = new RelationalNode($1, OpIn, $3); }
+;
+
+RelationalExprNoIn:
+ ShiftExpr
+ | RelationalExprNoIn '<' ShiftExpr { $$ = new RelationalNode($1, OpLess, $3); }
+ | RelationalExprNoIn '>' ShiftExpr { $$ = new RelationalNode($1, OpGreater, $3); }
+ | RelationalExprNoIn LE ShiftExpr { $$ = new RelationalNode($1, OpLessEq, $3); }
+ | RelationalExprNoIn GE ShiftExpr { $$ = new RelationalNode($1, OpGreaterEq, $3); }
+ | RelationalExprNoIn INSTANCEOF ShiftExpr
+ { $$ = new RelationalNode($1, OpInstanceOf, $3); }
+;
+
+RelationalExprNoBF:
+ ShiftExprNoBF
+ | RelationalExprNoBF '<' ShiftExpr { $$ = new RelationalNode($1, OpLess, $3); }
+ | RelationalExprNoBF '>' ShiftExpr { $$ = new RelationalNode($1, OpGreater, $3); }
+ | RelationalExprNoBF LE ShiftExpr { $$ = new RelationalNode($1, OpLessEq, $3); }
+ | RelationalExprNoBF GE ShiftExpr { $$ = new RelationalNode($1, OpGreaterEq, $3); }
+ | RelationalExprNoBF INSTANCEOF ShiftExpr
+ { $$ = new RelationalNode($1, OpInstanceOf, $3); }
+ | RelationalExprNoBF INTOKEN ShiftExpr { $$ = new RelationalNode($1, OpIn, $3); }
+;
+
+EqualityExpr:
+ RelationalExpr
+ | EqualityExpr EQEQ RelationalExpr { $$ = new EqualNode($1, OpEqEq, $3); }
+ | EqualityExpr NE RelationalExpr { $$ = new EqualNode($1, OpNotEq, $3); }
+ | EqualityExpr STREQ RelationalExpr { $$ = new EqualNode($1, OpStrEq, $3); }
+ | EqualityExpr STRNEQ RelationalExpr { $$ = new EqualNode($1, OpStrNEq, $3);}
+;
+
+EqualityExprNoIn:
+ RelationalExprNoIn
+ | EqualityExprNoIn EQEQ RelationalExprNoIn
+ { $$ = new EqualNode($1, OpEqEq, $3); }
+ | EqualityExprNoIn NE RelationalExprNoIn
+ { $$ = new EqualNode($1, OpNotEq, $3); }
+ | EqualityExprNoIn STREQ RelationalExprNoIn
+ { $$ = new EqualNode($1, OpStrEq, $3); }
+ | EqualityExprNoIn STRNEQ RelationalExprNoIn
+ { $$ = new EqualNode($1, OpStrNEq, $3);}
+;
+
+EqualityExprNoBF:
+ RelationalExprNoBF
+ | EqualityExprNoBF EQEQ RelationalExpr
+ { $$ = new EqualNode($1, OpEqEq, $3); }
+ | EqualityExprNoBF NE RelationalExpr { $$ = new EqualNode($1, OpNotEq, $3); }
+ | EqualityExprNoBF STREQ RelationalExpr
+ { $$ = new EqualNode($1, OpStrEq, $3); }
+ | EqualityExprNoBF STRNEQ RelationalExpr
+ { $$ = new EqualNode($1, OpStrNEq, $3);}
+;
+
+BitwiseANDExpr:
+ EqualityExpr
+ | BitwiseANDExpr '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
+;
+
+BitwiseANDExprNoIn:
+ EqualityExprNoIn
+ | BitwiseANDExprNoIn '&' EqualityExprNoIn
+ { $$ = new BitOperNode($1, OpBitAnd, $3); }
+;
+
+BitwiseANDExprNoBF:
+ EqualityExprNoBF
+ | BitwiseANDExprNoBF '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
+;
+
+BitwiseXORExpr:
+ BitwiseANDExpr
+ | BitwiseXORExpr '^' BitwiseANDExpr { $$ = new BitOperNode($1, OpBitXOr, $3); }
+;
+
+BitwiseXORExprNoIn:
+ BitwiseANDExprNoIn
+ | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
+ { $$ = new BitOperNode($1, OpBitXOr, $3); }
+;
+
+BitwiseXORExprNoBF:
+ BitwiseANDExprNoBF
+ | BitwiseXORExprNoBF '^' BitwiseANDExpr
+ { $$ = new BitOperNode($1, OpBitXOr, $3); }
+;
+
+BitwiseORExpr:
+ BitwiseXORExpr
+ | BitwiseORExpr '|' BitwiseXORExpr { $$ = new BitOperNode($1, OpBitOr, $3); }
+;
+
+BitwiseORExprNoIn:
+ BitwiseXORExprNoIn
+ | BitwiseORExprNoIn '|' BitwiseXORExprNoIn
+ { $$ = new BitOperNode($1, OpBitOr, $3); }
+;
+
+BitwiseORExprNoBF:
+ BitwiseXORExprNoBF
+ | BitwiseORExprNoBF '|' BitwiseXORExpr
+ { $$ = new BitOperNode($1, OpBitOr, $3); }
+;
+
+LogicalANDExpr:
+ BitwiseORExpr
+ | LogicalANDExpr AND BitwiseORExpr { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
+;
+
+LogicalANDExprNoIn:
+ BitwiseORExprNoIn
+ | LogicalANDExprNoIn AND BitwiseORExprNoIn
+ { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
+;
+
+LogicalANDExprNoBF:
+ BitwiseORExprNoBF
+ | LogicalANDExprNoBF AND BitwiseORExpr
+ { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
+;
+
+LogicalORExpr:
+ LogicalANDExpr
+ | LogicalORExpr OR LogicalANDExpr { $$ = new BinaryLogicalNode($1, OpOr, $3); }
+;
+
+LogicalORExprNoIn:
+ LogicalANDExprNoIn
+ | LogicalORExprNoIn OR LogicalANDExprNoIn
+ { $$ = new BinaryLogicalNode($1, OpOr, $3); }
+;
+
+LogicalORExprNoBF:
+ LogicalANDExprNoBF
+ | LogicalORExprNoBF OR LogicalANDExpr { $$ = new BinaryLogicalNode($1, OpOr, $3); }
+;
+
+ConditionalExpr:
+ LogicalORExpr
+ | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
+ { $$ = new ConditionalNode($1, $3, $5); }
+;
+
+ConditionalExprNoIn:
+ LogicalORExprNoIn
+ | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn
+ { $$ = new ConditionalNode($1, $3, $5); }
+;
+
+ConditionalExprNoBF:
+ LogicalORExprNoBF
+ | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr
+ { $$ = new ConditionalNode($1, $3, $5); }
+;
+
+AssignmentExpr:
+ ConditionalExpr
+ | LeftHandSideExpr AssignmentOperator AssignmentExpr
+ { $$ = makeAssignNode($1, $2, $3); }
+;
+
+AssignmentExprNoIn:
+ ConditionalExprNoIn
+ | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn
+ { $$ = makeAssignNode($1, $2, $3); }
+;
+
+AssignmentExprNoBF:
+ ConditionalExprNoBF
+ | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr
+ { $$ = makeAssignNode($1, $2, $3); }
+;
+
+AssignmentOperator:
+ '=' { $$ = OpEqual; }
+ | PLUSEQUAL { $$ = OpPlusEq; }
+ | MINUSEQUAL { $$ = OpMinusEq; }
+ | MULTEQUAL { $$ = OpMultEq; }
+ | DIVEQUAL { $$ = OpDivEq; }
+ | LSHIFTEQUAL { $$ = OpLShift; }
+ | RSHIFTEQUAL { $$ = OpRShift; }
+ | URSHIFTEQUAL { $$ = OpURShift; }
+ | ANDEQUAL { $$ = OpAndEq; }
+ | XOREQUAL { $$ = OpXOrEq; }
+ | OREQUAL { $$ = OpOrEq; }
+ | MODEQUAL { $$ = OpModEq; }
+;
+
+Expr:
+ AssignmentExpr
+ | Expr ',' AssignmentExpr { $$ = new CommaNode($1, $3); }
+;
+
+ExprNoIn:
+ AssignmentExprNoIn
+ | ExprNoIn ',' AssignmentExprNoIn { $$ = new CommaNode($1, $3); }
+;
+
+ExprNoBF:
+ AssignmentExprNoBF
+ | ExprNoBF ',' AssignmentExpr { $$ = new CommaNode($1, $3); }
+;
+
+Statement:
+ Block
+ | VariableStatement
+ | ConstStatement
+ | EmptyStatement
+ | ExprStatement
+ | IfStatement
+ | IterationStatement
+ | ContinueStatement
+ | BreakStatement
+ | ReturnStatement
+ | WithStatement
+ | SwitchStatement
+ | LabelledStatement
+ | ThrowStatement
+ | TryStatement
+ | DebuggerStatement
+;
+
+Block:
+ '{' '}' { $$ = new BlockNode(0); DBG($$, @2, @2); }
+ | '{' SourceElements '}' { $$ = new BlockNode($2); DBG($$, @3, @3); }
+;
+
+VariableStatement:
+ VAR VariableDeclarationList ';' { $$ = new VarStatementNode($2); DBG($$, @1, @3); }
+ | VAR VariableDeclarationList error { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+VariableDeclarationList:
+ VariableDeclaration { $$ = new VarDeclListNode($1); }
+ | VariableDeclarationList ',' VariableDeclaration
+ { $$ = new VarDeclListNode($1, $3); }
+;
+
+VariableDeclarationListNoIn:
+ VariableDeclarationNoIn { $$ = new VarDeclListNode($1); }
+ | VariableDeclarationListNoIn ',' VariableDeclarationNoIn
+ { $$ = new VarDeclListNode($1, $3); }
+;
+
+VariableDeclaration:
+ IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); }
+ | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); }
+;
+
+VariableDeclarationNoIn:
+ IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); }
+ | IDENT InitializerNoIn { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); }
+;
+
+ConstStatement:
+ CONSTTOKEN ConstDeclarationList ';' { $$ = new VarStatementNode($2); DBG($$, @1, @3); }
+ | CONSTTOKEN ConstDeclarationList error
+ { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+ConstDeclarationList:
+ ConstDeclaration { $$ = new VarDeclListNode($1); }
+ | ConstDeclarationList ',' ConstDeclaration
+ { $$ = new VarDeclListNode($1, $3); }
+;
+
+ConstDeclaration:
+ IDENT { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Constant); }
+ | IDENT Initializer { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Constant); }
+;
+
+Initializer:
+ '=' AssignmentExpr { $$ = new AssignExprNode($2); }
+;
+
+InitializerNoIn:
+ '=' AssignmentExprNoIn { $$ = new AssignExprNode($2); }
+;
+
+EmptyStatement:
+ ';' { $$ = new EmptyStatementNode(); }
+;
+
+ExprStatement:
+ ExprNoBF ';' { $$ = new ExprStatementNode($1); DBG($$, @1, @2); }
+ | ExprNoBF error { $$ = new ExprStatementNode($1); DBG($$, @1, @1); AUTO_SEMICOLON; }
+;
+
+IfStatement:
+ IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE
+ { $$ = new IfNode($3, $5, 0); DBG($$, @1, @4); }
+ | IF '(' Expr ')' Statement ELSE Statement
+ { $$ = new IfNode($3, $5, $7); DBG($$, @1, @4); }
+;
+
+IterationStatement:
+ DO Statement WHILE '(' Expr ')' ';' { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3);}
+ | DO Statement WHILE '(' Expr ')' { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3);}
+ | WHILE '(' Expr ')' Statement { $$ = new WhileNode($3, $5); DBG($$, @1, @4); }
+ | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement
+ { $$ = new ForNode($3, $5, $7, $9); DBG($$, @1, @8); }
+ | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement
+ { $$ = new ForNode($4, $6, $8, $10); DBG($$, @1, @9); }
+ | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement
+ {
+ Node *n = $3->nodeInsideAllParens();
+ if (!n->isLocation())
+ YYABORT;
+ $$ = new ForInNode(n, $5, $7);
+ DBG($$, @1, @6);
+ }
+ | FOR '(' VAR IDENT INTOKEN Expr ')' Statement
+ { $$ = new ForInNode(*$4, 0, $6, $8); DBG($$, @1, @7); }
+ | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement
+ { $$ = new ForInNode(*$4, $5, $7, $9); DBG($$, @1, @8); }
+;
+
+ExprOpt:
+ /* nothing */ { $$ = 0; }
+ | Expr
+;
+
+ExprNoInOpt:
+ /* nothing */ { $$ = 0; }
+ | ExprNoIn
+;
+
+ContinueStatement:
+ CONTINUE ';' { $$ = new ContinueNode(); DBG($$, @1, @2); }
+ | CONTINUE error { $$ = new ContinueNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
+ | CONTINUE IDENT ';' { $$ = new ContinueNode(*$2); DBG($$, @1, @3); }
+ | CONTINUE IDENT error { $$ = new ContinueNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+BreakStatement:
+ BREAK ';' { $$ = new BreakNode(); DBG($$, @1, @2); }
+ | BREAK error { $$ = new BreakNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
+ | BREAK IDENT ';' { $$ = new BreakNode(*$2); DBG($$, @1, @3); }
+ | BREAK IDENT error { $$ = new BreakNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+ReturnStatement:
+ RETURN ';' { $$ = new ReturnNode(0); DBG($$, @1, @2); }
+ | RETURN error { $$ = new ReturnNode(0); DBG($$, @1, @1); AUTO_SEMICOLON; }
+ | RETURN Expr ';' { $$ = new ReturnNode($2); DBG($$, @1, @3); }
+ | RETURN Expr error { $$ = new ReturnNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+WithStatement:
+ WITH '(' Expr ')' Statement { $$ = new WithNode($3, $5); DBG($$, @1, @4); }
+;
+
+SwitchStatement:
+ SWITCH '(' Expr ')' CaseBlock { $$ = new SwitchNode($3, $5); DBG($$, @1, @4); }
+;
+
+CaseBlock:
+ '{' CaseClausesOpt '}' { $$ = new CaseBlockNode($2, 0, 0); }
+ | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
+ { $$ = new CaseBlockNode($2, $3, $4); }
+;
+
+CaseClausesOpt:
+ /* nothing */ { $$ = 0; }
+ | CaseClauses
+;
+
+CaseClauses:
+ CaseClause { $$ = new ClauseListNode($1); }
+ | CaseClauses CaseClause { $$ = new ClauseListNode($1, $2); }
+;
+
+CaseClause:
+ CASE Expr ':' { $$ = new CaseClauseNode($2); }
+ | CASE Expr ':' SourceElements { $$ = new CaseClauseNode($2, $4); }
+;
+
+DefaultClause:
+ DEFAULT ':' { $$ = new CaseClauseNode(0); }
+ | DEFAULT ':' SourceElements { $$ = new CaseClauseNode(0, $3); }
+;
+
+LabelledStatement:
+ IDENT ':' Statement { $3->pushLabel(*$1); $$ = new LabelNode(*$1, $3); }
+;
+
+ThrowStatement:
+ THROW Expr ';' { $$ = new ThrowNode($2); DBG($$, @1, @3); }
+ | THROW Expr error { $$ = new ThrowNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
+;
+
+TryStatement:
+ TRY Block FINALLY Block { $$ = new TryNode($2, CommonIdentifiers::shared()->nullIdentifier, 0, $4); DBG($$, @1, @2); }
+ | TRY Block CATCH '(' IDENT ')' Block { $$ = new TryNode($2, *$5, $7, 0); DBG($$, @1, @2); }
+ | TRY Block CATCH '(' IDENT ')' Block FINALLY Block
+ { $$ = new TryNode($2, *$5, $7, $9); DBG($$, @1, @2); }
+;
+
+DebuggerStatement:
+ DEBUGGER ';' { $$ = new EmptyStatementNode(); DBG($$, @1, @2); }
+ | DEBUGGER error { $$ = new EmptyStatementNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
+;
+
+FunctionDeclaration:
+ FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncDeclNode(*$2, $5); }
+ | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
+ { $$ = new FuncDeclNode(*$2, $4, $6); }
+;
+
+FunctionExpr:
+ FUNCTION '(' ')' FunctionBody { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $4); }
+ | FUNCTION '(' FormalParameterList ')' FunctionBody
+ { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5, $3); }
+ | FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncExprNode(*$2, $5); }
+ | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
+ { $$ = new FuncExprNode(*$2, $6, $4); }
+;
+
+FormalParameterList:
+ IDENT { $$ = new ParameterNode(*$1); }
+ | FormalParameterList ',' IDENT { $$ = new ParameterNode($1, *$3); }
+;
+
+FunctionBody:
+ '{' '}' /* not in spec */ { $$ = new FunctionBodyNode(0); DBG($$, @1, @2); }
+ | '{' SourceElements '}' { $$ = new FunctionBodyNode($2); DBG($$, @1, @3); }
+;
+
+Program:
+ /* not in spec */ { Parser::accept(new ProgramNode(0)); }
+ | SourceElements { Parser::accept(new ProgramNode($1)); }
+;
+
+SourceElements:
+ SourceElement { $$ = new SourceElementsNode($1); }
+ | SourceElements SourceElement { $$ = new SourceElementsNode($1, $2); }
+;
+
+SourceElement:
+ FunctionDeclaration { $$ = $1; }
+ | Statement { $$ = $1; }
+;
+
+%%
+
+static Node* makeAssignNode(Node* loc, Operator op, Node* expr)
+{
+ Node *n = loc->nodeInsideAllParens();
+
+ if (!n->isLocation())
+ return new AssignErrorNode(loc, op, expr);
+
+ if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new AssignResolveNode(resolve->identifier(), op, expr);
+ }
+ if (n->isBracketAccessorNode()) {
+ BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
+ return new AssignBracketNode(bracket->base(), bracket->subscript(), op, expr);
+ }
+ assert(n->isDotAccessorNode());
+ DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
+ return new AssignDotNode(dot->base(), dot->identifier(), op, expr);
+}
+
+static Node* makePrefixNode(Node *expr, Operator op)
+{
+ Node *n = expr->nodeInsideAllParens();
+
+ if (!n->isLocation())
+ return new PrefixErrorNode(expr, op);
+
+ if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new PrefixResolveNode(resolve->identifier(), op);
+ }
+ if (n->isBracketAccessorNode()) {
+ BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
+ return new PrefixBracketNode(bracket->base(), bracket->subscript(), op);
+ }
+ assert(n->isDotAccessorNode());
+ DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
+ return new PrefixDotNode(dot->base(), dot->identifier(), op);
+}
+
+static Node* makePostfixNode(Node* expr, Operator op)
+{
+ Node *n = expr->nodeInsideAllParens();
+
+ if (!n->isLocation())
+ return new PostfixErrorNode(expr, op);
+
+ if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new PostfixResolveNode(resolve->identifier(), op);
+ }
+ if (n->isBracketAccessorNode()) {
+ BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
+ return new PostfixBracketNode(bracket->base(), bracket->subscript(), op);
+ }
+ assert(n->isDotAccessorNode());
+ DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
+ return new PostfixDotNode(dot->base(), dot->identifier(), op);
+}
+
+static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args)
+{
+ Node *n = func->nodeInsideAllParens();
+
+ if (!n->isLocation())
+ return new FunctionCallValueNode(func, args);
+ else if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new FunctionCallResolveNode(resolve->identifier(), args);
+ } else if (n->isBracketAccessorNode()) {
+ BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
+ if (n != func)
+ return new FunctionCallParenBracketNode(bracket->base(), bracket->subscript(), args);
+ else
+ return new FunctionCallBracketNode(bracket->base(), bracket->subscript(), args);
+ } else {
+ assert(n->isDotAccessorNode());
+ DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
+ if (n != func)
+ return new FunctionCallParenDotNode(dot->base(), dot->identifier(), args);
+ else
+ return new FunctionCallDotNode(dot->base(), dot->identifier(), args);
+ }
+}
+
+static Node *makeTypeOfNode(Node *expr)
+{
+ Node *n = expr->nodeInsideAllParens();
+
+ if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new TypeOfResolveNode(resolve->identifier());
+ } else
+ return new TypeOfValueNode(expr);
+}
+
+static Node *makeDeleteNode(Node *expr)
+{
+ Node *n = expr->nodeInsideAllParens();
+
+ if (!n->isLocation())
+ return new DeleteValueNode(expr);
+ else if (n->isResolveNode()) {
+ ResolveNode *resolve = static_cast<ResolveNode *>(n);
+ return new DeleteResolveNode(resolve->identifier());
+ } else if (n->isBracketAccessorNode()) {
+ BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
+ return new DeleteBracketNode(bracket->base(), bracket->subscript());
+ } else {
+ assert(n->isDotAccessorNode());
+ DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
+ return new DeleteDotNode(dot->base(), dot->identifier());
+ }
+}
+
+static bool makeGetterOrSetterPropertyNode(PropertyNode*& result, Identifier& getOrSet, Identifier& name, ParameterNode *params, FunctionBodyNode *body)
+{
+ PropertyNode::Type type;
+
+ if (getOrSet == "get")
+ type = PropertyNode::Getter;
+ else if (getOrSet == "set")
+ type = PropertyNode::Setter;
+ else
+ return false;
+
+ result = new PropertyNode(new PropertyNameNode(name),
+ new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, params), type);
+
+ return true;
+}
+
+/* called by yyparse on error */
+int yyerror(const char *)
+{
+ return 1;
+}
+
+/* may we automatically insert a semicolon ? */
+static bool allowAutomaticSemicolon()
+{
+ return yychar == '}' || yychar == 0 || Lexer::curr()->prevTerminator();
+}