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