source: EcnlProtoTool/trunk/webapp/webmrbc/mrb_parse.jay

Last change on this file was 430, checked in by coas-nagasima, 4 years ago

RubyパーサーとYaccを更新(変化なし)

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/plain;charset=UTF-8
File size: 72.1 KB
Line 
1/*
2** parse.y - mruby parser
3**
4** See Copyright Notice in mruby.h
5*/
6
7%{
8// can first specify namespace
9// could specify using directives
10// [this has not been done here to stress-test the skeleton]
11using System;
12using System.Collections.Generic;
13using System.Text.RegularExpressions;
14using Bridge;
15using Bridge.Html5;
16
17namespace WebMrbc
18{
19 public enum MrbTokens
20 {
21%}
22
23%token <int>
24 keyword_class
25 keyword_module
26 keyword_def
27 keyword_begin
28 keyword_if
29 keyword_unless
30 keyword_while
31 keyword_until
32 keyword_for
33
34%token
35 keyword_undef
36 keyword_rescue
37 keyword_ensure
38 keyword_end
39 keyword_then
40 keyword_elsif
41 keyword_else
42 keyword_case
43 keyword_when
44 keyword_break
45 keyword_next
46 keyword_redo
47 keyword_retry
48 keyword_in
49 keyword_do
50 keyword_do_cond
51 keyword_do_block
52 keyword_do_LAMBDA
53 keyword_return
54 keyword_yield
55 keyword_super
56 keyword_self
57 keyword_nil
58 keyword_true
59 keyword_false
60 keyword_and
61 keyword_or
62 keyword_not
63 modifier_if
64 modifier_unless
65 modifier_while
66 modifier_until
67 modifier_rescue
68 keyword_alias
69 keyword_BEGIN
70 keyword_END
71 keyword__LINE__
72 keyword__FILE__
73 keyword__ENCODING__
74
75%token <mrb_sym> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tLABEL
76%token <node> tINTEGER tFLOAT tCHAR tXSTRING tREGEXP
77%token <node> tSTRING tSTRING_PART tSTRING_MID tLABEL_END
78%token <node> tNTH_REF tBACK_REF
79%token <int> tREGEXP_END
80
81%type <node> singleton string string_rep string_interp xstring regexp
82%type <node> literal numeric cpath symbol
83%type <node> top_compstmt top_stmts top_stmt
84%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call
85%type <node> expr_value arg_rhs primary_value
86%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure
87%type <node> args call_args opt_call_args
88%type <node> paren_args opt_paren_args variable
89%type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs
90%type <node> command_asgn command_rhs mrhs superclass block_call block_command
91%type <node> f_block_optarg f_block_opt
92%type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs
93%type <node> assoc_list assocs assoc undef_list backref for_var
94%type <node> block_param opt_block_param block_param_def f_opt
95%type <node> bv_decls opt_bv_decl bvar f_larglist lambda_body
96%type <node> brace_block cmd_brace_block do_block lhs none f_bad_arg
97%type <node> mlhs mlhs_list mlhs_post mlhs_basic mlhs_item mlhs_node mlhs_inner
98%type <mrb_sym> fsym sym basic_symbol operation operation2 operation3
99%type <mrb_sym> cname fname op f_rest_arg f_block_arg opt_f_block_arg f_norm_arg f_opt_asgn
100%type <node> heredoc words symbols
101%type <MrbTokens> call_op call_op2 /* 0:'&.', 1:'.', 2:'::' */
102
103%token tUPLUS /* unary+ */
104%token tUMINUS /* unary- */
105%token tPOW /* ** */
106%token tCMP /* <=> */
107%token tEQ /* == */
108%token tEQQ /* === */
109%token tNEQ /* != */
110%token tGEQ /* >= */
111%token tLEQ /* <= */
112%token tANDOP tOROP /* && and || */
113%token tMATCH tNMATCH /* =~ and !~ */
114%token tDOT2 tDOT3 /* .. and ... */
115%token tAREF tASET /* [] and []= */
116%token tLSHFT tRSHFT /* << and >> */
117%token tCOLON2 /* :: */
118%token tCOLON3 /* :: at EXPR_BEG */
119%token <mrb_sym> tOP_ASGN /* +=, -= etc. */
120%token tASSOC /* => */
121%token tLPAREN /* ( */
122%token tLPAREN_ARG /* ( */
123%token tRPAREN /* ) */
124%token tLBRACK /* [ */
125%token tLBRACE /* { */
126%token tLBRACE_ARG /* { */
127%token tSTAR /* * */
128%token tAMPER /* & */
129%token tLAMBDA /* -> */
130%token tANDDOT /* &. */
131%token tSYMBEG tREGEXP_BEG tWORDS_BEG tSYMBOLS_BEG
132%token tSTRING_BEG tXSTRING_BEG tSTRING_DVAR tLAMBEG
133%token <node> tHEREDOC_BEG /* <<, <<- */
134%token tHEREDOC_END tLITERAL_DELIM tHD_LITERAL_DELIM
135%token <node> tHD_STRING_PART tHD_STRING_MID
136
137/*
138 * precedence table
139 */
140
141%nonassoc tLOWEST
142%nonassoc tLBRACE_ARG
143
144%nonassoc modifier_if modifier_unless modifier_while modifier_until
145%left keyword_or keyword_and
146%right keyword_not
147%right '=' tOP_ASGN
148%left modifier_rescue
149%right '?' ':'
150%nonassoc tDOT2 tDOT3
151%left tOROP
152%left tANDOP
153%nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
154%left '>' tGEQ '<' tLEQ
155%left '|' '^'
156%left '&'
157%left tLSHFT tRSHFT
158%left '+' '-'
159%left '*' '/' '%'
160%right tUMINUS_NUM tUMINUS
161%right tPOW
162%right '!' '~' tUPLUS
163
164%token tLAST_TOKEN
165
166%%
167
168%{
169 }
170
171 /// <summary>
172 /// start with an argument to trace
173 /// </summary>
174 public partial class MrbParser
175 {
176 // must specify class header
177 // must not use yy[A-Z].* as identifiers
178 // could overwrite some methods named yy[A-Z].* in subclass
179
180 const int yyErrorCode = (int)MrbTokens.yyErrorCode;
181%}
182
183program : {
184 this.lstate = mrb_lex_state_enum.EXPR_BEG;
185 if (this.locals == null) this.locals = new locals_node(null);
186 }
187 top_compstmt
188 {
189 this.tree = new_scope($2);
190 this.tree.NODE_LINENO($2);
191 }
192 ;
193
194top_compstmt : top_stmts opt_terms
195 {
196 $$ = $1;
197 }
198 ;
199
200top_stmts : none
201 {
202 $$ = new_begin(null);
203 }
204 | top_stmt
205 {
206 $$ = new_begin($1);
207 $<node>$.NODE_LINENO($1);
208 }
209 | top_stmts terms top_stmt
210 {
211 $$ = push($1, newline_node($3));
212 }
213 | error top_stmt
214 {
215 $$ = new_begin(null);
216 }
217 ;
218
219top_stmt : stmt
220 | keyword_BEGIN
221 {
222 $$ = local_switch();
223 }
224 '{' top_compstmt '}'
225 {
226 yyError("BEGIN not supported");
227 local_resume($<locals_node>2);
228 $$ = null;
229 }
230 ;
231
232bodystmt : compstmt
233 opt_rescue
234 opt_else
235 opt_ensure
236 {
237 if ($2 != null) {
238 $$ = new_rescue($1, $2, $3);
239 $<node>$.NODE_LINENO($1);
240 }
241 else if ($3 != null) {
242 yyWarning("else without rescue is useless");
243 $$ = push($1, $3);
244 }
245 else {
246 $$ = $1;
247 }
248 if ($4 != null) {
249 if ($$ != null) {
250 $$ = new_ensure($<node>$, $4);
251 }
252 else {
253 $$ = push($4, new_nil());
254 }
255 }
256 }
257 ;
258
259compstmt : stmts opt_terms
260 {
261 $$ = $1;
262 }
263 ;
264
265stmts : none
266 {
267 $$ = new_begin(null);
268 }
269 | stmt
270 {
271 $$ = new_begin($1);
272 $<node>$.NODE_LINENO($1);
273 }
274 | stmts terms stmt
275 {
276 $$ = push($1, newline_node($3));
277 }
278 | error stmt
279 {
280 $$ = new_begin($2);
281 }
282 ;
283
284stmt : keyword_alias fsym {this.lstate = mrb_lex_state_enum.EXPR_FNAME;} fsym
285 {
286 $$ = new_alias($2, $4);
287 }
288 | keyword_undef undef_list
289 {
290 $$ = $2;
291 }
292 | stmt modifier_if expr_value
293 {
294 $$ = new_if(cond($3), $1, null);
295 }
296 | stmt modifier_unless expr_value
297 {
298 $$ = new_unless(cond($3), $1, null);
299 }
300 | stmt modifier_while expr_value
301 {
302 $$ = new_while(cond($3), $1);
303 }
304 | stmt modifier_until expr_value
305 {
306 $$ = new_until(cond($3), $1);
307 }
308 | stmt modifier_rescue stmt
309 {
310 $$ = new_mod_rescue($1, $3);
311 }
312 | keyword_END '{' compstmt '}'
313 {
314 yyError("END not supported");
315 $$ = new_postexe($3);
316 }
317 | command_asgn
318 | mlhs '=' command_call
319 {
320 $$ = new_masgn($1, $3);
321 }
322 | lhs '=' mrhs
323 {
324 $$ = new_asgn($1, new_array($3));
325 }
326 | mlhs '=' arg
327 {
328 $$ = new_masgn($1, $3);
329 }
330 | mlhs '=' mrhs
331 {
332 $$ = new_masgn($1, new_array($3));
333 }
334 | expr
335 ;
336
337command_asgn : lhs '=' command_rhs
338 {
339 $$ = new_asgn($1, $3);
340 }
341 | var_lhs tOP_ASGN command_rhs
342 {
343 $$ = new_op_asgn($1, $2, $3);
344 }
345 | primary_value '[' opt_call_args rbracket tOP_ASGN command_rhs
346 {
347 $$ = new_op_asgn(new_call($1, intern("[]",2), $3, (MrbTokens)'.'), $5, $6);
348 }
349 | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
350 {
351 $$ = new_op_asgn(new_call($1, $3, null, $2), $4, $5);
352 }
353 | primary_value call_op tCONSTANT tOP_ASGN command_rhs
354 {
355 $$ = new_op_asgn(new_call($1, $3, null, $2), $4, $5);
356 }
357 | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
358 {
359 yyError("constant re-assignment");
360 $$ = null;
361 }
362 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
363 {
364 $$ = new_op_asgn(new_call($1, $3, null, MrbTokens.tCOLON2), $4, $5);
365 }
366 | backref tOP_ASGN command_rhs
367 {
368 backref_error($1);
369 $$ = new_begin(null);
370 }
371 ;
372
373command_rhs : command_call %prec tOP_ASGN
374 | command_call modifier_rescue stmt
375 {
376 $$ = new_mod_rescue($1, $3);
377 }
378 | command_asgn
379 ;
380
381
382expr : command_call
383 | expr keyword_and expr
384 {
385 $$ = new_and($1, $3);
386 }
387 | expr keyword_or expr
388 {
389 $$ = new_or($1, $3);
390 }
391 | keyword_not opt_nl expr
392 {
393 $$ = call_uni_op(cond($3), "!");
394 }
395 | '!' command_call
396 {
397 $$ = call_uni_op(cond($2), "!");
398 }
399 | arg
400 ;
401
402expr_value : expr
403 {
404 if ($1 == null) $$ = new_nil();
405 else{
406 $$ = $1;
407 }
408 }
409 ;
410
411command_call : command
412 | block_command
413 ;
414
415block_command : block_call
416 | block_call call_op2 operation2 command_args
417 {
418 $$ = new_call($1, $3, $4, $2);
419 }
420 ;
421
422cmd_brace_block : tLBRACE_ARG
423 {
424 local_nest();
425 }
426 opt_block_param
427 compstmt
428 '}'
429 {
430 $$ = new_block($3, $4, true);
431 local_unnest();
432 }
433 ;
434
435command : operation command_args %prec tLOWEST
436 {
437 $$ = new_fcall($1, $2);
438 }
439 | operation command_args cmd_brace_block
440 {
441 args_with_block($2, $3);
442 $$ = new_fcall($1, $2);
443 }
444 | primary_value call_op operation2 command_args %prec tLOWEST
445 {
446 $$ = new_call($1, $3, $4, $2);
447 }
448 | primary_value call_op operation2 command_args cmd_brace_block
449 {
450 args_with_block($4, $5);
451 $$ = new_call($1, $3, $4, $2);
452 }
453 | primary_value tCOLON2 operation2 command_args %prec tLOWEST
454 {
455 $$ = new_call($1, $3, $4, MrbTokens.tCOLON2);
456 }
457 | primary_value tCOLON2 operation2 command_args cmd_brace_block
458 {
459 args_with_block($4, $5);
460 $$ = new_call($1, $3, $4, MrbTokens.tCOLON2);
461 }
462 | keyword_super command_args
463 {
464 $$ = new_super($2);
465 }
466 | keyword_yield command_args
467 {
468 $$ = new_yield($2);
469 }
470 | keyword_return call_args
471 {
472 $$ = new_return(ret_args($2));
473 }
474 | keyword_break call_args
475 {
476 $$ = new_break(ret_args($2));
477 }
478 | keyword_next call_args
479 {
480 $$ = new_next(ret_args($2));
481 }
482 ;
483
484mlhs : mlhs_basic
485 {
486 $$ = $1;
487 }
488 | tLPAREN mlhs_inner rparen
489 {
490 $$ = $2;
491 }
492 ;
493
494mlhs_inner : mlhs_basic
495 | tLPAREN mlhs_inner rparen
496 {
497 $$ = $2;
498 }
499 ;
500
501mlhs_basic : mlhs_list
502 {
503 $$ = list1($1);
504 }
505 | mlhs_list mlhs_item
506 {
507 $$ = list1(push($1, $2));
508 }
509 | mlhs_list tSTAR mlhs_node
510 {
511 $$ = list2($1, $3);
512 }
513 | mlhs_list tSTAR mlhs_node ',' mlhs_post
514 {
515 $$ = list3($1, $3, $5);
516 }
517 | mlhs_list tSTAR
518 {
519 $$ = list2($1, new_nil());
520 }
521 | mlhs_list tSTAR ',' mlhs_post
522 {
523 $$ = list3($1, new_nil(), $4);
524 }
525 | tSTAR mlhs_node
526 {
527 $$ = list2(null, $2);
528 }
529 | tSTAR mlhs_node ',' mlhs_post
530 {
531 $$ = list3(null, $2, $4);
532 }
533 | tSTAR
534 {
535 $$ = list2(null, new_nil());
536 }
537 | tSTAR ',' mlhs_post
538 {
539 $$ = list3(null, new_nil(), $3);
540 }
541 ;
542
543mlhs_item : mlhs_node
544 | tLPAREN mlhs_inner rparen
545 {
546 $$ = new_masgn($2, null);
547 }
548 ;
549
550mlhs_list : mlhs_item ','
551 {
552 $$ = list1($1);
553 }
554 | mlhs_list mlhs_item ','
555 {
556 $$ = push($1, $2);
557 }
558 ;
559
560mlhs_post : mlhs_item
561 {
562 $$ = list1($1);
563 }
564 | mlhs_list mlhs_item
565 {
566 $$ = push($1, $2);
567 }
568 ;
569
570mlhs_node : variable
571 {
572 assignable($1);
573 }
574 | primary_value '[' opt_call_args rbracket
575 {
576 $$ = new_call($1, intern("[]",2), $3, (MrbTokens)'.');
577 }
578 | primary_value call_op tIDENTIFIER
579 {
580 $$ = new_call($1, $3, null, $2);
581 }
582 | primary_value tCOLON2 tIDENTIFIER
583 {
584 $$ = new_call($1, $3, null, MrbTokens.tCOLON2);
585 }
586 | primary_value call_op tCONSTANT
587 {
588 $$ = new_call($1, $3, null, $2);
589 }
590 | primary_value tCOLON2 tCONSTANT
591 {
592 if (this.in_def != 0 || this.in_single != 0)
593 yyError("dynamic constant assignment");
594 $$ = new_colon2($1, $3);
595 }
596 | tCOLON3 tCONSTANT
597 {
598 if (this.in_def != 0 || this.in_single != 0)
599 yyError("dynamic constant assignment");
600 $$ = new_colon3($2);
601 }
602 | backref
603 {
604 backref_error($1);
605 $$ = null;
606 }
607 ;
608
609lhs : variable
610 {
611 assignable($1);
612 }
613 | primary_value '[' opt_call_args rbracket
614 {
615 $$ = new_call($1, intern("[]",2), $3, (MrbTokens)'.');
616 }
617 | primary_value call_op tIDENTIFIER
618 {
619 $$ = new_call($1, $3, null, $2);
620 }
621 | primary_value tCOLON2 tIDENTIFIER
622 {
623 $$ = new_call($1, $3, null, MrbTokens.tCOLON2);
624 }
625 | primary_value call_op tCONSTANT
626 {
627 $$ = new_call($1, $3, null, $2);
628 }
629 | primary_value tCOLON2 tCONSTANT
630 {
631 if (this.in_def != 0 || this.in_single != 0)
632 yyError("dynamic constant assignment");
633 $$ = new_colon2($1, $3);
634 }
635 | tCOLON3 tCONSTANT
636 {
637 if (this.in_def != 0 || this.in_single != 0)
638 yyError("dynamic constant assignment");
639 $$ = new_colon3($2);
640 }
641 | backref
642 {
643 backref_error($1);
644 $$ = null;
645 }
646 ;
647
648cname : tIDENTIFIER
649 {
650 yyError("class/module name must be CONSTANT");
651 }
652 | tCONSTANT
653 ;
654
655cpath : tCOLON3 cname
656 {
657 $$ = cons(1, $2);
658 }
659 | cname
660 {
661 $$ = cons(0, $1);
662 }
663 | primary_value tCOLON2 cname
664 {
665 void_expr_error($1);
666 $$ = cons($1, $3);
667 }
668 ;
669
670fname : tIDENTIFIER
671 | tCONSTANT
672 | tFID
673 | op
674 {
675 this.lstate = mrb_lex_state_enum.EXPR_ENDFN;
676 $$ = $1;
677 }
678 | reswords
679 {
680 this.lstate = mrb_lex_state_enum.EXPR_ENDFN;
681 $$ = $<mrb_sym>1;
682 }
683 ;
684
685fsym : fname
686 | basic_symbol
687 ;
688
689undef_list : fsym
690 {
691 $$ = new_undef($1);
692 }
693 | undef_list ',' {this.lstate = mrb_lex_state_enum.EXPR_FNAME;} fsym
694 {
695 $$ = push($1, $4);
696 }
697 ;
698
699op : '|' { $$ = intern_c('|'); }
700 | '^' { $$ = intern_c('^'); }
701 | '&' { $$ = intern_c('&'); }
702 | tCMP { $$ = intern("<=>",3); }
703 | tEQ { $$ = intern("==",2); }
704 | tEQQ { $$ = intern("===",3); }
705 | tMATCH { $$ = intern("=~",2); }
706 | tNMATCH { $$ = intern("!~",2); }
707 | '>' { $$ = intern_c('>'); }
708 | tGEQ { $$ = intern(">=",2); }
709 | '<' { $$ = intern_c('<'); }
710 | tLEQ { $$ = intern("<=",2); }
711 | tNEQ { $$ = intern("!=",2); }
712 | tLSHFT { $$ = intern("<<",2); }
713 | tRSHFT { $$ = intern(">>",2); }
714 | '+' { $$ = intern_c('+'); }
715 | '-' { $$ = intern_c('-'); }
716 | '*' { $$ = intern_c('*'); }
717 | tSTAR { $$ = intern_c('*'); }
718 | '/' { $$ = intern_c('/'); }
719 | '%' { $$ = intern_c('%'); }
720 | tPOW { $$ = intern("**",2); }
721 | '!' { $$ = intern_c('!'); }
722 | '~' { $$ = intern_c('~'); }
723 | tUPLUS { $$ = intern("+@",2); }
724 | tUMINUS { $$ = intern("-@",2); }
725 | tAREF { $$ = intern("[]",2); }
726 | tASET { $$ = intern("[]=",3); }
727 | '`' { $$ = intern_c('`'); }
728 ;
729
730reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
731 | keyword_BEGIN | keyword_END
732 | keyword_alias | keyword_and | keyword_begin
733 | keyword_break | keyword_case | keyword_class | keyword_def
734 | keyword_do | keyword_else | keyword_elsif
735 | keyword_end | keyword_ensure | keyword_false
736 | keyword_for | keyword_in | keyword_module | keyword_next
737 | keyword_nil | keyword_not | keyword_or | keyword_redo
738 | keyword_rescue | keyword_retry | keyword_return | keyword_self
739 | keyword_super | keyword_then | keyword_true | keyword_undef
740 | keyword_when | keyword_yield | keyword_if | keyword_unless
741 | keyword_while | keyword_until
742 ;
743
744arg : lhs '=' arg_rhs
745 {
746 $$ = new_asgn($1, $3);
747 }
748 | var_lhs tOP_ASGN arg_rhs
749 {
750 $$ = new_op_asgn($1, $2, $3);
751 }
752 | primary_value '[' opt_call_args rbracket tOP_ASGN arg_rhs
753 {
754 $$ = new_op_asgn(new_call($1, intern("[]",2), $3, (MrbTokens)'.'), $5, $6);
755 }
756 | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
757 {
758 $$ = new_op_asgn(new_call($1, $3, null, $2), $4, $5);
759 }
760 | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
761 {
762 $$ = new_op_asgn(new_call($1, $3, null, $2), $4, $5);
763 }
764 | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
765 {
766 $$ = new_op_asgn(new_call($1, $3, null, MrbTokens.tCOLON2), $4, $5);
767 }
768 | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
769 {
770 yyError("constant re-assignment");
771 $$ = new_begin(null);
772 }
773 | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
774 {
775 yyError("constant re-assignment");
776 $$ = new_begin(null);
777 }
778 | backref tOP_ASGN arg_rhs
779 {
780 backref_error($1);
781 $$ = new_begin(null);
782 }
783 | arg tDOT2 arg
784 {
785 $$ = new_dot2($1, $3);
786 }
787 | arg tDOT3 arg
788 {
789 $$ = new_dot3($1, $3);
790 }
791 | arg '+' arg
792 {
793 $$ = call_bin_op($1, "+", $3);
794 }
795 | arg '-' arg
796 {
797 $$ = call_bin_op($1, "-", $3);
798 }
799 | arg '*' arg
800 {
801 $$ = call_bin_op($1, "*", $3);
802 }
803 | arg '/' arg
804 {
805 $$ = call_bin_op($1, "/", $3);
806 }
807 | arg '%' arg
808 {
809 $$ = call_bin_op($1, "%", $3);
810 }
811 | arg tPOW arg
812 {
813 $$ = call_bin_op($1, "**", $3);
814 }
815 | tUMINUS_NUM tINTEGER tPOW arg
816 {
817 $$ = call_uni_op(call_bin_op($2, "**", $4), "-@");
818 }
819 | tUMINUS_NUM tFLOAT tPOW arg
820 {
821 $$ = call_uni_op(call_bin_op($2, "**", $4), "-@");
822 }
823 | tUPLUS arg
824 {
825 $$ = call_uni_op($2, "+@");
826 }
827 | tUMINUS arg
828 {
829 $$ = call_uni_op($2, "-@");
830 }
831 | arg '|' arg
832 {
833 $$ = call_bin_op($1, "|", $3);
834 }
835 | arg '^' arg
836 {
837 $$ = call_bin_op($1, "^", $3);
838 }
839 | arg '&' arg
840 {
841 $$ = call_bin_op($1, "&", $3);
842 }
843 | arg tCMP arg
844 {
845 $$ = call_bin_op($1, "<=>", $3);
846 }
847 | arg '>' arg
848 {
849 $$ = call_bin_op($1, ">", $3);
850 }
851 | arg tGEQ arg
852 {
853 $$ = call_bin_op($1, ">=", $3);
854 }
855 | arg '<' arg
856 {
857 $$ = call_bin_op($1, "<", $3);
858 }
859 | arg tLEQ arg
860 {
861 $$ = call_bin_op($1, "<=", $3);
862 }
863 | arg tEQ arg
864 {
865 $$ = call_bin_op($1, "==", $3);
866 }
867 | arg tEQQ arg
868 {
869 $$ = call_bin_op($1, "===", $3);
870 }
871 | arg tNEQ arg
872 {
873 $$ = call_bin_op($1, "!=", $3);
874 }
875 | arg tMATCH arg
876 {
877 $$ = call_bin_op($1, "=~", $3);
878 }
879 | arg tNMATCH arg
880 {
881 $$ = call_bin_op($1, "!~", $3);
882 }
883 | '!' arg
884 {
885 $$ = call_uni_op(cond($2), "!");
886 }
887 | '~' arg
888 {
889 $$ = call_uni_op(cond($2), "~");
890 }
891 | arg tLSHFT arg
892 {
893 $$ = call_bin_op($1, "<<", $3);
894 }
895 | arg tRSHFT arg
896 {
897 $$ = call_bin_op($1, ">>", $3);
898 }
899 | arg tANDOP arg
900 {
901 $$ = new_and($1, $3);
902 }
903 | arg tOROP arg
904 {
905 $$ = new_or($1, $3);
906 }
907 | arg '?' arg opt_nl ':' arg
908 {
909 $$ = new_if(cond($1), $3, $6, true);
910 }
911 | primary
912 {
913 $$ = $1;
914 }
915 ;
916
917aref_args : none
918 | args trailer
919 {
920 $$ = $1;
921 $<node>$.NODE_LINENO($1);
922 }
923 | args comma assocs trailer
924 {
925 $$ = push($1, new_hash($3));
926 }
927 | assocs trailer
928 {
929 $$ = cons(new_hash($1), null);
930 $<node>$.NODE_LINENO($1);
931 }
932 ;
933
934arg_rhs : arg %prec tOP_ASGN
935 {
936 $$ = $1;
937 }
938 | arg modifier_rescue arg
939 {
940 void_expr_error($1);
941 void_expr_error($3);
942 $$ = new_mod_rescue($1, $3);
943 }
944 ;
945
946paren_args : '(' opt_call_args rparen
947 {
948 $$ = $2;
949 }
950 ;
951
952opt_paren_args : none
953 | paren_args
954 ;
955
956opt_call_args : none
957 | call_args
958 | args ','
959 {
960 $$ = cons($1, null);
961 $<node>$.NODE_LINENO($1);
962 }
963 | args comma assocs ','
964 {
965 $$ = cons(push($1, new_hash($3)), null);
966 $<node>$.NODE_LINENO($1);
967 }
968 | assocs ','
969 {
970 $$ = cons(list1(new_hash($1)), null);
971 $<node>$.NODE_LINENO($1);
972 }
973 ;
974
975call_args : command
976 {
977 void_expr_error($1);
978 $$ = cons(list1($1), null);
979 $<node>$.NODE_LINENO($1);
980 }
981 | args opt_block_arg
982 {
983 $$ = cons($1, $2);
984 $<node>$.NODE_LINENO($1);
985 }
986 | assocs opt_block_arg
987 {
988 $$ = cons(list1(new_hash($1)), $2);
989 $<node>$.NODE_LINENO($1);
990 }
991 | args comma assocs opt_block_arg
992 {
993 $$ = cons(push($1, new_hash($3)), $4);
994 $<node>$.NODE_LINENO($1);
995 }
996 | block_arg
997 {
998 $$ = cons(null, $1);
999 $<node>$.NODE_LINENO($1);
1000 }
1001 ;
1002
1003command_args : {
1004 $$ = (stack_type)this.cmdarg_stack;
1005 CMDARG_PUSH(1);
1006 }
1007 call_args
1008 {
1009 this.cmdarg_stack = $<stack_type>1;
1010 $$ = $2;
1011 }
1012 ;
1013
1014block_arg : tAMPER arg
1015 {
1016 $$ = new_block_arg((node)$2);
1017 }
1018 ;
1019
1020opt_block_arg : comma block_arg
1021 {
1022 $$ = $2;
1023 }
1024 | none
1025 {
1026 $$ = null;
1027 }
1028 ;
1029
1030comma : ','
1031 | ',' heredoc_bodies
1032 ;
1033
1034args : arg
1035 {
1036 void_expr_error($1);
1037 $$ = cons($1, null);
1038 $<node>$.NODE_LINENO($1);
1039 }
1040 | tSTAR arg
1041 {
1042 void_expr_error($2);
1043 $$ = cons(new_splat($2), null);
1044 $<node>$.NODE_LINENO($2);
1045 }
1046 | args comma arg
1047 {
1048 void_expr_error($3);
1049 $$ = push($1, $3);
1050 }
1051 | args comma tSTAR arg
1052 {
1053 void_expr_error($4);
1054 $$ = push($1, new_splat($4));
1055 }
1056 ;
1057
1058mrhs : args comma arg
1059 {
1060 void_expr_error($3);
1061 $$ = push($1, $3);
1062 }
1063 | args comma tSTAR arg
1064 {
1065 void_expr_error($4);
1066 $$ = push($1, new_splat($4));
1067 }
1068 | tSTAR arg
1069 {
1070 void_expr_error($2);
1071 $$ = list1(new_splat($2));
1072 }
1073 ;
1074
1075primary : literal
1076 | string
1077 | xstring
1078 | regexp
1079 | heredoc
1080 | var_ref
1081 | backref
1082 | tFID
1083 {
1084 $$ = new_fcall($1, null);
1085 }
1086 | keyword_begin
1087 {
1088 $$ = (stack_type)this.cmdarg_stack;
1089 this.cmdarg_stack = 0;
1090 }
1091 bodystmt
1092 keyword_end
1093 {
1094 this.cmdarg_stack = $<stack_type>2;
1095 $$ = $3;
1096 }
1097 | tLPAREN_ARG
1098 {
1099 $$ = (stack_type)this.cmdarg_stack;
1100 this.cmdarg_stack = 0;
1101 }
1102 stmt {this.lstate = mrb_lex_state_enum.EXPR_ENDARG;} rparen
1103 {
1104 this.cmdarg_stack = $<stack_type>2;
1105 $$ = $3;
1106 }
1107 | tLPAREN_ARG {this.lstate = mrb_lex_state_enum.EXPR_ENDARG;} rparen
1108 {
1109 $$ = new_nil();
1110 }
1111 | tLPAREN compstmt ')'
1112 {
1113 $$ = $2;
1114 }
1115 | primary_value tCOLON2 tCONSTANT
1116 {
1117 $$ = new_colon2($1, $3);
1118 }
1119 | tCOLON3 tCONSTANT
1120 {
1121 $$ = new_colon3($2);
1122 }
1123 | tLBRACK aref_args ']'
1124 {
1125 $$ = new_array($2);
1126 $<node>$.NODE_LINENO($2);
1127 }
1128 | tLBRACE assoc_list '}'
1129 {
1130 $$ = new_hash($2);
1131 $<node>$.NODE_LINENO($2);
1132 }
1133 | keyword_return
1134 {
1135 $$ = new_return(null);
1136 }
1137 | keyword_yield opt_paren_args
1138 {
1139 $$ = new_yield($2);
1140 }
1141 | keyword_not '(' expr rparen
1142 {
1143 $$ = call_uni_op(cond($3), "!");
1144 }
1145 | keyword_not '(' rparen
1146 {
1147 $$ = call_uni_op(new_nil(), "!");
1148 }
1149 | operation brace_block
1150 {
1151 $$ = new_fcall($1, cons(null, $2));
1152 }
1153 | method_call
1154 | method_call brace_block
1155 {
1156 call_with_block($1, $2);
1157 $$ = $1;
1158 }
1159 | tLAMBDA
1160 {
1161 local_nest();
1162 $$ = (int)this.lpar_beg;
1163 this.lpar_beg = ++this.paren_nest;
1164 }
1165 f_larglist
1166 {
1167 $$ = (stack_type)this.cmdarg_stack;
1168 this.cmdarg_stack = 0;
1169 }
1170 lambda_body
1171 {
1172 this.lpar_beg = $<int>2;
1173 $$ = new_lambda($3, $5);
1174 local_unnest();
1175 this.cmdarg_stack = $<stack_type>4;
1176 CMDARG_LEXPOP();
1177 }
1178 | keyword_if expr_value then
1179 compstmt
1180 if_tail
1181 keyword_end
1182 {
1183 $$ = new_if(cond($2), $4, $5);
1184 $<node>$.SET_LINENO($1);
1185 }
1186 | keyword_unless expr_value then
1187 compstmt
1188 opt_else
1189 keyword_end
1190 {
1191 $$ = new_unless(cond($2), $4, $5);
1192 $<node>$.SET_LINENO($1);
1193 }
1194 | keyword_while {COND_PUSH(1);} expr_value do {COND_POP();}
1195 compstmt
1196 keyword_end
1197 {
1198 $$ = new_while(cond($3), $6);
1199 $<node>$.SET_LINENO($1);
1200 }
1201 | keyword_until {COND_PUSH(1);} expr_value do {COND_POP();}
1202 compstmt
1203 keyword_end
1204 {
1205 $$ = new_until(cond($3), $6);
1206 $<node>$.SET_LINENO($1);
1207 }
1208 | keyword_case expr_value opt_terms
1209 case_body
1210 keyword_end
1211 {
1212 $$ = new_case($2, $4);
1213 }
1214 | keyword_case opt_terms case_body keyword_end
1215 {
1216 $$ = new_case(null, $3);
1217 }
1218 | keyword_for for_var keyword_in
1219 {COND_PUSH(1);}
1220 expr_value do
1221 {COND_POP();}
1222 compstmt
1223 keyword_end
1224 {
1225 $$ = new_for($2, $5, $8);
1226 $<node>$.SET_LINENO($1);
1227 }
1228 | keyword_class
1229 cpath superclass
1230 {
1231 if (this.in_def != 0 || this.in_single != 0)
1232 yyError("class definition in method body");
1233 $$ = local_switch();
1234 }
1235 bodystmt
1236 keyword_end
1237 {
1238 $$ = new_class($2, $3, $5);
1239 $<node>$.SET_LINENO($1);
1240 local_resume($<locals_node>4);
1241 }
1242 | keyword_class
1243 tLSHFT expr
1244 {
1245 $$ = (int)this.in_def;
1246 this.in_def = 0;
1247 }
1248 term
1249 {
1250 $$ = cons(local_switch(), this.in_single);
1251 this.in_single = 0;
1252 }
1253 bodystmt
1254 keyword_end
1255 {
1256 $$ = new_sclass($3, $7);
1257 $<node>$.SET_LINENO($1);
1258 local_resume((locals_node)$<node>6.car);
1259 this.in_def = $<int>4;
1260 this.in_single = (int)($<node>6.cdr);
1261 }
1262 | keyword_module
1263 cpath
1264 {
1265 if (this.in_def != 0 || this.in_single != 0)
1266 yyError("module definition in method body");
1267 $$ = local_switch();
1268 }
1269 bodystmt
1270 keyword_end
1271 {
1272 $$ = new_module($2, $4);
1273 $<node>$.SET_LINENO($1);
1274 local_resume($<locals_node>3);
1275 }
1276 | keyword_def fname
1277 {
1278 $$ = (stack_type)this.cmdarg_stack;
1279 this.cmdarg_stack = 0;
1280 }
1281 {
1282 this.in_def++;
1283 $$ = local_switch();
1284 }
1285 f_arglist
1286 bodystmt
1287 keyword_end
1288 {
1289 $$ = new_def($2, $5, $6);
1290 $<node>$.SET_LINENO($1);
1291 local_resume($<locals_node>4);
1292 this.in_def--;
1293 this.cmdarg_stack = $<stack_type>3;
1294 }
1295 | keyword_def singleton dot_or_colon
1296 {
1297 this.lstate = mrb_lex_state_enum.EXPR_FNAME;
1298 $$ = (stack_type)this.cmdarg_stack;
1299 this.cmdarg_stack = 0;
1300 }
1301 fname
1302 {
1303 this.in_single++;
1304 this.lstate = mrb_lex_state_enum.EXPR_ENDFN; /* force for args */
1305 $$ = local_switch();
1306 }
1307 f_arglist
1308 bodystmt
1309 keyword_end
1310 {
1311 $$ = new_sdef($2, $5, $7, $8);
1312 $<node>$.SET_LINENO($1);
1313 local_resume($<locals_node>6);
1314 this.in_single--;
1315 this.cmdarg_stack = $<stack_type>4;
1316 }
1317 | keyword_break
1318 {
1319 $$ = new_break(null);
1320 }
1321 | keyword_next
1322 {
1323 $$ = new_next(null);
1324 }
1325 | keyword_redo
1326 {
1327 $$ = new_redo();
1328 }
1329 | keyword_retry
1330 {
1331 $$ = new_retry();
1332 }
1333 ;
1334
1335primary_value : primary
1336 {
1337 $$ = $1;
1338 if ($$ == null) $$ = new_nil();
1339 }
1340 ;
1341
1342then : term
1343 | keyword_then
1344 | term keyword_then
1345 ;
1346
1347do : term
1348 | keyword_do_cond
1349 ;
1350
1351if_tail : opt_else
1352 | keyword_elsif expr_value then
1353 compstmt
1354 if_tail
1355 {
1356 $$ = new_if(cond($2), $4, $5);
1357 }
1358 ;
1359
1360opt_else : none
1361 | keyword_else compstmt
1362 {
1363 $$ = $2;
1364 }
1365 ;
1366
1367for_var : lhs
1368 {
1369 $$ = list1(list1($1));
1370 }
1371 | mlhs
1372 ;
1373
1374f_marg : f_norm_arg
1375 {
1376 $$ = new_arg($1);
1377 }
1378 | tLPAREN f_margs rparen
1379 {
1380 $$ = new_masgn($2, null);
1381 }
1382 ;
1383
1384f_marg_list : f_marg
1385 {
1386 $$ = list1($1);
1387 }
1388 | f_marg_list ',' f_marg
1389 {
1390 $$ = push($1, $3);
1391 }
1392 ;
1393
1394f_margs : f_marg_list
1395 {
1396 $$ = list3($1, null, null);
1397 }
1398 | f_marg_list ',' tSTAR f_norm_arg
1399 {
1400 $$ = list3($1, new_arg($4), null);
1401 }
1402 | f_marg_list ',' tSTAR f_norm_arg ',' f_marg_list
1403 {
1404 $$ = list3($1, new_arg($4), $6);
1405 }
1406 | f_marg_list ',' tSTAR
1407 {
1408 $$ = list3($1, -1, null);
1409 }
1410 | f_marg_list ',' tSTAR ',' f_marg_list
1411 {
1412 $$ = list3($1, -1, $5);
1413 }
1414 | tSTAR f_norm_arg
1415 {
1416 $$ = list3(null, new_arg($2), null);
1417 }
1418 | tSTAR f_norm_arg ',' f_marg_list
1419 {
1420 $$ = list3(null, new_arg($2), $4);
1421 }
1422 | tSTAR
1423 {
1424 $$ = list3(null, -1, null);
1425 }
1426 | tSTAR ',' f_marg_list
1427 {
1428 $$ = list3(null, -1, $3);
1429 }
1430 ;
1431
1432block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg
1433 {
1434 $$ = new_args($1, $3, $5, null, $6);
1435 }
1436 | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
1437 {
1438 $$ = new_args($1, $3, $5, $7, $8);
1439 }
1440 | f_arg ',' f_block_optarg opt_f_block_arg
1441 {
1442 $$ = new_args($1, $3, 0, null, $4);
1443 }
1444 | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg
1445 {
1446 $$ = new_args($1, $3, 0, $5, $6);
1447 }
1448 | f_arg ',' f_rest_arg opt_f_block_arg
1449 {
1450 $$ = new_args($1, null, $3, null, $4);
1451 }
1452 | f_arg ','
1453 {
1454 $$ = new_args($1, null, (mrb_sym)0, null, 0);
1455 }
1456 | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
1457 {
1458 $$ = new_args($1, null, $3, $5, $6);
1459 }
1460 | f_arg opt_f_block_arg
1461 {
1462 $$ = new_args($1, null, 0, null, $2);
1463 }
1464 | f_block_optarg ',' f_rest_arg opt_f_block_arg
1465 {
1466 $$ = new_args(null, $1, $3, null, $4);
1467 }
1468 | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
1469 {
1470 $$ = new_args(null, $1, $3, $5, $6);
1471 }
1472 | f_block_optarg opt_f_block_arg
1473 {
1474 $$ = new_args(null, $1, 0, null, $2);
1475 }
1476 | f_block_optarg ',' f_arg opt_f_block_arg
1477 {
1478 $$ = new_args(null, $1, 0, $3, $4);
1479 }
1480 | f_rest_arg opt_f_block_arg
1481 {
1482 $$ = new_args(null, null, $1, null, $2);
1483 }
1484 | f_rest_arg ',' f_arg opt_f_block_arg
1485 {
1486 $$ = new_args(null, null, $1, $3, $4);
1487 }
1488 | f_block_arg
1489 {
1490 $$ = new_args(null, null, 0, null, $1);
1491 }
1492 ;
1493
1494opt_block_param : none
1495 | block_param_def
1496 {
1497 this.cmd_start = true;
1498 $$ = $1;
1499 }
1500 ;
1501
1502block_param_def : '|' opt_bv_decl '|'
1503 {
1504 $$ = null;
1505 }
1506 | tOROP
1507 {
1508 $$ = null;
1509 }
1510 | '|' block_param opt_bv_decl '|'
1511 {
1512 $$ = $2;
1513 }
1514 ;
1515
1516
1517opt_bv_decl : opt_nl
1518 {
1519 $$ = null;
1520 }
1521 | opt_nl ';' bv_decls opt_nl
1522 {
1523 $$ = null;
1524 }
1525 ;
1526
1527bv_decls : bvar
1528 | bv_decls ',' bvar
1529 ;
1530
1531bvar : tIDENTIFIER
1532 {
1533 local_add_f($1);
1534 new_bv($1);
1535 }
1536 | f_bad_arg
1537 ;
1538
1539f_larglist : '(' f_args opt_bv_decl ')'
1540 {
1541 $$ = $2;
1542 }
1543 | f_args
1544 {
1545 $$ = $1;
1546 }
1547 ;
1548
1549lambda_body : tLAMBEG compstmt '}'
1550 {
1551 $$ = $2;
1552 }
1553 | keyword_do_LAMBDA compstmt keyword_end
1554 {
1555 $$ = $2;
1556 }
1557 ;
1558
1559do_block : keyword_do_block
1560 {
1561 local_nest();
1562 }
1563 opt_block_param
1564 compstmt
1565 keyword_end
1566 {
1567 $$ = new_block($3, $4, false);
1568 local_unnest();
1569 }
1570 ;
1571
1572block_call : command do_block
1573 {
1574 if ((node_type)$1.car == node_type.NODE_YIELD) {
1575 yyError("block given to yield");
1576 }
1577 else {
1578 call_with_block($1, $2);
1579 }
1580 $$ = $1;
1581 }
1582 | block_call call_op2 operation2 opt_paren_args
1583 {
1584 $$ = new_call($1, $3, $4, $2);
1585 }
1586 | block_call call_op2 operation2 opt_paren_args brace_block
1587 {
1588 $$ = new_call($1, $3, $4, $2);
1589 call_with_block((node)$$, $5);
1590 }
1591 | block_call call_op2 operation2 command_args do_block
1592 {
1593 $$ = new_call($1, $3, $4, $2);
1594 call_with_block((node)$$, $5);
1595 }
1596 ;
1597
1598method_call : operation paren_args
1599 {
1600 $$ = new_fcall($1, $2);
1601 }
1602 | primary_value call_op operation2 opt_paren_args
1603 {
1604 $$ = new_call($1, $3, $4, $2);
1605 }
1606 | primary_value tCOLON2 operation2 paren_args
1607 {
1608 $$ = new_call($1, $3, $4, MrbTokens.tCOLON2);
1609 }
1610 | primary_value tCOLON2 operation3
1611 {
1612 $$ = new_call($1, $3, null, MrbTokens.tCOLON2);
1613 }
1614 | primary_value call_op paren_args
1615 {
1616 $$ = new_call($1, intern("call",4), $3, $2);
1617 }
1618 | primary_value tCOLON2 paren_args
1619 {
1620 $$ = new_call($1, intern("call",4), $3, MrbTokens.tCOLON2);
1621 }
1622 | keyword_super paren_args
1623 {
1624 $$ = new_super($2);
1625 }
1626 | keyword_super
1627 {
1628 $$ = new_zsuper();
1629 }
1630 | primary_value '[' opt_call_args rbracket
1631 {
1632 $$ = new_call($1, intern("[]",2), $3, (MrbTokens)'.');
1633 }
1634 ;
1635
1636brace_block : '{'
1637 {
1638 local_nest();
1639 $$ = (int)this.lineno;
1640 }
1641 opt_block_param
1642 compstmt '}'
1643 {
1644 $$ = new_block($3, $4, true);
1645 $<node>$.SET_LINENO($<int>2);
1646 local_unnest();
1647 }
1648 | keyword_do
1649 {
1650 local_nest();
1651 $$ = (int)this.lineno;
1652 }
1653 opt_block_param
1654 compstmt keyword_end
1655 {
1656 $$ = new_block($3, $4, false);
1657 $<node>$.SET_LINENO($<int>2);
1658 local_unnest();
1659 }
1660 ;
1661
1662case_body : keyword_when args then
1663 compstmt
1664 cases
1665 {
1666 $$ = cons(cons($2, $4), $5);
1667 }
1668 ;
1669
1670cases : opt_else
1671 {
1672 if ($1 != null) {
1673 $$ = cons(cons(null, $1), null);
1674 }
1675 else {
1676 $$ = null;
1677 }
1678 }
1679 | case_body
1680 ;
1681
1682opt_rescue : keyword_rescue exc_list exc_var then
1683 compstmt
1684 opt_rescue
1685 {
1686 $$ = list1(list3($2, $3, $5));
1687 if ($6 != null) $$ = append($<node>$, $6);
1688 }
1689 | none
1690 ;
1691
1692exc_list : arg
1693 {
1694 $$ = list1($1);
1695 }
1696 | mrhs
1697 | none
1698 ;
1699
1700exc_var : tASSOC lhs
1701 {
1702 $$ = $2;
1703 }
1704 | none
1705 ;
1706
1707opt_ensure : keyword_ensure compstmt
1708 {
1709 $$ = $2;
1710 }
1711 | none
1712 ;
1713
1714literal : numeric
1715 | symbol
1716 | words
1717 | symbols
1718 ;
1719
1720string : tCHAR
1721 | tSTRING
1722 | tSTRING_BEG tSTRING
1723 {
1724 $$ = $2;
1725 }
1726 | tSTRING_BEG string_rep tSTRING
1727 {
1728 $$ = new_dstr(push($2, $3));
1729 }
1730 ;
1731
1732string_rep : string_interp
1733 | string_rep string_interp
1734 {
1735 $$ = append($1, $2);
1736 }
1737 ;
1738
1739string_interp : tSTRING_MID
1740 {
1741 $$ = list1($1);
1742 }
1743 | tSTRING_PART
1744 {
1745 $$ = (node)this.lex_strterm;
1746 this.lex_strterm = null;
1747 }
1748 compstmt
1749 '}'
1750 {
1751 this.lex_strterm = $<node>2;
1752 $$ = list2($1, $3);
1753 }
1754 | tLITERAL_DELIM
1755 {
1756 $$ = list1(new_literal_delim());
1757 }
1758 | tHD_LITERAL_DELIM heredoc_bodies
1759 {
1760 $$ = list1(new_literal_delim());
1761 }
1762 ;
1763
1764xstring : tXSTRING_BEG tXSTRING
1765 {
1766 $$ = $2;
1767 }
1768 | tXSTRING_BEG string_rep tXSTRING
1769 {
1770 $$ = new_dxstr(push($2, $3));
1771 }
1772 ;
1773
1774regexp : tREGEXP_BEG tREGEXP
1775 {
1776 $$ = $2;
1777 }
1778 | tREGEXP_BEG string_rep tREGEXP
1779 {
1780 $$ = new_dregx($2, $3);
1781 }
1782 ;
1783
1784heredoc : tHEREDOC_BEG
1785 ;
1786
1787heredoc_bodies : heredoc_body
1788 | heredoc_bodies heredoc_body
1789 ;
1790
1791heredoc_body : tHEREDOC_END
1792 {
1793 parser_heredoc_info inf = parsing_heredoc_inf();
1794 inf.push_doc(new_str(new Uint8Array(0), 0));
1795 heredoc_end();
1796 }
1797 | heredoc_string_rep tHEREDOC_END
1798 {
1799 heredoc_end();
1800 }
1801 ;
1802
1803heredoc_string_rep : heredoc_string_interp
1804 | heredoc_string_rep heredoc_string_interp
1805 ;
1806
1807heredoc_string_interp : tHD_STRING_MID
1808 {
1809 parser_heredoc_info inf = parsing_heredoc_inf();
1810 inf.push_doc($1);
1811 heredoc_treat_nextline();
1812 }
1813 | tHD_STRING_PART
1814 {
1815 $$ = (node)this.lex_strterm;
1816 this.lex_strterm = null;
1817 }
1818 compstmt
1819 '}'
1820 {
1821 parser_heredoc_info inf = parsing_heredoc_inf();
1822 this.lex_strterm = $<node>2;
1823 inf.push_doc($1);
1824 inf.push_doc($3);
1825 }
1826 ;
1827
1828words : tWORDS_BEG tSTRING
1829 {
1830 $$ = new_words(list1($2));
1831 }
1832 | tWORDS_BEG string_rep tSTRING
1833 {
1834 $$ = new_words(push($2, $3));
1835 }
1836 ;
1837
1838
1839symbol : basic_symbol
1840 {
1841 $$ = new_sym($1);
1842 }
1843 | tSYMBEG tSTRING_BEG string_rep tSTRING
1844 {
1845 this.lstate = mrb_lex_state_enum.EXPR_END;
1846 $$ = new_dsym(push($3, $4));
1847 }
1848 ;
1849
1850basic_symbol : tSYMBEG sym
1851 {
1852 this.lstate = mrb_lex_state_enum.EXPR_END;
1853 $$ = $2;
1854 }
1855 ;
1856
1857sym : fname
1858 | tIVAR
1859 | tGVAR
1860 | tCVAR
1861 | tSTRING
1862 {
1863 $$ = new_strsym($1);
1864 }
1865 | tSTRING_BEG tSTRING
1866 {
1867 $$ = new_strsym($2);
1868 }
1869 ;
1870
1871symbols : tSYMBOLS_BEG tSTRING
1872 {
1873 $$ = new_symbols(list1($2));
1874 }
1875 | tSYMBOLS_BEG string_rep tSTRING
1876 {
1877 $$ = new_symbols(push($2, $3));
1878 }
1879 ;
1880
1881numeric : tINTEGER
1882 | tFLOAT
1883 | tUMINUS_NUM tINTEGER %prec tLOWEST
1884 {
1885 $$ = negate_lit($2);
1886 }
1887 | tUMINUS_NUM tFLOAT %prec tLOWEST
1888 {
1889 $$ = negate_lit($2);
1890 }
1891 ;
1892
1893variable : tIDENTIFIER
1894 {
1895 $$ = new_lvar($1);
1896 }
1897 | tIVAR
1898 {
1899 $$ = new_ivar($1);
1900 }
1901 | tGVAR
1902 {
1903 $$ = new_gvar($1);
1904 }
1905 | tCVAR
1906 {
1907 $$ = new_cvar($1);
1908 }
1909 | tCONSTANT
1910 {
1911 $$ = new_const($1);
1912 }
1913 ;
1914
1915var_lhs : variable
1916 {
1917 assignable($1);
1918 }
1919 ;
1920
1921var_ref : variable
1922 {
1923 $$ = var_reference($1);
1924 }
1925 | keyword_nil
1926 {
1927 $$ = new_nil();
1928 }
1929 | keyword_self
1930 {
1931 $$ = new_self();
1932 }
1933 | keyword_true
1934 {
1935 $$ = new_true();
1936 }
1937 | keyword_false
1938 {
1939 $$ = new_false();
1940 }
1941 | keyword__FILE__
1942 {
1943 if (this.filename == null) {
1944 this.mrb_parser_set_filename("(null)");
1945 }
1946 $$ = new_filename(this.filename);
1947 }
1948 | keyword__LINE__
1949 {
1950 $$ = new_lineno(this.lineno);
1951 }
1952 ;
1953
1954backref : tNTH_REF
1955 | tBACK_REF
1956 ;
1957
1958superclass : /* term */
1959 {
1960 $$ = null;
1961 }
1962 | '<'
1963 {
1964 this.lstate = mrb_lex_state_enum.EXPR_BEG;
1965 this.cmd_start = true;
1966 }
1967 expr_value term
1968 {
1969 $$ = $3;
1970 } /*
1971 | error term
1972 {
1973 yyErrorFlag = 0;
1974 $$ = null;
1975 } */
1976 ;
1977
1978f_arglist : '(' f_args rparen
1979 {
1980 $$ = $2;
1981 this.lstate = mrb_lex_state_enum.EXPR_BEG;
1982 this.cmd_start = true;
1983 }
1984 | f_args term
1985 {
1986 $$ = $1;
1987 }
1988 ;
1989
1990f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg
1991 {
1992 $$ = new_args($1, $3, $5, null, $6);
1993 }
1994 | f_arg ',' f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
1995 {
1996 $$ = new_args($1, $3, $5, $7, $8);
1997 }
1998 | f_arg ',' f_optarg opt_f_block_arg
1999 {
2000 $$ = new_args($1, $3, 0, null, $4);
2001 }
2002 | f_arg ',' f_optarg ',' f_arg opt_f_block_arg
2003 {
2004 $$ = new_args($1, $3, 0, $5, $6);
2005 }
2006 | f_arg ',' f_rest_arg opt_f_block_arg
2007 {
2008 $$ = new_args($1, null, $3, null, $4);
2009 }
2010 | f_arg ',' f_rest_arg ',' f_arg opt_f_block_arg
2011 {
2012 $$ = new_args($1, null, $3, $5, $6);
2013 }
2014 | f_arg opt_f_block_arg
2015 {
2016 $$ = new_args($1, null, 0, null, $2);
2017 }
2018 | f_optarg ',' f_rest_arg opt_f_block_arg
2019 {
2020 $$ = new_args(null, $1, $3, null, $4);
2021 }
2022 | f_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg
2023 {
2024 $$ = new_args(null, $1, $3, $5, $6);
2025 }
2026 | f_optarg opt_f_block_arg
2027 {
2028 $$ = new_args(null, $1, 0, null, $2);
2029 }
2030 | f_optarg ',' f_arg opt_f_block_arg
2031 {
2032 $$ = new_args(null, $1, 0, $3, $4);
2033 }
2034 | f_rest_arg opt_f_block_arg
2035 {
2036 $$ = new_args(null, null, $1, null, $2);
2037 }
2038 | f_rest_arg ',' f_arg opt_f_block_arg
2039 {
2040 $$ = new_args(null, null, $1, $3, $4);
2041 }
2042 | f_block_arg
2043 {
2044 $$ = new_args(null, null, 0, null, $1);
2045 }
2046 | /* none */
2047 {
2048 local_add_f(0);
2049 $$ = new_args(null, null, 0, null, 0);
2050 }
2051 ;
2052
2053f_bad_arg : tCONSTANT
2054 {
2055 yyError("formal argument cannot be a constant");
2056 $$ = null;
2057 }
2058 | tIVAR
2059 {
2060 yyError("formal argument cannot be an instance variable");
2061 $$ = null;
2062 }
2063 | tGVAR
2064 {
2065 yyError("formal argument cannot be a global variable");
2066 $$ = null;
2067 }
2068 | tCVAR
2069 {
2070 yyError("formal argument cannot be a class variable");
2071 $$ = null;
2072 }
2073 ;
2074
2075f_norm_arg : f_bad_arg
2076 {
2077 $$ = null;
2078 }
2079 | tIDENTIFIER
2080 {
2081 local_add_f($1);
2082 $$ = $1;
2083 }
2084 ;
2085
2086f_arg_item : f_norm_arg
2087 {
2088 $$ = new_arg($1);
2089 }
2090 | tLPAREN f_margs rparen
2091 {
2092 $$ = new_masgn($2, null);
2093 }
2094 ;
2095
2096f_arg : f_arg_item
2097 {
2098 $$ = list1($1);
2099 }
2100 | f_arg ',' f_arg_item
2101 {
2102 $$ = push($1, $3);
2103 }
2104 ;
2105
2106f_opt_asgn : tIDENTIFIER '='
2107 {
2108 local_add_f($1);
2109 $$ = $1;
2110 }
2111 ;
2112
2113f_opt : f_opt_asgn arg
2114 {
2115 void_expr_error($2);
2116 $$ = cons($1, $2);
2117 }
2118 ;
2119
2120f_block_opt : f_opt_asgn primary_value
2121 {
2122 void_expr_error($2);
2123 $$ = cons($1, $2);
2124 }
2125 ;
2126
2127f_block_optarg : f_block_opt
2128 {
2129 $$ = list1($1);
2130 }
2131 | f_block_optarg ',' f_block_opt
2132 {
2133 $$ = push($1, $3);
2134 }
2135 ;
2136
2137f_optarg : f_opt
2138 {
2139 $$ = list1($1);
2140 }
2141 | f_optarg ',' f_opt
2142 {
2143 $$ = push($1, $3);
2144 }
2145 ;
2146
2147restarg_mark : '*'
2148 | tSTAR
2149 ;
2150
2151f_rest_arg : restarg_mark tIDENTIFIER
2152 {
2153 local_add_f($2);
2154 $$ = $2;
2155 }
2156 | restarg_mark
2157 {
2158 local_add_f(0);
2159 $$ = -1;
2160 }
2161 ;
2162
2163blkarg_mark : '&'
2164 | tAMPER
2165 ;
2166
2167f_block_arg : blkarg_mark tIDENTIFIER
2168 {
2169 local_add_f($2);
2170 $$ = $2;
2171 }
2172 ;
2173
2174opt_f_block_arg : ',' f_block_arg
2175 {
2176 $$ = $2;
2177 }
2178 | none
2179 {
2180 local_add_f(0);
2181 $$ = 0;
2182 }
2183 ;
2184
2185singleton : var_ref
2186 {
2187 $$ = $1;
2188 if ($$ == null) $$ = new_nil();
2189 }
2190 | '(' {this.lstate = mrb_lex_state_enum.EXPR_BEG;} expr rparen
2191 {
2192 if ($<int>3 == 0) {
2193 yyError("can't define singleton method for ().");
2194 }
2195 else {
2196 switch ((node_type)($3.car)) {
2197 case node_type.NODE_STR:
2198 case node_type.NODE_DSTR:
2199 case node_type.NODE_XSTR:
2200 case node_type.NODE_DXSTR:
2201 case node_type.NODE_DREGX:
2202 case node_type.NODE_MATCH:
2203 case node_type.NODE_FLOAT:
2204 case node_type.NODE_ARRAY:
2205 case node_type.NODE_HEREDOC:
2206 yyError("can't define singleton method for literals");
2207 break;
2208 default:
2209 break;
2210 }
2211 }
2212 $$ = $3;
2213 }
2214 ;
2215
2216assoc_list : none
2217 | assocs trailer
2218 {
2219 $$ = $1;
2220 }
2221 ;
2222
2223assocs : assoc
2224 {
2225 $$ = list1($1);
2226 $<node>$.NODE_LINENO($1);
2227 }
2228 | assocs ',' assoc
2229 {
2230 $$ = push($1, $3);
2231 }
2232 ;
2233
2234assoc : arg tASSOC arg
2235 {
2236 void_expr_error($1);
2237 void_expr_error($3);
2238 $$ = cons($1, $3);
2239 }
2240 | tLABEL arg
2241 {
2242 void_expr_error($2);
2243 $$ = cons(new_sym($1), $2);
2244 }
2245 | tLABEL_END arg
2246 {
2247 void_expr_error($2);
2248 $$ = cons(new_sym(new_strsym($1)), $2);
2249 }
2250 | tSTRING_BEG tLABEL_END arg
2251 {
2252 void_expr_error($3);
2253 $$ = cons(new_sym(new_strsym($2)), $3);
2254 }
2255 | tSTRING_BEG string_rep tLABEL_END arg
2256 {
2257 void_expr_error($4);
2258 $$ = cons(new_dsym(push($2, $3)), $4);
2259 }
2260 ;
2261
2262operation : tIDENTIFIER
2263 | tCONSTANT
2264 | tFID
2265 ;
2266
2267operation2 : tIDENTIFIER
2268 | tCONSTANT
2269 | tFID
2270 | op
2271 ;
2272
2273operation3 : tIDENTIFIER
2274 | tFID
2275 | op
2276 ;
2277
2278dot_or_colon : '.'
2279 | tCOLON2
2280 ;
2281
2282call_op : '.'
2283 {
2284 $$ = (MrbTokens)'.';
2285 }
2286 | tANDDOT
2287 {
2288 $$ = (MrbTokens)0;
2289 }
2290 ;
2291
2292call_op2 : call_op
2293 | tCOLON2
2294 {
2295 $$ = MrbTokens.tCOLON2;
2296 }
2297 ;
2298
2299opt_terms : /* none */
2300 | terms
2301 ;
2302
2303opt_nl : /* none */
2304 | nl
2305 ;
2306
2307rparen : opt_nl ')'
2308 ;
2309
2310rbracket : opt_nl ']'
2311 ;
2312
2313trailer : /* none */
2314 | nl
2315 | comma
2316 ;
2317
2318term : ';' {yyErrorFlag = 0;}
2319 | nl
2320 | heredoc_body
2321 ;
2322
2323nl : '\n'
2324 {
2325 this.lineno++;
2326 this.column = 0;
2327 }
2328 ;
2329
2330terms : term
2331 | terms term
2332 ;
2333
2334none : /* none */
2335 {
2336 $$ = null;
2337 }
2338 ;
2339%%
2340
2341 } // must specify trailing } for parser class
2342} // must specify trailing } for namespace, if any
Note: See TracBrowser for help on using the repository browser.