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