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