]> git.saurik.com Git - cycript.git/blob - Cycript.y
f87d08077e45125c94862a4f24d5303adb22b303
[cycript.git] / Cycript.y
1 %code top {
2 #include "Cycript.tab.hh"
3 int cylex(YYSTYPE *lvalp, YYLTYPE *llocp, void *scanner);
4 #define scanner driver.scanner_
5 }
6
7 %code requires {
8 #include "Parser.hpp"
9
10 typedef struct {
11 bool newline_;
12
13 union {
14 CYArgument *argument_;
15 CYBoolean *boolean_;
16 CYClause *clause_;
17 CYCatch *catch_;
18 CYDeclaration *declaration_;
19 CYDeclarations *declarations_;
20 CYElement *element_;
21 CYExpression *expression_;
22 CYFalse *false_;
23 CYForInitialiser *for_;
24 CYForInInitialiser *forin_;
25 CYIdentifier *identifier_;
26 CYLiteral *literal_;
27 CYName *name_;
28 CYNull *null_;
29 CYNumber *number_;
30 CYParameter *parameter_;
31 CYProperty *property_;
32 CYSource *source_;
33 CYStatement *statement_;
34 CYString *string_;
35 CYThis *this_;
36 CYTrue *true_;
37 CYWord *word_;
38 };
39 } YYSTYPE;
40
41 }
42
43 %name-prefix "cy"
44
45 %language "C++"
46 %locations
47 %glr-parser
48
49 %initial-action {
50 @$.begin.filename = @$.end.filename = &driver.filename_;
51 };
52
53 %defines
54
55 %debug
56 %error-verbose
57
58 %parse-param { CYDriver &driver }
59 %lex-param { void *scanner }
60
61 %token Ampersand "&"
62 %token AmpersandAmpersand "&&"
63 %token AmpersandEqual "&="
64 %token Carrot "^"
65 %token CarrotEqual "^="
66 %token Equal "="
67 %token EqualEqual "=="
68 %token EqualEqualEqual "==="
69 %token Exclamation "!"
70 %token ExclamationEqual "!="
71 %token ExclamationEqualEqual "!=="
72 %token Hyphen "-"
73 %token HyphenEqual "-="
74 %token HyphenHyphen "--"
75 %token HyphenHyphen_ "\n--"
76 %token HyphenRight "->"
77 %token Left "<"
78 %token LeftEqual "<="
79 %token LeftLeft "<<"
80 %token LeftLeftEqual "<<="
81 %token Percent "%"
82 %token PercentEqual "%="
83 %token Period "."
84 %token Pipe "|"
85 %token PipeEqual "|="
86 %token PipePipe "||"
87 %token Plus "+"
88 %token PlusEqual "+="
89 %token PlusPlus "++"
90 %token PlusPlus_ "\n++"
91 %token Right ">"
92 %token RightEqual ">="
93 %token RightRight ">>"
94 %token RightRightEqual ">>="
95 %token RightRightRight ">>>"
96 %token RightRightRightEqual ">>>="
97 %token Slash "/"
98 %token SlashEqual "/="
99 %token Star "*"
100 %token StarEqual "*="
101 %token Tilde "~"
102
103 %token Colon ":"
104 %token Comma ","
105 %token Question "?"
106 %token SemiColon ";"
107 %token NewLine "\n"
108
109 %token OpenParen "("
110 %token CloseParen ")"
111
112 %token OpenBrace "{"
113 %token CloseBrace "}"
114
115 %token OpenBracket "["
116 %token CloseBracket "]"
117
118 %token <word_> Break "break"
119 %token <word_> Case "case"
120 %token <word_> Catch "catch"
121 %token <word_> Continue "continue"
122 %token <word_> Default "default"
123 %token <word_> Delete "delete"
124 %token <word_> Do "do"
125 %token <word_> Else "else"
126 %token <false_> False "false"
127 %token <word_> Finally "finally"
128 %token <word_> For "for"
129 %token <word_> Function "function"
130 %token <word_> If "if"
131 %token <word_> In "in"
132 %token <word_> InstanceOf "instanceof"
133 %token <word_> New "new"
134 %token <null_> Null "null"
135 %token <word_> Return "return"
136 %token <word_> Switch "switch"
137 %token <this_> This "this"
138 %token <word_> Throw "throw"
139 %token <true_> True "true"
140 %token <word_> Try "try"
141 %token <word_> TypeOf "typeof"
142 %token <word_> Var "var"
143 %token <word_> Void "void"
144 %token <word_> While "while"
145 %token <word_> With "with"
146
147 %token <identifier_> Identifier
148 %token <number_> NumericLiteral
149 %token <string_> StringLiteral
150
151 %type <expression_> AdditiveExpression
152 %type <argument_> ArgumentList
153 %type <argument_> ArgumentList_
154 %type <argument_> ArgumentListOpt
155 %type <argument_> Arguments
156 %type <literal_> ArrayLiteral
157 %type <expression_> AssignmentExpression
158 %type <expression_> BitwiseANDExpression
159 %type <statement_> Block
160 %type <boolean_> BooleanLiteral
161 %type <expression_> BitwiseORExpression
162 %type <expression_> BitwiseXORExpression
163 %type <statement_> BreakStatement
164 %type <expression_> CallExpression
165 %type <clause_> CaseBlock
166 %type <clause_> CaseClause
167 %type <clause_> CaseClausesOpt
168 %type <catch_> CatchOpt
169 %type <expression_> ConditionalExpression
170 %type <statement_> ContinueStatement
171 %type <clause_> DefaultClause
172 %type <statement_> DoWhileStatement
173 %type <expression_> Element
174 %type <element_> ElementList
175 %type <element_> ElementList_
176 %type <statement_> ElseStatementOpt
177 %type <statement_> EmptyStatement
178 %type <expression_> EqualityExpression
179 %type <expression_> Expression
180 %type <expression_> Expression_
181 %type <expression_> ExpressionOpt
182 %type <statement_> ExpressionStatement
183 %type <statement_> FinallyOpt
184 %type <statement_> ForStatement
185 %type <for_> ForStatementInitialiser
186 %type <statement_> ForInStatement
187 %type <forin_> ForInStatementInitialiser
188 %type <parameter_> FormalParameterList
189 %type <parameter_> FormalParameterList_
190 %type <source_> FunctionBody
191 %type <source_> FunctionDeclaration
192 %type <expression_> FunctionExpression
193 %type <identifier_> IdentifierOpt
194 %type <statement_> IfStatement
195 %type <expression_> Initialiser
196 %type <expression_> InitialiserOpt
197 %type <statement_> IterationStatement
198 %type <statement_> LabelledStatement
199 %type <expression_> LeftHandSideExpression
200 %type <literal_> Literal
201 %type <expression_> LogicalANDExpression
202 %type <expression_> LogicalORExpression
203 %type <expression_> MemberExpression
204 %type <expression_> MultiplicativeExpression
205 %type <expression_> NewExpression
206 %type <null_> NullLiteral
207 %type <literal_> ObjectLiteral
208 %type <expression_> MessageExpression
209 %type <expression_> PostfixExpression
210 %type <expression_> PrimaryExpression
211 %type <source_> Program
212 %type <name_> PropertyName
213 %type <property_> PropertyNameAndValueList
214 %type <property_> PropertyNameAndValueList_
215 %type <property_> PropertyNameAndValueListOpt
216 %type <expression_> QExpressionOpt
217 %type <identifier_> QIdentifierOpt
218 %type <expression_> RelationalExpression
219 %type <statement_> ReturnStatement
220 %type <argument_> SelectorCall
221 %type <argument_> SelectorCall_
222 %type <argument_> SelectorList
223 %type <expression_> ShiftExpression
224 %type <source_> SourceElement
225 %type <source_> SourceElements
226 %type <statement_> Statement
227 %type <statement_> StatementListOpt
228 %type <statement_> SwitchStatement
229 %type <statement_> ThrowStatement
230 %type <statement_> TryStatement
231 %type <expression_> UnaryExpression
232 %type <declaration_> VariableDeclaration
233 %type <declarations_> VariableDeclarationList
234 %type <declarations_> VariableDeclarationList_
235 %type <statement_> VariableStatement
236 %type <argument_> VariadicCall
237 %type <statement_> WhileStatement
238 %type <statement_> WithStatement
239 %type <word_> Word
240 %type <word_> WordOpt
241
242 %nonassoc "if"
243 %nonassoc "else"
244
245 %%
246
247 %start Program;
248
249 Q
250 :
251 /*| NewLine*/
252 ;
253
254 QTerminator
255 : Q Terminator
256 ;
257
258 /*TerminatorOpt
259 : QTerminator
260 |
261 ;
262
263 Terminator
264 : ";"
265 | NewLine
266 ;*/
267
268 TerminatorOpt
269 : ";"
270 | NewLine
271 |
272 ;
273
274 Terminator
275 : ";"
276 | NewLine
277 | error { yyerrok; }
278 ;
279
280 NewLineOpt
281 : NewLine
282 |
283 ;
284
285 WordOpt /*Qq*/
286 : Word { $$ = $1; }
287 | { $$ = NULL; }
288 ;
289
290 Word /*Q*/
291 : Identifier { $$ = $1; }
292 | "break" NewLineOpt { $$ = $1; }
293 | "case" { $$ = $1; }
294 | "catch" { $$ = $1; }
295 | "continue" NewLineOpt { $$ = $1; }
296 | "default" { $$ = $1; }
297 | "delete" { $$ = $1; }
298 | "do" { $$ = $1; }
299 | "else" { $$ = $1; }
300 | "false" { $$ = $1; }
301 | "finally" { $$ = $1; }
302 | "for" { $$ = $1; }
303 | "function" { $$ = $1; }
304 | "if" { $$ = $1; }
305 | "in" { $$ = $1; }
306 | "instanceof" { $$ = $1; }
307 | "new" { $$ = $1; }
308 | "null" { $$ = $1; }
309 | "return" NewLineOpt { $$ = $1; }
310 | "switch" { $$ = $1; }
311 | "this" { $$ = $1; }
312 | "throw" NewLineOpt { $$ = $1; }
313 | "true" { $$ = $1; }
314 | "try" { $$ = $1; }
315 | "typeof" { $$ = $1; }
316 | "var" { $$ = $1; }
317 | "void" { $$ = $1; }
318 | "while" { $$ = $1; }
319 | "with" { $$ = $1; }
320 ;
321
322 IdentifierOpt /*Q*/
323 : Identifier { $$ = $1; }
324 | { $$ = NULL; }
325 ;
326
327 QIdentifierOpt
328 : Q Identifier { $$ = $2; }
329 | { $$ = NULL; }
330 ;
331
332 Literal /*Q*/
333 : NullLiteral { $$ = $1; }
334 | BooleanLiteral { $$ = $1; }
335 | NumericLiteral { $$ = $1; }
336 | StringLiteral { $$ = $1; }
337 ;
338
339 NullLiteral /*Q*/
340 : "null" { $$ = $1; }
341 ;
342
343 BooleanLiteral /*Q*/
344 : "true" { $$ = $1; }
345 | "false" { $$ = $1; }
346 ;
347
348 /* Objective-C Extensions {{{ */
349 VariadicCall /*Qq*/
350 : "," Q AssignmentExpression VariadicCall { $$ = new(driver.pool_) CYArgument(NULL, $3, $4); }
351 | { $$ = NULL; }
352 ;
353
354 SelectorCall_ /*Qq*/
355 : SelectorCall { $$ = $1; }
356 | VariadicCall { $$ = $1; }
357 ;
358
359 SelectorCall /*Qq*/
360 : WordOpt ":" Q AssignmentExpression SelectorCall_ { $$ = new(driver.pool_) CYArgument($1 ?: new(driver.pool_) CYBlank(), $4, $5); }
361 ;
362
363 SelectorList /*Qq*/
364 : SelectorCall { $$ = $1; }
365 | Word Q { $$ = new(driver.pool_) CYArgument($1, NULL); }
366 ;
367
368 MessageExpression /*Q*/
369 : "[" Q AssignmentExpression SelectorList "]" { $$ = new(driver.pool_) CYMessage($3, $4); }
370 ;
371 /* }}} */
372
373 /* 11.1 Primary Expressions {{{ */
374 PrimaryExpression /*Q*/
375 : "this" { $$ = $1; }
376 | Identifier { $$ = new(driver.pool_) CYVariable($1); }
377 | Literal { $$ = $1; }
378 | ArrayLiteral { $$ = $1; }
379 | ObjectLiteral { $$ = $1; }
380 | "(" Q Expression ")" { $$ = $3; }
381 | MessageExpression { $$ = $1; }
382 ;
383 /* }}} */
384 /* 11.1.4 Array Initialiser {{{ */
385 ArrayLiteral /*Q*/
386 : "[" Q ElementList "]" { $$ = $3; }
387 ;
388
389 Element /*Qq*/
390 : AssignmentExpression { $$ = $1; }
391 | { $$ = NULL; }
392 ;
393
394 ElementList_ /*Qq*/
395 : "," Q ElementList { $$ = $3; }
396 | { $$ = NULL; }
397 ;
398
399 ElementList /*Qq*/
400 : Element ElementList_ { $$ = new(driver.pool_) CYElement($1, $2); }
401 ;
402 /* }}} */
403 /* 11.1.5 Object Initialiser {{{ */
404 ObjectLiteral /*Q*/
405 : "{" PropertyNameAndValueListOpt "}" { $$ = $2; }
406 ;
407
408 PropertyNameAndValueList_ /*Qq*/
409 : "," PropertyNameAndValueList { $$ = $2; }
410 | { $$ = NULL; }
411 ;
412
413 PropertyNameAndValueListOpt /*q*/
414 : PropertyNameAndValueList { $$ = $1; }
415 | Q { $$ = NULL; }
416 ;
417
418 PropertyNameAndValueList /*q*/
419 : PropertyName Q ":" Q AssignmentExpression PropertyNameAndValueList_ { $$ = new(driver.pool_) CYProperty($1, $5, $6); }
420 ;
421
422 PropertyName
423 : Q Identifier { $$ = $2; }
424 | Q StringLiteral { $$ = $2; }
425 | Q NumericLiteral { $$ = $2; }
426 ;
427 /* }}} */
428
429 MemberExpression /*Q*/
430 : PrimaryExpression { $$ = $1; }
431 | FunctionExpression { $$ = $1; }
432 | MemberExpression Q "[" Q Expression "]" { $$ = new(driver.pool_) CYMember($1, $5); }
433 | MemberExpression Q "." Q Identifier { $$ = new(driver.pool_) CYMember($1, new(driver.pool_) CYString($5)); }
434 | "new" Q MemberExpression Arguments { $$ = new(driver.pool_) CYNew($3, $4); }
435 ;
436
437 NewExpression /*Q*/
438 : MemberExpression { $$ = $1; }
439 | "new" Q NewExpression { $$ = new(driver.pool_) CYNew($3, NULL); }
440 ;
441
442 CallExpression /*Q*/
443 : MemberExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
444 | CallExpression Arguments { $$ = new(driver.pool_) CYCall($1, $2); }
445 | CallExpression Q "[" Q Expression "]" { $$ = new(driver.pool_) CYMember($1, $5); }
446 | CallExpression Q "." Q Identifier { $$ = new(driver.pool_) CYMember($1, new(driver.pool_) CYString($5)); }
447 ;
448
449 ArgumentList_ /*Qq*/
450 : "," ArgumentList { $$ = $2; }
451 | { $$ = NULL; }
452 ;
453
454 ArgumentListOpt /*q*/
455 : ArgumentList { $$ = $1; }
456 | Q { $$ = NULL; }
457 ;
458
459 ArgumentList /*q*/
460 : Q AssignmentExpression ArgumentList_ { $$ = new(driver.pool_) CYArgument(NULL, $2, $3); }
461 ;
462
463 Arguments
464 : Q "(" ArgumentListOpt ")" { $$ = $3; }
465 ;
466
467 LeftHandSideExpression /*Q*/
468 : NewExpression { $$ = $1; }
469 | CallExpression { $$ = $1; }
470 | "*" Q LeftHandSideExpression { $$ = new(driver.pool_) CYIndirect($3); }
471 ;
472
473 PostfixExpression /*Q*/
474 : LeftHandSideExpression { $$ = $1; }
475 | LeftHandSideExpression "++" { $$ = new(driver.pool_) CYPostIncrement($1); }
476 | LeftHandSideExpression "--" { $$ = new(driver.pool_) CYPostDecrement($1); }
477 ;
478
479 UnaryExpression /*Qq*/
480 : PostfixExpression Q { $$ = $1; }
481 | "delete" Q UnaryExpression { $$ = new(driver.pool_) CYDelete($3); }
482 | "void" Q UnaryExpression { $$ = new(driver.pool_) CYVoid($3); }
483 | "typeof" Q UnaryExpression { $$ = new(driver.pool_) CYTypeOf($3); }
484 | "++" Q UnaryExpression { $$ = new(driver.pool_) CYPreIncrement($3); }
485 | "\n++" Q UnaryExpression { $$ = new(driver.pool_) CYPreIncrement($3); }
486 | "--" Q UnaryExpression { $$ = new(driver.pool_) CYPreDecrement($3); }
487 | "\n--" Q UnaryExpression { $$ = new(driver.pool_) CYPreDecrement($3); }
488 | "+" Q UnaryExpression { $$ = $3; }
489 | "-" Q UnaryExpression { $$ = new(driver.pool_) CYNegate($3); }
490 | "~" Q UnaryExpression { $$ = new(driver.pool_) CYBitwiseNot($3); }
491 | "!" Q UnaryExpression { $$ = new(driver.pool_) CYLogicalNot($3); }
492 | "&" Q UnaryExpression { $$ = new(driver.pool_) CYAddressOf($3); }
493 ;
494
495 MultiplicativeExpression /*Qq*/
496 : UnaryExpression { $$ = $1; }
497 | MultiplicativeExpression "*" Q UnaryExpression { $$ = new(driver.pool_) CYMultiply($1, $4); }
498 | MultiplicativeExpression "/" Q UnaryExpression { $$ = new(driver.pool_) CYDivide($1, $4); }
499 | MultiplicativeExpression "%" Q UnaryExpression { $$ = new(driver.pool_) CYModulus($1, $4); }
500 ;
501
502 AdditiveExpression /*Qq*/
503 : MultiplicativeExpression { $$ = $1; }
504 | AdditiveExpression "+" Q MultiplicativeExpression { $$ = new(driver.pool_) CYAdd($1, $4); }
505 | AdditiveExpression "-" Q MultiplicativeExpression { $$ = new(driver.pool_) CYSubtract($1, $4); }
506 ;
507
508 ShiftExpression /*Qq*/
509 : AdditiveExpression { $$ = $1; }
510 | ShiftExpression "<<" Q AdditiveExpression { $$ = new(driver.pool_) CYShiftLeft($1, $4); }
511 | ShiftExpression ">>" Q AdditiveExpression { $$ = new(driver.pool_) CYShiftRightSigned($1, $4); }
512 | ShiftExpression ">>>" Q AdditiveExpression { $$ = new(driver.pool_) CYShiftRightUnsigned($1, $4); }
513 ;
514
515 RelationalExpression /*Qq*/
516 : ShiftExpression { $$ = $1; }
517 | RelationalExpression "<" Q ShiftExpression { $$ = new(driver.pool_) CYLess($1, $4); }
518 | RelationalExpression ">" Q ShiftExpression { $$ = new(driver.pool_) CYGreater($1, $4); }
519 | RelationalExpression "<=" Q ShiftExpression { $$ = new(driver.pool_) CYLessOrEqual($1, $4); }
520 | RelationalExpression ">=" Q ShiftExpression { $$ = new(driver.pool_) CYGreaterOrEqual($1, $4); }
521 | RelationalExpression "instanceof" Q ShiftExpression { $$ = new(driver.pool_) CYInstanceOf($1, $4); }
522 | RelationalExpression "in" Q ShiftExpression { $$ = new(driver.pool_) CYIn($1, $4); }
523 ;
524
525 EqualityExpression /*Qq*/
526 : RelationalExpression { $$ = $1; }
527 | EqualityExpression "==" Q RelationalExpression { $$ = new(driver.pool_) CYEqual($1, $4); }
528 | EqualityExpression "!=" Q RelationalExpression { $$ = new(driver.pool_) CYNotEqual($1, $4); }
529 | EqualityExpression "===" Q RelationalExpression { $$ = new(driver.pool_) CYIdentical($1, $4); }
530 | EqualityExpression "!==" Q RelationalExpression { $$ = new(driver.pool_) CYNotIdentical($1, $4); }
531 ;
532
533 BitwiseANDExpression /*Qq*/
534 : EqualityExpression { $$ = $1; }
535 | BitwiseANDExpression "&" Q EqualityExpression { $$ = new(driver.pool_) CYBitwiseAnd($1, $4); }
536 ;
537
538 BitwiseXORExpression /*Qq*/
539 : BitwiseANDExpression { $$ = $1; }
540 | BitwiseXORExpression "^" Q BitwiseANDExpression { $$ = new(driver.pool_) CYBitwiseXOr($1, $4); }
541 ;
542
543 BitwiseORExpression /*Qq*/
544 : BitwiseXORExpression { $$ = $1; }
545 | BitwiseORExpression "|" Q BitwiseXORExpression { $$ = new(driver.pool_) CYBitwiseOr($1, $4); }
546 ;
547
548 LogicalANDExpression /*Qq*/
549 : BitwiseORExpression { $$ = $1; }
550 | LogicalANDExpression "&&" Q BitwiseORExpression { $$ = new(driver.pool_) CYLogicalAnd($1, $4); }
551 ;
552
553 LogicalORExpression /*Qq*/
554 : LogicalANDExpression { $$ = $1; }
555 | LogicalORExpression "||" Q LogicalANDExpression { $$ = new(driver.pool_) CYLogicalOr($1, $4); }
556 ;
557
558 ConditionalExpression /*Qq*/
559 : LogicalORExpression { $$ = $1; }
560 | LogicalORExpression "?" Q AssignmentExpression ":" Q AssignmentExpression { $$ = new(driver.pool_) CYCondition($1, $4, $7); }
561 ;
562
563 AssignmentExpression /*Qq*/
564 : ConditionalExpression { $$ = $1; }
565 | LeftHandSideExpression Q "=" Q AssignmentExpression { $$ = new(driver.pool_) CYAssign($1, $5); }
566 | LeftHandSideExpression Q "*=" Q AssignmentExpression { $$ = new(driver.pool_) CYMultiplyAssign($1, $5); }
567 | LeftHandSideExpression Q "/=" Q AssignmentExpression { $$ = new(driver.pool_) CYDivideAssign($1, $5); }
568 | LeftHandSideExpression Q "%=" Q AssignmentExpression { $$ = new(driver.pool_) CYModulusAssign($1, $5); }
569 | LeftHandSideExpression Q "+=" Q AssignmentExpression { $$ = new(driver.pool_) CYAddAssign($1, $5); }
570 | LeftHandSideExpression Q "-=" Q AssignmentExpression { $$ = new(driver.pool_) CYSubtractAssign($1, $5); }
571 | LeftHandSideExpression Q "<<=" Q AssignmentExpression { $$ = new(driver.pool_) CYShiftLeftAssign($1, $5); }
572 | LeftHandSideExpression Q ">>=" Q AssignmentExpression { $$ = new(driver.pool_) CYShiftRightSignedAssign($1, $5); }
573 | LeftHandSideExpression Q ">>>=" Q AssignmentExpression { $$ = new(driver.pool_) CYShiftRightUnsignedAssign($1, $5); }
574 | LeftHandSideExpression Q "&=" Q AssignmentExpression { $$ = new(driver.pool_) CYBitwiseAndAssign($1, $5); }
575 | LeftHandSideExpression Q "^=" Q AssignmentExpression { $$ = new(driver.pool_) CYBitwiseXOrAssign($1, $5); }
576 | LeftHandSideExpression Q "|=" Q AssignmentExpression { $$ = new(driver.pool_) CYBitwiseOrAssign($1, $5); }
577 ;
578
579 Expression_ /*Qq*/
580 : "," Q Expression { $$ = $3; }
581 | { $$ = NULL; }
582 ;
583
584 ExpressionOpt /*Qq*/
585 : Expression { $$ = $1; }
586 | Q { $$ = NULL; }
587 ;
588
589 QExpressionOpt /*q*/
590 : Q Expression { $$ = $2; }
591 | Q { $$ = NULL; }
592 ;
593
594 Expression /*Qq*/
595 : AssignmentExpression Expression_ { if ($1) { $1->SetNext($2); $$ = $1; } else $$ = $2; }
596 ;
597
598 Statement /*Qq*/
599 : Block Q { $$ = $1; }
600 | VariableStatement Q { $$ = $1; }
601 | EmptyStatement Q { $$ = $1; }
602 | ExpressionStatement Q { $$ = $1; }
603 | IfStatement { $$ = $1; }
604 | IterationStatement { $$ = $1; }
605 | ContinueStatement Q { $$ = $1; }
606 | BreakStatement Q { $$ = $1; }
607 | ReturnStatement Q { $$ = $1; }
608 | WithStatement { $$ = $1; }
609 | LabelledStatement { $$ = $1; }
610 | SwitchStatement Q { $$ = $1; }
611 | ThrowStatement Q { $$ = $1; }
612 | TryStatement Q { $$ = $1; }
613 ;
614
615 Block /*Q*/
616 : "{" StatementListOpt "}" { $$ = $2 ?: new(driver.pool_) CYEmpty(); }
617 ;
618
619 StatementListOpt /*Qq*/
620 : Statement StatementListOpt { $1->SetNext($2); $$ = $1; }
621 | { $$ = NULL; }
622 ;
623
624 VariableStatement /*Q*/
625 : "var" VariableDeclarationList Terminator { $$ = $2; }
626 ;
627
628 VariableDeclarationList_ /*Qq*/
629 : "," VariableDeclarationList { $$ = $2; }
630 | { $$ = NULL; }
631 ;
632
633 VariableDeclarationList /*q*/
634 : VariableDeclaration VariableDeclarationList_ { $$ = new(driver.pool_) CYDeclarations($1, $2); }
635 ;
636
637 VariableDeclaration /*q*/
638 : Q Identifier InitialiserOpt { $$ = new(driver.pool_) CYDeclaration($2, $3); }
639 ;
640
641 InitialiserOpt /*q*/
642 : Initialiser { $$ = $1; }
643 | Q { $$ = NULL; }
644 ;
645
646 Initialiser /*q*/
647 : Q "=" Q AssignmentExpression { $$ = $4; }
648 ;
649
650 EmptyStatement /*Q*/
651 : ";" { $$ = new(driver.pool_) CYEmpty(); }
652 ;
653
654 ExpressionStatement /*Q*/
655 : Expression Terminator { $$ = new(driver.pool_) CYExpress($1); }
656 ;
657
658 ElseStatementOpt /*Qq*/
659 : "else" Q Statement { $$ = $3; }
660 | %prec "if" { $$ = NULL; }
661 ;
662
663 IfStatement /*Qq*/
664 : "if" Q "(" Q Expression ")" Q Statement ElseStatementOpt { $$ = new(driver.pool_) CYIf($5, $8, $9); }
665 ;
666
667 IterationStatement /*Qq*/
668 : DoWhileStatement Q { $$ = $1; }
669 | WhileStatement { $$ = $1; }
670 | ForStatement { $$ = $1; }
671 | ForInStatement { $$ = $1; }
672 ;
673
674 DoWhileStatement /*Q*/
675 : "do" Q Statement "while" Q "(" Q Expression ")" TerminatorOpt { $$ = new(driver.pool_) CYDoWhile($8, $3); }
676 ;
677
678 WhileStatement /*Qq*/
679 : "while" Q "(" Q Expression ")" Q Statement { $$ = new(driver.pool_) CYWhile($5, $8); }
680 ;
681
682 ForStatement /*Qq*/
683 : "for" Q "(" Q ForStatementInitialiser ";" QExpressionOpt ";" QExpressionOpt ")" Q Statement { $$ = new(driver.pool_) CYFor($5, $7, $9, $12); }
684 ;
685
686 ForStatementInitialiser /*Qq*/
687 : ExpressionOpt { $$ = $1; }
688 | "var" VariableDeclarationList { $$ = $2; }
689 ;
690
691 ForInStatement /*Qq*/
692 : "for" Q "(" Q ForInStatementInitialiser "in" Q Expression ")" Q Statement { $$ = new(driver.pool_) CYForIn($5, $8, $11); }
693 ;
694
695 ForInStatementInitialiser /*Qq*/
696 : LeftHandSideExpression Q { $$ = $1; }
697 | "var" VariableDeclaration { $$ = $2; }
698 ;
699
700 ContinueStatement /*Q*/
701 : "continue" IdentifierOpt QTerminator { $$ = new(driver.pool_) CYContinue($2); }
702 ;
703
704 BreakStatement /*Q*/
705 : "break" IdentifierOpt QTerminator { $$ = new(driver.pool_) CYBreak($2); }
706 ;
707
708 ReturnStatement /*Q*/
709 : "return" ExpressionOpt Terminator { $$ = new(driver.pool_) CYReturn($2); }
710 ;
711
712 WithStatement /*Qq*/
713 : "with" Q "(" Q Expression ")" Q Statement { $$ = new(driver.pool_) CYWith($5, $8); }
714 ;
715
716 SwitchStatement /*Qq*/
717 : "switch" Q "(" Q Expression ")" CaseBlock { $$ = new(driver.pool_) CYSwitch($5, $7); }
718 ;
719
720 CaseBlock
721 : Q "{" Q CaseClausesOpt "}" { $$ = $4; }
722 ;
723
724 CaseClausesOpt /*Qq*/
725 : CaseClause CaseClausesOpt { $1->SetNext($2); $$ = $1; }
726 | DefaultClause CaseClausesOpt { $1->SetNext($2); $$ = $1; }
727 | { $$ = NULL; }
728 ;
729
730 CaseClause /*Qq*/
731 : "case" Q Expression ":" StatementListOpt { $$ = new(driver.pool_) CYClause($3, $5); }
732 ;
733
734 DefaultClause /*Qq*/
735 : "default" Q ":" StatementListOpt { $$ = new(driver.pool_) CYClause(NULL, $4); }
736 ;
737
738 LabelledStatement /*Qq*/
739 : Identifier Q ":" Q Statement { $5->AddLabel($1); $$ = $5; }
740 ;
741
742 ThrowStatement /*Q*/
743 : "throw" Expression Terminator { $$ = new(driver.pool_) CYThrow($2); }
744 ;
745
746 TryStatement /*Q*/
747 : "try" Block CatchOpt FinallyOpt { $$ = new(driver.pool_) CYTry($2, $3, $4); }
748 ;
749
750 CatchOpt
751 : Q "catch" Q "(" Q Identifier Q ")" Block { $$ = new(driver.pool_) CYCatch($6, $9); }
752 | { $$ = NULL; }
753 ;
754
755 FinallyOpt
756 : Q "finally" Block { $$ = $3; }
757 | { $$ = NULL; }
758 ;
759
760 FunctionDeclaration /*Q*/
761 : "function" Q Identifier Q "(" FormalParameterList Q ")" Q "{" FunctionBody "}" { $$ = new(driver.pool_) CYFunction($3, $6, $11); }
762 ;
763
764 FunctionExpression /*Q*/
765 : "function" QIdentifierOpt Q "(" FormalParameterList Q ")" Q "{" FunctionBody "}" { $$ = new(driver.pool_) CYLambda($2, $5, $10); }
766 ;
767
768 FormalParameterList_
769 : Q "," FormalParameterList { $$ = $3; }
770 | { $$ = NULL; }
771 ;
772
773 FormalParameterList
774 : Q Identifier FormalParameterList_ { $$ = new(driver.pool_) CYParameter($2, $3); }
775 | { $$ = NULL; }
776 ;
777
778 FunctionBody /*q*/
779 : Q SourceElements { $$ = $2; }
780 ;
781
782 Program
783 : Q SourceElements { driver.source_.push_back($2); $$ = $2; }
784 ;
785
786 SourceElements /*Qq*/
787 : SourceElement Q SourceElements { $1->SetNext($3); $$ = $1; }
788 | { $$ = NULL; }
789 ;
790
791 /*Command
792 : Q SourceElement { driver.source_.push_back($2); if (driver.filename_.empty() && false) YYACCEPT; $2->Show(std::cout); }
793 ;*/
794
795 SourceElement /*Qq*/
796 : Statement { $$ = $1; }
797 | FunctionDeclaration Q { $$ = $1; }
798 ;
799
800 %%