JavaScriptCore:
[WebKit-https.git] / JavaScriptCore / kjs / grammar.y
1 %{
2
3 /*
4  *  This file is part of the KDE libraries
5  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
6  *  Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #include "config.h"
25
26 #include <string.h>
27 #include <stdlib.h>
28 #include "value.h"
29 #include "object.h"
30 #include "types.h"
31 #include "interpreter.h"
32 #include "nodes.h"
33 #include "lexer.h"
34 #include "internal.h"
35 #include "CommonIdentifiers.h"
36     
37 // Not sure why, but yacc doesn't add this define along with the others.
38 #define yylloc kjsyylloc
39
40 #define YYMAXDEPTH 10000
41 #define YYENABLE_NLS 0
42
43 /* default values for bison */
44 #define YYDEBUG 0
45 #if !PLATFORM(DARWIN)
46     // avoid triggering warnings in older bison
47 #define YYERROR_VERBOSE
48 #endif
49
50 extern int kjsyylex();
51 int kjsyyerror(const char *);
52 static bool allowAutomaticSemicolon();
53
54 #define AUTO_SEMICOLON do { if (!allowAutomaticSemicolon()) YYABORT; } while (0)
55 #define DBG(l, s, e) (l)->setLoc((s).first_line, (e).last_line)
56
57 using namespace KJS;
58
59 static Node* makeAssignNode(Node* loc, Operator, Node* expr);
60 static Node* makePrefixNode(Node* expr, Operator);
61 static Node* makePostfixNode(Node* expr, Operator);
62 static bool makeGetterOrSetterPropertyNode(PropertyNode*& result, Identifier &getOrSet, Identifier& name, ParameterNode *params, FunctionBodyNode *body);
63 static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args);
64 static Node *makeTypeOfNode(Node *expr);
65 static Node *makeDeleteNode(Node *expr);
66
67 #if COMPILER(MSVC)
68
69 #pragma warning(disable: 4065)
70 #pragma warning(disable: 4244)
71 #pragma warning(disable: 4702)
72
73 // At least some of the time, the declarations of malloc and free that bison
74 // generates are causing warnings. A way to avoid this is to explicitly define
75 // the macros so that bison doesn't try to declare malloc and free.
76 #define YYMALLOC malloc
77 #define YYFREE free
78
79 #endif
80
81 %}
82
83 %union {
84   int                 ival;
85   double              dval;
86   UString             *ustr;
87   Identifier          *ident;
88   Node                *node;
89   StatementNode       *stat;
90   ParameterNode       *param;
91   FunctionBodyNode    *body;
92   FuncDeclNode        *func;
93   FuncExprNode        *funcExpr;
94   ProgramNode         *prog;
95   AssignExprNode      *init;
96   SourceElementsNode  *srcs;
97   ArgumentsNode       *args;
98   ArgumentListNode    *alist;
99   VarDeclNode         *decl;
100   VarDeclListNode     *vlist;
101   CaseBlockNode       *cblk;
102   ClauseListNode      *clist;
103   CaseClauseNode      *ccl;
104   ElementNode         *elm;
105   Operator            op;
106   PropertyListNode   *plist;
107   PropertyNode       *pnode;
108   PropertyNameNode   *pname;
109 }
110
111 %start Program
112
113 /* literals */
114 %token NULLTOKEN TRUETOKEN FALSETOKEN
115
116 /* keywords */
117 %token BREAK CASE DEFAULT FOR NEW VAR CONSTTOKEN CONTINUE
118 %token FUNCTION RETURN VOIDTOKEN DELETETOKEN
119 %token IF THISTOKEN DO WHILE INTOKEN INSTANCEOF TYPEOF
120 %token SWITCH WITH RESERVED
121 %token THROW TRY CATCH FINALLY
122 %token DEBUGGER
123
124 /* give an if without an else higher precedence than an else to resolve the ambiguity */
125 %nonassoc IF_WITHOUT_ELSE
126 %nonassoc ELSE
127
128 /* punctuators */
129 %token EQEQ NE                     /* == and != */
130 %token STREQ STRNEQ                /* === and !== */
131 %token LE GE                       /* < and > */
132 %token OR AND                      /* || and && */
133 %token PLUSPLUS MINUSMINUS         /* ++ and --  */
134 %token LSHIFT                      /* << */
135 %token RSHIFT URSHIFT              /* >> and >>> */
136 %token PLUSEQUAL MINUSEQUAL        /* += and -= */
137 %token MULTEQUAL DIVEQUAL          /* *= and /= */
138 %token LSHIFTEQUAL                 /* <<= */
139 %token RSHIFTEQUAL URSHIFTEQUAL    /* >>= and >>>= */
140 %token ANDEQUAL MODEQUAL           /* &= and %= */
141 %token XOREQUAL OREQUAL            /* ^= and |= */
142
143 /* terminal types */
144 %token <dval> NUMBER
145 %token <ustr> STRING
146 %token <ident> IDENT
147
148 /* automatically inserted semicolon */
149 %token AUTOPLUSPLUS AUTOMINUSMINUS
150
151 /* non-terminal types */
152 %type <node>  Literal ArrayLiteral
153
154 %type <node>  PrimaryExpr PrimaryExprNoBrace
155 %type <node>  MemberExpr MemberExprNoBF /* BF => brace or function */
156 %type <node>  NewExpr NewExprNoBF
157 %type <node>  CallExpr CallExprNoBF
158 %type <node>  LeftHandSideExpr LeftHandSideExprNoBF
159 %type <node>  PostfixExpr PostfixExprNoBF
160 %type <node>  UnaryExpr UnaryExprNoBF UnaryExprCommon
161 %type <node>  MultiplicativeExpr MultiplicativeExprNoBF
162 %type <node>  AdditiveExpr AdditiveExprNoBF
163 %type <node>  ShiftExpr ShiftExprNoBF
164 %type <node>  RelationalExpr RelationalExprNoIn RelationalExprNoBF
165 %type <node>  EqualityExpr EqualityExprNoIn EqualityExprNoBF
166 %type <node>  BitwiseANDExpr BitwiseANDExprNoIn BitwiseANDExprNoBF
167 %type <node>  BitwiseXORExpr BitwiseXORExprNoIn BitwiseXORExprNoBF
168 %type <node>  BitwiseORExpr BitwiseORExprNoIn BitwiseORExprNoBF
169 %type <node>  LogicalANDExpr LogicalANDExprNoIn LogicalANDExprNoBF
170 %type <node>  LogicalORExpr LogicalORExprNoIn LogicalORExprNoBF
171 %type <node>  ConditionalExpr ConditionalExprNoIn ConditionalExprNoBF
172 %type <node>  AssignmentExpr AssignmentExprNoIn AssignmentExprNoBF
173 %type <node>  Expr ExprNoIn ExprNoBF
174
175 %type <node>  ExprOpt ExprNoInOpt
176
177 %type <stat>  Statement Block
178 %type <stat>  VariableStatement ConstStatement EmptyStatement ExprStatement
179 %type <stat>  IfStatement IterationStatement ContinueStatement
180 %type <stat>  BreakStatement ReturnStatement WithStatement
181 %type <stat>  SwitchStatement LabelledStatement
182 %type <stat>  ThrowStatement TryStatement
183 %type <stat>  DebuggerStatement
184 %type <stat>  SourceElement
185
186 %type <init>  Initializer InitializerNoIn
187 %type <func>  FunctionDeclaration
188 %type <funcExpr>  FunctionExpr
189 %type <body>  FunctionBody
190 %type <srcs>  SourceElements
191 %type <param> FormalParameterList
192 %type <op>    AssignmentOperator
193 %type <args>  Arguments
194 %type <alist> ArgumentList
195 %type <vlist> VariableDeclarationList VariableDeclarationListNoIn ConstDeclarationList
196 %type <decl>  VariableDeclaration VariableDeclarationNoIn ConstDeclaration
197 %type <cblk>  CaseBlock
198 %type <ccl>   CaseClause DefaultClause
199 %type <clist> CaseClauses  CaseClausesOpt
200 %type <ival>  Elision ElisionOpt
201 %type <elm>   ElementList
202 %type <pname> PropertyName
203 %type <pnode> Property
204 %type <plist> PropertyList
205 %%
206
207 Literal:
208     NULLTOKEN                           { $$ = new NullNode(); }
209   | TRUETOKEN                           { $$ = new BooleanNode(true); }
210   | FALSETOKEN                          { $$ = new BooleanNode(false); }
211   | NUMBER                              { $$ = new NumberNode($1); }
212   | STRING                              { $$ = new StringNode($1); }
213   | '/' /* regexp */                    {
214                                             Lexer *l = Lexer::curr();
215                                             if (!l->scanRegExp()) YYABORT;
216                                             $$ = new RegExpNode(l->pattern, l->flags);
217                                         }
218   | DIVEQUAL /* regexp with /= */       {
219                                             Lexer *l = Lexer::curr();
220                                             if (!l->scanRegExp()) YYABORT;
221                                             $$ = new RegExpNode("=" + l->pattern, l->flags);
222                                         }
223 ;
224
225 PropertyName:
226     IDENT                               { $$ = new PropertyNameNode(*$1); }
227   | STRING                              { $$ = new PropertyNameNode(Identifier(*$1)); }
228   | NUMBER                              { $$ = new PropertyNameNode($1); }
229 ;
230
231 Property:
232     PropertyName ':' AssignmentExpr     { $$ = new PropertyNode($1, $3, PropertyNode::Constant); }
233   | IDENT IDENT '(' ')' FunctionBody    { if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, 0, $5)) YYABORT; }
234   | IDENT IDENT '(' FormalParameterList ')' FunctionBody
235                                         { if (!makeGetterOrSetterPropertyNode($$, *$1, *$2, $4, $6)) YYABORT; }
236 ;
237
238 PropertyList:
239     Property                            { $$ = new PropertyListNode($1); }
240   | PropertyList ',' Property           { $$ = new PropertyListNode($3, $1); }
241 ;
242
243 PrimaryExpr:
244     PrimaryExprNoBrace
245   | '{' '}'                             { $$ = new ObjectLiteralNode(); }
246   | '{' PropertyList '}'                { $$ = new ObjectLiteralNode($2); }
247   /* allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939 */
248   | '{' PropertyList ',' '}'            { $$ = new ObjectLiteralNode($2); }
249 ;
250
251 PrimaryExprNoBrace:
252     THISTOKEN                           { $$ = new ThisNode(); }
253   | Literal
254   | ArrayLiteral
255   | IDENT                               { $$ = new ResolveNode(*$1); }
256   | '(' Expr ')'                        { $$ = ($2->isResolveNode() || $2->isGroupNode()) ?
257                                             $2 : new GroupNode($2); }
258 ;
259
260 ArrayLiteral:
261     '[' ElisionOpt ']'                  { $$ = new ArrayNode($2); }
262   | '[' ElementList ']'                 { $$ = new ArrayNode($2); }
263   | '[' ElementList ',' ElisionOpt ']'  { $$ = new ArrayNode($4, $2); }
264 ;
265
266 ElementList:
267     ElisionOpt AssignmentExpr           { $$ = new ElementNode($1, $2); }
268   | ElementList ',' ElisionOpt AssignmentExpr
269                                         { $$ = new ElementNode($1, $3, $4); }
270 ;
271
272 ElisionOpt:
273     /* nothing */                       { $$ = 0; }
274   | Elision
275 ;
276
277 Elision:
278     ','                                 { $$ = 1; }
279   | Elision ','                         { $$ = $1 + 1; }
280 ;
281
282 MemberExpr:
283     PrimaryExpr
284   | FunctionExpr                        { $$ = $1; }
285   | MemberExpr '[' Expr ']'             { $$ = new BracketAccessorNode($1, $3); }
286   | MemberExpr '.' IDENT                { $$ = new DotAccessorNode($1, *$3); }
287   | NEW MemberExpr Arguments            { $$ = new NewExprNode($2, $3); }
288 ;
289
290 MemberExprNoBF:
291     PrimaryExprNoBrace
292   | MemberExprNoBF '[' Expr ']'         { $$ = new BracketAccessorNode($1, $3); }
293   | MemberExprNoBF '.' IDENT            { $$ = new DotAccessorNode($1, *$3); }
294   | NEW MemberExpr Arguments            { $$ = new NewExprNode($2, $3); }
295 ;
296
297 NewExpr:
298     MemberExpr
299   | NEW NewExpr                         { $$ = new NewExprNode($2); }
300 ;
301
302 NewExprNoBF:
303     MemberExprNoBF
304   | NEW NewExpr                         { $$ = new NewExprNode($2); }
305 ;
306
307 CallExpr:
308     MemberExpr Arguments                { $$ = makeFunctionCallNode($1, $2); }
309   | CallExpr Arguments                  { $$ = makeFunctionCallNode($1, $2); }
310   | CallExpr '[' Expr ']'               { $$ = new BracketAccessorNode($1, $3); }
311   | CallExpr '.' IDENT                  { $$ = new DotAccessorNode($1, *$3); }
312 ;
313
314 CallExprNoBF:
315     MemberExprNoBF Arguments            { $$ = makeFunctionCallNode($1, $2); }
316   | CallExprNoBF Arguments              { $$ = makeFunctionCallNode($1, $2); }
317   | CallExprNoBF '[' Expr ']'           { $$ = new BracketAccessorNode($1, $3); }
318   | CallExprNoBF '.' IDENT              { $$ = new DotAccessorNode($1, *$3); }
319 ;
320
321 Arguments:
322     '(' ')'                             { $$ = new ArgumentsNode(); }
323   | '(' ArgumentList ')'                { $$ = new ArgumentsNode($2); }
324 ;
325
326 ArgumentList:
327     AssignmentExpr                      { $$ = new ArgumentListNode($1); }
328   | ArgumentList ',' AssignmentExpr     { $$ = new ArgumentListNode($1, $3); }
329 ;
330
331 LeftHandSideExpr:
332     NewExpr
333   | CallExpr
334 ;
335
336 LeftHandSideExprNoBF:
337     NewExprNoBF
338   | CallExprNoBF
339 ;
340
341 PostfixExpr:
342     LeftHandSideExpr
343   | LeftHandSideExpr PLUSPLUS           { $$ = makePostfixNode($1, OpPlusPlus); }
344   | LeftHandSideExpr MINUSMINUS         { $$ = makePostfixNode($1, OpMinusMinus); }
345 ;
346
347 PostfixExprNoBF:
348     LeftHandSideExprNoBF
349   | LeftHandSideExprNoBF PLUSPLUS       { $$ = makePostfixNode($1, OpPlusPlus); }
350   | LeftHandSideExprNoBF MINUSMINUS     { $$ = makePostfixNode($1, OpMinusMinus); }
351 ;
352
353 UnaryExprCommon:
354     DELETETOKEN UnaryExpr               { $$ = makeDeleteNode($2); }
355   | VOIDTOKEN UnaryExpr                 { $$ = new VoidNode($2); }
356   | TYPEOF UnaryExpr                    { $$ = makeTypeOfNode($2); }
357   | PLUSPLUS UnaryExpr                  { $$ = makePrefixNode($2, OpPlusPlus); }
358   | AUTOPLUSPLUS UnaryExpr              { $$ = makePrefixNode($2, OpPlusPlus); }
359   | MINUSMINUS UnaryExpr                { $$ = makePrefixNode($2, OpMinusMinus); }
360   | AUTOMINUSMINUS UnaryExpr            { $$ = makePrefixNode($2, OpMinusMinus); }
361   | '+' UnaryExpr                       { $$ = new UnaryPlusNode($2); }
362   | '-' UnaryExpr                       { $$ = new NegateNode($2); }
363   | '~' UnaryExpr                       { $$ = new BitwiseNotNode($2); }
364   | '!' UnaryExpr                       { $$ = new LogicalNotNode($2); }
365
366 UnaryExpr:
367     PostfixExpr
368   | UnaryExprCommon
369 ;
370
371 UnaryExprNoBF:
372     PostfixExprNoBF
373   | UnaryExprCommon
374 ;
375
376 MultiplicativeExpr:
377     UnaryExpr
378   | MultiplicativeExpr '*' UnaryExpr    { $$ = new MultNode($1, $3, '*'); }
379   | MultiplicativeExpr '/' UnaryExpr    { $$ = new MultNode($1, $3, '/'); }
380   | MultiplicativeExpr '%' UnaryExpr    { $$ = new MultNode($1, $3,'%'); }
381 ;
382
383 MultiplicativeExprNoBF:
384     UnaryExprNoBF
385   | MultiplicativeExprNoBF '*' UnaryExpr
386                                         { $$ = new MultNode($1, $3, '*'); }
387   | MultiplicativeExprNoBF '/' UnaryExpr
388                                         { $$ = new MultNode($1, $3, '/'); }
389   | MultiplicativeExprNoBF '%' UnaryExpr
390                                         { $$ = new MultNode($1, $3,'%'); }
391 ;
392
393 AdditiveExpr:
394     MultiplicativeExpr
395   | AdditiveExpr '+' MultiplicativeExpr { $$ = new AddNode($1, $3, '+'); }
396   | AdditiveExpr '-' MultiplicativeExpr { $$ = new AddNode($1, $3, '-'); }
397 ;
398
399 AdditiveExprNoBF:
400     MultiplicativeExprNoBF
401   | AdditiveExprNoBF '+' MultiplicativeExpr
402                                         { $$ = new AddNode($1, $3, '+'); }
403   | AdditiveExprNoBF '-' MultiplicativeExpr
404                                         { $$ = new AddNode($1, $3, '-'); }
405 ;
406
407 ShiftExpr:
408     AdditiveExpr
409   | ShiftExpr LSHIFT AdditiveExpr       { $$ = new ShiftNode($1, OpLShift, $3); }
410   | ShiftExpr RSHIFT AdditiveExpr       { $$ = new ShiftNode($1, OpRShift, $3); }
411   | ShiftExpr URSHIFT AdditiveExpr      { $$ = new ShiftNode($1, OpURShift, $3); }
412 ;
413
414 ShiftExprNoBF:
415     AdditiveExprNoBF
416   | ShiftExprNoBF LSHIFT AdditiveExpr   { $$ = new ShiftNode($1, OpLShift, $3); }
417   | ShiftExprNoBF RSHIFT AdditiveExpr   { $$ = new ShiftNode($1, OpRShift, $3); }
418   | ShiftExprNoBF URSHIFT AdditiveExpr  { $$ = new ShiftNode($1, OpURShift, $3); }
419 ;
420
421 RelationalExpr:
422     ShiftExpr
423   | RelationalExpr '<' ShiftExpr        { $$ = new RelationalNode($1, OpLess, $3); }
424   | RelationalExpr '>' ShiftExpr        { $$ = new RelationalNode($1, OpGreater, $3); }
425   | RelationalExpr LE ShiftExpr         { $$ = new RelationalNode($1, OpLessEq, $3); }
426   | RelationalExpr GE ShiftExpr         { $$ = new RelationalNode($1, OpGreaterEq, $3); }
427   | RelationalExpr INSTANCEOF ShiftExpr { $$ = new RelationalNode($1, OpInstanceOf, $3); }
428   | RelationalExpr INTOKEN ShiftExpr    { $$ = new RelationalNode($1, OpIn, $3); }
429 ;
430
431 RelationalExprNoIn:
432     ShiftExpr
433   | RelationalExprNoIn '<' ShiftExpr    { $$ = new RelationalNode($1, OpLess, $3); }
434   | RelationalExprNoIn '>' ShiftExpr    { $$ = new RelationalNode($1, OpGreater, $3); }
435   | RelationalExprNoIn LE ShiftExpr     { $$ = new RelationalNode($1, OpLessEq, $3); }
436   | RelationalExprNoIn GE ShiftExpr     { $$ = new RelationalNode($1, OpGreaterEq, $3); }
437   | RelationalExprNoIn INSTANCEOF ShiftExpr
438                                         { $$ = new RelationalNode($1, OpInstanceOf, $3); }
439 ;
440
441 RelationalExprNoBF:
442     ShiftExprNoBF
443   | RelationalExprNoBF '<' ShiftExpr    { $$ = new RelationalNode($1, OpLess, $3); }
444   | RelationalExprNoBF '>' ShiftExpr    { $$ = new RelationalNode($1, OpGreater, $3); }
445   | RelationalExprNoBF LE ShiftExpr     { $$ = new RelationalNode($1, OpLessEq, $3); }
446   | RelationalExprNoBF GE ShiftExpr     { $$ = new RelationalNode($1, OpGreaterEq, $3); }
447   | RelationalExprNoBF INSTANCEOF ShiftExpr
448                                         { $$ = new RelationalNode($1, OpInstanceOf, $3); }
449   | RelationalExprNoBF INTOKEN ShiftExpr     { $$ = new RelationalNode($1, OpIn, $3); }
450 ;
451
452 EqualityExpr:
453     RelationalExpr
454   | EqualityExpr EQEQ RelationalExpr    { $$ = new EqualNode($1, OpEqEq, $3); }
455   | EqualityExpr NE RelationalExpr      { $$ = new EqualNode($1, OpNotEq, $3); }
456   | EqualityExpr STREQ RelationalExpr   { $$ = new EqualNode($1, OpStrEq, $3); }
457   | EqualityExpr STRNEQ RelationalExpr  { $$ = new EqualNode($1, OpStrNEq, $3);}
458 ;
459
460 EqualityExprNoIn:
461     RelationalExprNoIn
462   | EqualityExprNoIn EQEQ RelationalExprNoIn
463                                         { $$ = new EqualNode($1, OpEqEq, $3); }
464   | EqualityExprNoIn NE RelationalExprNoIn
465                                         { $$ = new EqualNode($1, OpNotEq, $3); }
466   | EqualityExprNoIn STREQ RelationalExprNoIn
467                                         { $$ = new EqualNode($1, OpStrEq, $3); }
468   | EqualityExprNoIn STRNEQ RelationalExprNoIn
469                                         { $$ = new EqualNode($1, OpStrNEq, $3);}
470 ;
471
472 EqualityExprNoBF:
473     RelationalExprNoBF
474   | EqualityExprNoBF EQEQ RelationalExpr
475                                         { $$ = new EqualNode($1, OpEqEq, $3); }
476   | EqualityExprNoBF NE RelationalExpr  { $$ = new EqualNode($1, OpNotEq, $3); }
477   | EqualityExprNoBF STREQ RelationalExpr
478                                         { $$ = new EqualNode($1, OpStrEq, $3); }
479   | EqualityExprNoBF STRNEQ RelationalExpr
480                                         { $$ = new EqualNode($1, OpStrNEq, $3);}
481 ;
482
483 BitwiseANDExpr:
484     EqualityExpr
485   | BitwiseANDExpr '&' EqualityExpr     { $$ = new BitOperNode($1, OpBitAnd, $3); }
486 ;
487
488 BitwiseANDExprNoIn:
489     EqualityExprNoIn
490   | BitwiseANDExprNoIn '&' EqualityExprNoIn
491                                         { $$ = new BitOperNode($1, OpBitAnd, $3); }
492 ;
493
494 BitwiseANDExprNoBF:
495     EqualityExprNoBF
496   | BitwiseANDExprNoBF '&' EqualityExpr { $$ = new BitOperNode($1, OpBitAnd, $3); }
497 ;
498
499 BitwiseXORExpr:
500     BitwiseANDExpr
501   | BitwiseXORExpr '^' BitwiseANDExpr   { $$ = new BitOperNode($1, OpBitXOr, $3); }
502 ;
503
504 BitwiseXORExprNoIn:
505     BitwiseANDExprNoIn
506   | BitwiseXORExprNoIn '^' BitwiseANDExprNoIn
507                                         { $$ = new BitOperNode($1, OpBitXOr, $3); }
508 ;
509
510 BitwiseXORExprNoBF:
511     BitwiseANDExprNoBF
512   | BitwiseXORExprNoBF '^' BitwiseANDExpr
513                                         { $$ = new BitOperNode($1, OpBitXOr, $3); }
514 ;
515
516 BitwiseORExpr:
517     BitwiseXORExpr
518   | BitwiseORExpr '|' BitwiseXORExpr    { $$ = new BitOperNode($1, OpBitOr, $3); }
519 ;
520
521 BitwiseORExprNoIn:
522     BitwiseXORExprNoIn
523   | BitwiseORExprNoIn '|' BitwiseXORExprNoIn
524                                         { $$ = new BitOperNode($1, OpBitOr, $3); }
525 ;
526
527 BitwiseORExprNoBF:
528     BitwiseXORExprNoBF
529   | BitwiseORExprNoBF '|' BitwiseXORExpr
530                                         { $$ = new BitOperNode($1, OpBitOr, $3); }
531 ;
532
533 LogicalANDExpr:
534     BitwiseORExpr
535   | LogicalANDExpr AND BitwiseORExpr    { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
536 ;
537
538 LogicalANDExprNoIn:
539     BitwiseORExprNoIn
540   | LogicalANDExprNoIn AND BitwiseORExprNoIn
541                                         { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
542 ;
543
544 LogicalANDExprNoBF:
545     BitwiseORExprNoBF
546   | LogicalANDExprNoBF AND BitwiseORExpr
547                                         { $$ = new BinaryLogicalNode($1, OpAnd, $3); }
548 ;
549
550 LogicalORExpr:
551     LogicalANDExpr
552   | LogicalORExpr OR LogicalANDExpr     { $$ = new BinaryLogicalNode($1, OpOr, $3); }
553 ;
554
555 LogicalORExprNoIn:
556     LogicalANDExprNoIn
557   | LogicalORExprNoIn OR LogicalANDExprNoIn
558                                         { $$ = new BinaryLogicalNode($1, OpOr, $3); }
559 ;
560
561 LogicalORExprNoBF:
562     LogicalANDExprNoBF
563   | LogicalORExprNoBF OR LogicalANDExpr { $$ = new BinaryLogicalNode($1, OpOr, $3); }
564 ;
565
566 ConditionalExpr:
567     LogicalORExpr
568   | LogicalORExpr '?' AssignmentExpr ':' AssignmentExpr
569                                         { $$ = new ConditionalNode($1, $3, $5); }
570 ;
571
572 ConditionalExprNoIn:
573     LogicalORExprNoIn
574   | LogicalORExprNoIn '?' AssignmentExprNoIn ':' AssignmentExprNoIn
575                                         { $$ = new ConditionalNode($1, $3, $5); }
576 ;
577
578 ConditionalExprNoBF:
579     LogicalORExprNoBF
580   | LogicalORExprNoBF '?' AssignmentExpr ':' AssignmentExpr
581                                         { $$ = new ConditionalNode($1, $3, $5); }
582 ;
583
584 AssignmentExpr:
585     ConditionalExpr
586   | LeftHandSideExpr AssignmentOperator AssignmentExpr
587                                         { $$ = makeAssignNode($1, $2, $3); }
588 ;
589
590 AssignmentExprNoIn:
591     ConditionalExprNoIn
592   | LeftHandSideExpr AssignmentOperator AssignmentExprNoIn
593                                         { $$ = makeAssignNode($1, $2, $3); }
594 ;
595
596 AssignmentExprNoBF:
597     ConditionalExprNoBF
598   | LeftHandSideExprNoBF AssignmentOperator AssignmentExpr
599                                         { $$ = makeAssignNode($1, $2, $3); }
600 ;
601
602 AssignmentOperator:
603     '='                                 { $$ = OpEqual; }
604   | PLUSEQUAL                           { $$ = OpPlusEq; }
605   | MINUSEQUAL                          { $$ = OpMinusEq; }
606   | MULTEQUAL                           { $$ = OpMultEq; }
607   | DIVEQUAL                            { $$ = OpDivEq; }
608   | LSHIFTEQUAL                         { $$ = OpLShift; }
609   | RSHIFTEQUAL                         { $$ = OpRShift; }
610   | URSHIFTEQUAL                        { $$ = OpURShift; }
611   | ANDEQUAL                            { $$ = OpAndEq; }
612   | XOREQUAL                            { $$ = OpXOrEq; }
613   | OREQUAL                             { $$ = OpOrEq; }
614   | MODEQUAL                            { $$ = OpModEq; }
615 ;
616
617 Expr:
618     AssignmentExpr
619   | Expr ',' AssignmentExpr             { $$ = new CommaNode($1, $3); }
620 ;
621
622 ExprNoIn:
623     AssignmentExprNoIn
624   | ExprNoIn ',' AssignmentExprNoIn     { $$ = new CommaNode($1, $3); }
625 ;
626
627 ExprNoBF:
628     AssignmentExprNoBF
629   | ExprNoBF ',' AssignmentExpr         { $$ = new CommaNode($1, $3); }
630 ;
631
632 Statement:
633     Block
634   | VariableStatement
635   | ConstStatement
636   | EmptyStatement
637   | ExprStatement
638   | IfStatement
639   | IterationStatement
640   | ContinueStatement
641   | BreakStatement
642   | ReturnStatement
643   | WithStatement
644   | SwitchStatement
645   | LabelledStatement
646   | ThrowStatement
647   | TryStatement
648   | DebuggerStatement
649 ;
650
651 Block:
652     '{' '}'                             { $$ = new BlockNode(0); DBG($$, @2, @2); }
653   | '{' SourceElements '}'              { $$ = new BlockNode($2); DBG($$, @3, @3); }
654 ;
655
656 VariableStatement:
657     VAR VariableDeclarationList ';'     { $$ = new VarStatementNode($2); DBG($$, @1, @3); }
658   | VAR VariableDeclarationList error   { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
659 ;
660
661 VariableDeclarationList:
662     VariableDeclaration                 { $$ = new VarDeclListNode($1); }
663   | VariableDeclarationList ',' VariableDeclaration
664                                         { $$ = new VarDeclListNode($1, $3); }
665 ;
666
667 VariableDeclarationListNoIn:
668     VariableDeclarationNoIn             { $$ = new VarDeclListNode($1); }
669   | VariableDeclarationListNoIn ',' VariableDeclarationNoIn
670                                         { $$ = new VarDeclListNode($1, $3); }
671 ;
672
673 VariableDeclaration:
674     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); }
675   | IDENT Initializer                   { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); }
676 ;
677
678 VariableDeclarationNoIn:
679     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Variable); }
680   | IDENT InitializerNoIn               { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Variable); }
681 ;
682
683 ConstStatement:
684     CONSTTOKEN ConstDeclarationList ';' { $$ = new VarStatementNode($2); DBG($$, @1, @3); }
685   | CONSTTOKEN ConstDeclarationList error
686                                         { $$ = new VarStatementNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
687 ;
688
689 ConstDeclarationList:
690     ConstDeclaration                    { $$ = new VarDeclListNode($1); }
691   | ConstDeclarationList ',' ConstDeclaration
692                                         { $$ = new VarDeclListNode($1, $3); }
693 ;
694
695 ConstDeclaration:
696     IDENT                               { $$ = new VarDeclNode(*$1, 0, VarDeclNode::Constant); }
697   | IDENT Initializer                   { $$ = new VarDeclNode(*$1, $2, VarDeclNode::Constant); }
698 ;
699
700 Initializer:
701     '=' AssignmentExpr                  { $$ = new AssignExprNode($2); }
702 ;
703
704 InitializerNoIn:
705     '=' AssignmentExprNoIn              { $$ = new AssignExprNode($2); }
706 ;
707
708 EmptyStatement:
709     ';'                                 { $$ = new EmptyStatementNode(); }
710 ;
711
712 ExprStatement:
713     ExprNoBF ';'                        { $$ = new ExprStatementNode($1); DBG($$, @1, @2); }
714   | ExprNoBF error                      { $$ = new ExprStatementNode($1); DBG($$, @1, @1); AUTO_SEMICOLON; }
715 ;
716
717 IfStatement:
718     IF '(' Expr ')' Statement %prec IF_WITHOUT_ELSE
719                                         { $$ = new IfNode($3, $5, 0); DBG($$, @1, @4); }
720   | IF '(' Expr ')' Statement ELSE Statement
721                                         { $$ = new IfNode($3, $5, $7); DBG($$, @1, @4); }
722 ;
723
724 IterationStatement:
725     DO Statement WHILE '(' Expr ')' ';'    { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3);}
726   | DO Statement WHILE '(' Expr ')'     { $$ = new DoWhileNode($2, $5); DBG($$, @1, @3);}
727   | WHILE '(' Expr ')' Statement        { $$ = new WhileNode($3, $5); DBG($$, @1, @4); }
728   | FOR '(' ExprNoInOpt ';' ExprOpt ';' ExprOpt ')' Statement
729                                         { $$ = new ForNode($3, $5, $7, $9); DBG($$, @1, @8); }
730   | FOR '(' VAR VariableDeclarationListNoIn ';' ExprOpt ';' ExprOpt ')' Statement
731                                         { $$ = new ForNode($4, $6, $8, $10); DBG($$, @1, @9); }
732   | FOR '(' LeftHandSideExpr INTOKEN Expr ')' Statement
733                                         {
734                                             Node *n = $3->nodeInsideAllParens();
735                                             if (!n->isLocation())
736                                                 YYABORT;
737                                             $$ = new ForInNode(n, $5, $7);
738                                             DBG($$, @1, @6);
739                                         }
740   | FOR '(' VAR IDENT INTOKEN Expr ')' Statement
741                                         { $$ = new ForInNode(*$4, 0, $6, $8); DBG($$, @1, @7); }
742   | FOR '(' VAR IDENT InitializerNoIn INTOKEN Expr ')' Statement
743                                         { $$ = new ForInNode(*$4, $5, $7, $9); DBG($$, @1, @8); }
744 ;
745
746 ExprOpt:
747     /* nothing */                       { $$ = 0; }
748   | Expr
749 ;
750
751 ExprNoInOpt:
752     /* nothing */                       { $$ = 0; }
753   | ExprNoIn
754 ;
755
756 ContinueStatement:
757     CONTINUE ';'                        { $$ = new ContinueNode(); DBG($$, @1, @2); }
758   | CONTINUE error                      { $$ = new ContinueNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
759   | CONTINUE IDENT ';'                  { $$ = new ContinueNode(*$2); DBG($$, @1, @3); }
760   | CONTINUE IDENT error                { $$ = new ContinueNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; }
761 ;
762
763 BreakStatement:
764     BREAK ';'                           { $$ = new BreakNode(); DBG($$, @1, @2); }
765   | BREAK error                         { $$ = new BreakNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
766   | BREAK IDENT ';'                     { $$ = new BreakNode(*$2); DBG($$, @1, @3); }
767   | BREAK IDENT error                   { $$ = new BreakNode(*$2); DBG($$, @1, @2); AUTO_SEMICOLON; }
768 ;
769
770 ReturnStatement:
771     RETURN ';'                          { $$ = new ReturnNode(0); DBG($$, @1, @2); }
772   | RETURN error                        { $$ = new ReturnNode(0); DBG($$, @1, @1); AUTO_SEMICOLON; }
773   | RETURN Expr ';'                     { $$ = new ReturnNode($2); DBG($$, @1, @3); }
774   | RETURN Expr error                   { $$ = new ReturnNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
775 ;
776
777 WithStatement:
778     WITH '(' Expr ')' Statement         { $$ = new WithNode($3, $5); DBG($$, @1, @4); }
779 ;
780
781 SwitchStatement:
782     SWITCH '(' Expr ')' CaseBlock       { $$ = new SwitchNode($3, $5); DBG($$, @1, @4); }
783 ;
784
785 CaseBlock:
786     '{' CaseClausesOpt '}'              { $$ = new CaseBlockNode($2, 0, 0); }
787   | '{' CaseClausesOpt DefaultClause CaseClausesOpt '}'
788                                         { $$ = new CaseBlockNode($2, $3, $4); }
789 ;
790
791 CaseClausesOpt:
792     /* nothing */                       { $$ = 0; }
793   | CaseClauses
794 ;
795
796 CaseClauses:
797     CaseClause                          { $$ = new ClauseListNode($1); }
798   | CaseClauses CaseClause              { $$ = new ClauseListNode($1, $2); }
799 ;
800
801 CaseClause:
802     CASE Expr ':'                       { $$ = new CaseClauseNode($2); }
803   | CASE Expr ':' SourceElements        { $$ = new CaseClauseNode($2, $4); }
804 ;
805
806 DefaultClause:
807     DEFAULT ':'                         { $$ = new CaseClauseNode(0); }
808   | DEFAULT ':' SourceElements          { $$ = new CaseClauseNode(0, $3); }
809 ;
810
811 LabelledStatement:
812     IDENT ':' Statement                 { $3->pushLabel(*$1); $$ = new LabelNode(*$1, $3); }
813 ;
814
815 ThrowStatement:
816     THROW Expr ';'                      { $$ = new ThrowNode($2); DBG($$, @1, @3); }
817   | THROW Expr error                    { $$ = new ThrowNode($2); DBG($$, @1, @2); AUTO_SEMICOLON; }
818 ;
819
820 TryStatement:
821     TRY Block FINALLY Block             { $$ = new TryNode($2, CommonIdentifiers::shared()->nullIdentifier, 0, $4); DBG($$, @1, @2); }
822   | TRY Block CATCH '(' IDENT ')' Block { $$ = new TryNode($2, *$5, $7, 0); DBG($$, @1, @2); }
823   | TRY Block CATCH '(' IDENT ')' Block FINALLY Block
824                                         { $$ = new TryNode($2, *$5, $7, $9); DBG($$, @1, @2); }
825 ;
826
827 DebuggerStatement:
828     DEBUGGER ';'                        { $$ = new EmptyStatementNode(); DBG($$, @1, @2); }
829   | DEBUGGER error                      { $$ = new EmptyStatementNode(); DBG($$, @1, @1); AUTO_SEMICOLON; }
830 ;
831
832 FunctionDeclaration:
833     FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncDeclNode(*$2, $5); }
834   | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
835                                         { $$ = new FuncDeclNode(*$2, $4, $6); }
836 ;
837
838 FunctionExpr:
839     FUNCTION '(' ')' FunctionBody       { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $4); }
840   | FUNCTION '(' FormalParameterList ')' FunctionBody
841                                         { $$ = new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, $5, $3); }
842   | FUNCTION IDENT '(' ')' FunctionBody { $$ = new FuncExprNode(*$2, $5); }
843   | FUNCTION IDENT '(' FormalParameterList ')' FunctionBody
844                                         { $$ = new FuncExprNode(*$2, $6, $4); }
845 ;
846
847 FormalParameterList:
848     IDENT                               { $$ = new ParameterNode(*$1); }
849   | FormalParameterList ',' IDENT       { $$ = new ParameterNode($1, *$3); }
850 ;
851
852 FunctionBody:
853     '{' '}' /* not in spec */           { $$ = new FunctionBodyNode(0); DBG($$, @1, @2); }
854   | '{' SourceElements '}'              { $$ = new FunctionBodyNode($2); DBG($$, @1, @3); }
855 ;
856
857 Program:
858     /* not in spec */                   { Parser::accept(new ProgramNode(0)); }
859     | SourceElements                    { Parser::accept(new ProgramNode($1)); }
860 ;
861
862 SourceElements:
863     SourceElement                       { $$ = new SourceElementsNode($1); }
864   | SourceElements SourceElement        { $$ = new SourceElementsNode($1, $2); }
865 ;
866
867 SourceElement:
868     FunctionDeclaration                 { $$ = $1; }
869   | Statement                           { $$ = $1; }
870 ;
871  
872 %%
873
874 static Node* makeAssignNode(Node* loc, Operator op, Node* expr)
875
876     Node *n = loc->nodeInsideAllParens();
877
878     if (!n->isLocation())
879         return new AssignErrorNode(loc, op, expr);
880
881     if (n->isResolveNode()) {
882         ResolveNode *resolve = static_cast<ResolveNode *>(n);
883         return new AssignResolveNode(resolve->identifier(), op, expr);
884     }
885     if (n->isBracketAccessorNode()) {
886         BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
887         return new AssignBracketNode(bracket->base(), bracket->subscript(), op, expr);
888     }
889     assert(n->isDotAccessorNode());
890     DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
891     return new AssignDotNode(dot->base(), dot->identifier(), op, expr);
892 }
893
894 static Node* makePrefixNode(Node *expr, Operator op)
895
896     Node *n = expr->nodeInsideAllParens();
897
898     if (!n->isLocation())
899         return new PrefixErrorNode(expr, op);
900     
901     if (n->isResolveNode()) {
902         ResolveNode *resolve = static_cast<ResolveNode *>(n);
903         return new PrefixResolveNode(resolve->identifier(), op);
904     }
905     if (n->isBracketAccessorNode()) {
906         BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
907         return new PrefixBracketNode(bracket->base(), bracket->subscript(), op);
908     }
909     assert(n->isDotAccessorNode());
910     DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
911     return new PrefixDotNode(dot->base(), dot->identifier(), op);
912 }
913
914 static Node* makePostfixNode(Node* expr, Operator op)
915
916     Node *n = expr->nodeInsideAllParens();
917
918     if (!n->isLocation())
919         return new PostfixErrorNode(expr, op);
920     
921     if (n->isResolveNode()) {
922         ResolveNode *resolve = static_cast<ResolveNode *>(n);
923         return new PostfixResolveNode(resolve->identifier(), op);
924     }
925     if (n->isBracketAccessorNode()) {
926         BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
927         return new PostfixBracketNode(bracket->base(), bracket->subscript(), op);
928     }
929     assert(n->isDotAccessorNode());
930     DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
931     return new PostfixDotNode(dot->base(), dot->identifier(), op);
932 }
933
934 static Node *makeFunctionCallNode(Node *func, ArgumentsNode *args)
935 {
936     Node *n = func->nodeInsideAllParens();
937     
938     if (!n->isLocation())
939         return new FunctionCallValueNode(func, args);
940     else if (n->isResolveNode()) {
941         ResolveNode *resolve = static_cast<ResolveNode *>(n);
942         return new FunctionCallResolveNode(resolve->identifier(), args);
943     } else if (n->isBracketAccessorNode()) {
944         BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
945         if (n != func)
946             return new FunctionCallParenBracketNode(bracket->base(), bracket->subscript(), args);
947         else
948             return new FunctionCallBracketNode(bracket->base(), bracket->subscript(), args);
949     } else {
950         assert(n->isDotAccessorNode());
951         DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
952         if (n != func)
953             return new FunctionCallParenDotNode(dot->base(), dot->identifier(), args);
954         else
955             return new FunctionCallDotNode(dot->base(), dot->identifier(), args);
956     }
957 }
958
959 static Node *makeTypeOfNode(Node *expr)
960 {
961     Node *n = expr->nodeInsideAllParens();
962
963     if (n->isResolveNode()) {
964         ResolveNode *resolve = static_cast<ResolveNode *>(n);
965         return new TypeOfResolveNode(resolve->identifier());
966     } else
967         return new TypeOfValueNode(expr);
968 }
969
970 static Node *makeDeleteNode(Node *expr)
971 {
972     Node *n = expr->nodeInsideAllParens();
973     
974     if (!n->isLocation())
975         return new DeleteValueNode(expr);
976     else if (n->isResolveNode()) {
977         ResolveNode *resolve = static_cast<ResolveNode *>(n);
978         return new DeleteResolveNode(resolve->identifier());
979     } else if (n->isBracketAccessorNode()) {
980         BracketAccessorNode *bracket = static_cast<BracketAccessorNode *>(n);
981         return new DeleteBracketNode(bracket->base(), bracket->subscript());
982     } else {
983         assert(n->isDotAccessorNode());
984         DotAccessorNode *dot = static_cast<DotAccessorNode *>(n);
985         return new DeleteDotNode(dot->base(), dot->identifier());
986     }
987 }
988
989 static bool makeGetterOrSetterPropertyNode(PropertyNode*& result, Identifier& getOrSet, Identifier& name, ParameterNode *params, FunctionBodyNode *body)
990 {
991     PropertyNode::Type type;
992     
993     if (getOrSet == "get")
994         type = PropertyNode::Getter;
995     else if (getOrSet == "set")
996         type = PropertyNode::Setter;
997     else
998         return false;
999     
1000     result = new PropertyNode(new PropertyNameNode(name), 
1001                               new FuncExprNode(CommonIdentifiers::shared()->nullIdentifier, body, params), type);
1002
1003     return true;
1004 }
1005
1006 /* called by yyparse on error */
1007 int yyerror(const char *)
1008 {
1009     return 1;
1010 }
1011
1012 /* may we automatically insert a semicolon ? */
1013 static bool allowAutomaticSemicolon()
1014 {
1015     return yychar == '}' || yychar == 0 || Lexer::curr()->prevTerminator();
1016 }