ruby_parser 3.15.1 → 3.18.1

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ruby_parser.yy CHANGED
@@ -36,7 +36,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
36
36
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
37
37
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
38
38
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
39
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
39
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
40
40
  #if V >= 21
41
41
  tRATIONAL tIMAGINARY
42
42
  #endif
@@ -46,6 +46,9 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
46
46
  #if V >= 23
47
47
  tLONELY
48
48
  #endif
49
+ #if V >= 26
50
+ tBDOT2 tBDOT3
51
+ #endif
49
52
 
50
53
  preclow
51
54
  nonassoc tLOWEST
@@ -57,7 +60,7 @@ preclow
57
60
  right tEQL tOP_ASGN
58
61
  left kRESCUE_MOD
59
62
  right tEH tCOLON
60
- nonassoc tDOT2 tDOT3
63
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
61
64
  left tOROP
62
65
  left tANDOP
63
66
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -80,6 +83,9 @@ rule
80
83
  top_compstmt
81
84
  {
82
85
  result = new_compstmt val
86
+
87
+ lexer.cond.pop # local_pop
88
+ lexer.cmdarg.pop
83
89
  }
84
90
 
85
91
  top_compstmt: top_stmts opt_terms
@@ -100,7 +106,7 @@ rule
100
106
  | klBEGIN
101
107
  {
102
108
  if (self.in_def || self.in_single > 0) then
103
- debug20 1
109
+ debug 11
104
110
  yyerror "BEGIN in method"
105
111
  end
106
112
  self.env.extend
@@ -125,7 +131,13 @@ rule
125
131
  bodystmt: compstmt opt_rescue k_else
126
132
  {
127
133
  res = _values[-2]
134
+ # TODO: move down to main match so I can just use val
135
+
136
+ #if V >= 26
128
137
  yyerror "else without rescue is useless" unless res
138
+ #else
139
+ warn "else without rescue is useless" unless res
140
+ #endif
129
141
  }
130
142
  compstmt
131
143
  opt_ensure
@@ -155,7 +167,7 @@ rule
155
167
  | error stmt
156
168
  {
157
169
  result = val[1]
158
- debug20 2, val, result
170
+ debug 12
159
171
  }
160
172
 
161
173
  stmt_or_begin: stmt
@@ -163,6 +175,10 @@ rule
163
175
  {
164
176
  yyerror "BEGIN is permitted only at toplevel"
165
177
  }
178
+ begin_block
179
+ {
180
+ result = val[2] # wtf?
181
+ }
166
182
 
167
183
  stmt: kALIAS fitem
168
184
  {
@@ -175,12 +191,12 @@ rule
175
191
  }
176
192
  | kALIAS tGVAR tGVAR
177
193
  {
178
- (_, line), lhs, rhs = val
194
+ (_, line), (lhs, _), (rhs, _) = val
179
195
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
180
196
  }
181
197
  | kALIAS tGVAR tBACK_REF
182
198
  {
183
- (_, line), lhs, rhs = val
199
+ (_, line), (lhs, _), (rhs, _) = val
184
200
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
185
201
  }
186
202
  | kALIAS tGVAR tNTH_REF
@@ -223,7 +239,7 @@ rule
223
239
  (_, line), _, stmt, _ = val
224
240
 
225
241
  if (self.in_def || self.in_single > 0) then
226
- debug20 3
242
+ debug 13
227
243
  yyerror "END in method; use at_exit"
228
244
  end
229
245
 
@@ -244,6 +260,19 @@ rule
244
260
  {
245
261
  result = new_masgn val[0], val[2], :wrap
246
262
  }
263
+ #endif
264
+ #if V >= 27
265
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
266
+ {
267
+ # unwraps s(:to_ary, rhs)
268
+ lhs, _, (_, rhs), _, resbody = val
269
+
270
+ resbody = new_resbody s(:array).line(resbody.line), resbody
271
+
272
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
273
+ }
274
+ #endif
275
+ #if V == 20
247
276
  | mlhs tEQL mrhs
248
277
  #else
249
278
  | mlhs tEQL mrhs_arg
@@ -271,32 +300,31 @@ rule
271
300
  }
272
301
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
273
302
  {
274
- prim, _, id, opasgn, rhs = val
275
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
276
- if val[1] == '&.'
277
- result.sexp_type = :safe_op_asgn
278
- end
279
- result.line = val[0].line
303
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
304
+
305
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
306
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
307
+ result.line prim.line
280
308
  }
281
309
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
282
310
  {
283
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
284
- if val[1] == '&.'
285
- result.sexp_type = :safe_op_asgn
286
- end
287
- result.line = val[0].line
311
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
312
+
313
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
314
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
315
+ result.line prim.line
288
316
  }
289
317
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
290
318
  {
291
- lhs1, _, lhs2, op, rhs = val
319
+ lhs1, _, (lhs2, line), (id, _), rhs = val
292
320
 
293
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
321
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
294
322
  }
295
323
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
296
324
  {
297
- lhs1, _, lhs2, op, rhs = val
325
+ lhs1, _, (lhs2, line), (id, _), rhs = val
298
326
 
299
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
327
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
300
328
  }
301
329
  | backref tOP_ASGN command_rhs
302
330
  {
@@ -344,7 +372,31 @@ rule
344
372
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
345
373
  # REFACTOR: call_uni_op -- see parse26.y
346
374
  }
375
+ #if V >= 27
347
376
  | arg
377
+ kIN
378
+ {
379
+ # TODO? value_expr($1);
380
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
381
+ self.lexer.command_start = false
382
+ result = self.in_kwarg
383
+ self.in_kwarg = true
384
+ self.env.extend
385
+ }
386
+ p_expr
387
+ {
388
+ self.env.unextend
389
+
390
+ expr, _, old_kwarg, pat = val
391
+
392
+ expr = value_expr expr
393
+
394
+ self.in_kwarg = old_kwarg
395
+ pat_in = new_in pat, nil, nil, expr.line
396
+ result = new_case expr, pat_in, expr.line
397
+ }
398
+ #endif
399
+ | arg =tLBRACE_ARG
348
400
 
349
401
  expr_value: expr
350
402
  {
@@ -369,7 +421,7 @@ rule
369
421
  block_command: block_call
370
422
  | block_call call_op2 operation2 command_args
371
423
  {
372
- blk, _, msg, args = val
424
+ blk, _, (msg, _line), args = val
373
425
  result = new_call(blk, msg.to_sym, args).line blk.line
374
426
  }
375
427
 
@@ -383,15 +435,15 @@ rule
383
435
  _, line, body, _ = val
384
436
 
385
437
  result = body
386
- result.line = line
438
+ result.line line
387
439
 
388
440
  # self.env.unextend
389
441
  }
390
442
 
391
443
  fcall: operation
392
444
  {
393
- msg, = val
394
- result = new_call(nil, msg.to_sym).line lexer.lineno
445
+ (msg, line), = val
446
+ result = new_call(nil, msg.to_sym).line line
395
447
  }
396
448
 
397
449
  command: fcall command_args =tLOWEST
@@ -414,12 +466,14 @@ rule
414
466
  }
415
467
  | primary_value call_op operation2 command_args =tLOWEST
416
468
  {
417
- lhs, callop, op, args = val
469
+ lhs, callop, (op, _), args = val
470
+
418
471
  result = new_call lhs, op.to_sym, args, callop
472
+ result.line lhs.line
419
473
  }
420
474
  | primary_value call_op operation2 command_args cmd_brace_block
421
475
  {
422
- recv, _, msg, args, block = val
476
+ recv, _, (msg, _line), args, block = val
423
477
  call = new_call recv, msg.to_sym, args, val[1]
424
478
 
425
479
  block_dup_check call, block
@@ -429,11 +483,14 @@ rule
429
483
  }
430
484
  | primary_value tCOLON2 operation2 command_args =tLOWEST
431
485
  {
432
- result = new_call val[0], val[2].to_sym, val[3]
486
+ lhs, _, (id, line), args = val
487
+
488
+ result = new_call lhs, id.to_sym, args
489
+ result.line line
433
490
  }
434
491
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
435
492
  {
436
- recv, _, msg, args, block = val
493
+ recv, _, (msg, _line), args, block = val
437
494
  call = new_call recv, msg.to_sym, args
438
495
 
439
496
  block_dup_check call, block
@@ -591,25 +648,29 @@ rule
591
648
  }
592
649
  | primary_value call_op tIDENTIFIER
593
650
  {
594
- result = new_attrasgn val[0], val[2], val[1]
651
+ lhs, call_op, (id, _line) = val
652
+
653
+ result = new_attrasgn lhs, id, call_op
595
654
  }
596
655
  | primary_value tCOLON2 tIDENTIFIER
597
656
  {
598
- recv, _, id = val
657
+ recv, _, (id, _line) = val
599
658
  result = new_attrasgn recv, id
600
659
  }
601
660
  | primary_value call_op tCONSTANT
602
661
  {
603
- result = new_attrasgn val[0], val[2], val[1]
662
+ lhs, call_op, (id, _line) = val
663
+
664
+ result = new_attrasgn lhs, id, call_op
604
665
  }
605
666
  | primary_value tCOLON2 tCONSTANT
606
667
  {
607
668
  if (self.in_def || self.in_single > 0) then
608
- debug20 7
669
+ debug 14
609
670
  yyerror "dynamic constant assignment"
610
671
  end
611
672
 
612
- expr, _, id = val
673
+ expr, _, (id, _line) = val
613
674
  l = expr.line
614
675
 
615
676
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -617,58 +678,65 @@ rule
617
678
  | tCOLON3 tCONSTANT
618
679
  {
619
680
  if (self.in_def || self.in_single > 0) then
620
- debug20 8
681
+ debug 15
621
682
  yyerror "dynamic constant assignment"
622
683
  end
623
684
 
624
- _, id = val
625
- l = lexer.lineno
685
+ _, (id, l) = val
626
686
 
627
687
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
628
688
  }
629
689
  | backref
630
690
  {
631
- self.backref_assign_error val[0]
691
+ ref, = val
692
+
693
+ self.backref_assign_error ref
632
694
  }
633
695
 
634
696
  lhs: user_variable
635
697
  {
636
- line = lexer.lineno
637
- result = self.assignable val[0]
638
- result.line = line
698
+ var, = val
699
+
700
+ result = self.assignable var
639
701
  }
640
702
  | keyword_variable
641
703
  {
642
- line = lexer.lineno
643
- result = self.assignable val[0]
644
- result.line = line
645
- debug20 9, val, result
704
+ var, = val
705
+
706
+ result = self.assignable var
707
+
708
+ debug 16
646
709
  }
647
710
  | primary_value tLBRACK2 opt_call_args rbracket
648
711
  {
649
712
  lhs, _, args, _ = val
713
+
650
714
  result = self.aryset lhs, args
651
715
  }
652
716
  | primary_value call_op tIDENTIFIER # REFACTOR
653
717
  {
654
- lhs, op, id = val
718
+ lhs, op, (id, _line) = val
719
+
655
720
  result = new_attrasgn lhs, id, op
656
721
  }
657
722
  | primary_value tCOLON2 tIDENTIFIER
658
723
  {
659
- lhs, _, id = val
724
+ lhs, _, (id, _line) = val
725
+
660
726
  result = new_attrasgn lhs, id
661
727
  }
662
728
  | primary_value call_op tCONSTANT # REFACTOR?
663
729
  {
664
- result = new_attrasgn val[0], val[2], val[1]
730
+ lhs, call_op, (id, _line) = val
731
+
732
+ result = new_attrasgn lhs, id, call_op
665
733
  }
666
734
  | primary_value tCOLON2 tCONSTANT
667
735
  {
668
- expr, _, id = val
736
+ expr, _, (id, _line) = val
669
737
 
670
738
  if (self.in_def || self.in_single > 0) then
671
- debug20 10
739
+ debug 17
672
740
  yyerror "dynamic constant assignment"
673
741
  end
674
742
 
@@ -677,14 +745,13 @@ rule
677
745
  }
678
746
  | tCOLON3 tCONSTANT
679
747
  {
680
- _, id = val
748
+ _, (id, l) = val
681
749
 
682
750
  if (self.in_def || self.in_single > 0) then
683
- debug20 11
751
+ debug 18
684
752
  yyerror "dynamic constant assignment"
685
753
  end
686
754
 
687
- l = lexer.lineno
688
755
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
689
756
  }
690
757
  | backref
@@ -700,16 +767,17 @@ rule
700
767
 
701
768
  cpath: tCOLON3 cname
702
769
  {
703
- _, name = val
704
- result = s(:colon3, name.to_sym).line lexer.lineno
770
+ _, (name, line) = val
771
+ result = s(:colon3, name.to_sym).line line
705
772
  }
706
773
  | cname
707
774
  {
708
- result = val[0].to_sym
775
+ (id, line), = val
776
+ result = [id.to_sym, line] # TODO: sexp?
709
777
  }
710
778
  | primary_value tCOLON2 cname
711
779
  {
712
- pval, _, name = val
780
+ pval, _, (name, _line) = val
713
781
 
714
782
  result = s(:colon2, pval, name.to_sym)
715
783
  result.line pval.line
@@ -719,24 +787,17 @@ rule
719
787
  | op
720
788
  {
721
789
  lexer.lex_state = EXPR_END
722
- result = val[0]
723
790
  }
724
791
 
725
792
  | reswords
726
- {
727
- (sym, _line), = val
728
- lexer.lex_state = EXPR_END
729
- result = sym
730
- }
731
793
 
732
- fsym: fname | symbol
733
-
734
- fitem: fsym
794
+ fitem: fname
735
795
  {
736
- id, = val
737
- result = s(:lit, id.to_sym).line lexer.lineno
796
+ (id, line), = val
797
+
798
+ result = s(:lit, id.to_sym).line line
738
799
  }
739
- | dsym
800
+ | symbol
740
801
 
741
802
  undef_list: fitem
742
803
  {
@@ -757,10 +818,6 @@ rule
757
818
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
758
819
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
759
820
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
760
- #if V >= 20
761
- # TODO: tUBANG dead?
762
- | tUBANG
763
- #endif
764
821
 
765
822
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
766
823
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -794,24 +851,20 @@ rule
794
851
  }
795
852
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
796
853
  {
797
- lhs, _, id, op, rhs = val
854
+ lhs, _, (id, _line), (op, _), rhs = val
798
855
 
799
856
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
800
857
  }
801
858
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
802
859
  {
803
- lhs1, _, lhs2, op, rhs = val
860
+ lhs1, _, (lhs2, _line), op, rhs = val
804
861
 
805
862
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
806
863
  result = new_const_op_asgn [lhs, op, rhs]
807
864
  }
808
- | tCOLON3 tCONSTANT
809
- {
810
- result = self.lexer.lineno
811
- }
812
- tOP_ASGN arg_rhs
865
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
813
866
  {
814
- _, lhs, line, op, rhs = val
867
+ _, (lhs, line), op, rhs = val
815
868
 
816
869
  lhs = s(:colon3, lhs.to_sym).line line
817
870
  result = new_const_op_asgn [lhs, op, rhs]
@@ -825,7 +878,7 @@ rule
825
878
  | arg tDOT2 arg
826
879
  {
827
880
  v1, v2 = val[0], val[2]
828
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
881
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
829
882
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
830
883
  else
831
884
  result = s(:dot2, v1, v2).line v1.line
@@ -834,7 +887,7 @@ rule
834
887
  | arg tDOT3 arg
835
888
  {
836
889
  v1, v2 = val[0], val[2]
837
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
890
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
838
891
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
839
892
  else
840
893
  result = s(:dot3, v1, v2).line v1.line
@@ -856,6 +909,24 @@ rule
856
909
  result = s(:dot3, v1, v2).line v1.line
857
910
  }
858
911
  #endif
912
+
913
+ #if V >= 27
914
+ | tBDOT2 arg
915
+ {
916
+ _, v2, = val
917
+ v1 = nil
918
+
919
+ result = s(:dot2, v1, v2).line v2.line
920
+ }
921
+ | tBDOT3 arg
922
+ {
923
+ _, v2 = val
924
+ v1 = nil
925
+
926
+ result = s(:dot3, v1, v2).line v2.line
927
+ }
928
+ #endif
929
+
859
930
  | arg tPLUS arg
860
931
  {
861
932
  result = new_call val[0], :+, argl(val[2])
@@ -883,20 +954,22 @@ rule
883
954
  #if V == 20
884
955
  | tUMINUS_NUM tINTEGER tPOW arg
885
956
  {
886
- lit = s(:lit, val[1]).line lexer.lineno
887
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
957
+ _, (num, line), _, arg = val
958
+ lit = s(:lit, num).line line
959
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
888
960
  }
889
961
  | tUMINUS_NUM tFLOAT tPOW arg
890
962
  #else
891
963
  | tUMINUS_NUM simple_numeric tPOW arg
892
964
  #endif
893
965
  {
894
- lit = s(:lit, val[1]).line lexer.lineno
895
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
966
+ _, (num, line), _, arg = val
967
+ lit = s(:lit, num).line line
968
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
896
969
 
897
970
  #if V == 20
898
971
  ## TODO: why is this 2.0 only?
899
- debug20 12, val, result
972
+ debug 19
900
973
  #endif
901
974
  }
902
975
  | tUPLUS arg
@@ -995,12 +1068,12 @@ rule
995
1068
 
996
1069
  rel_expr: arg relop arg =tGT
997
1070
  {
998
- lhs, op, rhs = val
1071
+ lhs, (op, _), rhs = val
999
1072
  result = new_call lhs, op.to_sym, argl(rhs)
1000
1073
  }
1001
1074
  | rel_expr relop arg =tGT
1002
1075
  {
1003
- lhs, op, rhs = val
1076
+ lhs, (op, _), rhs = val
1004
1077
  warn "comparison '%s' after comparison", op
1005
1078
  result = new_call lhs, op.to_sym, argl(rhs)
1006
1079
  }
@@ -1040,6 +1113,26 @@ rule
1040
1113
  _, args, _ = val
1041
1114
  result = args
1042
1115
  }
1116
+ #if V >= 27
1117
+ | tLPAREN2 args tCOMMA args_forward rparen
1118
+ {
1119
+ yyerror "Unexpected ..." unless
1120
+ self.lexer.is_local_id(:"*") &&
1121
+ self.lexer.is_local_id(:"**") &&
1122
+ self.lexer.is_local_id(:"&")
1123
+
1124
+ result = call_args val
1125
+ }
1126
+ | tLPAREN2 args_forward rparen
1127
+ {
1128
+ yyerror "Unexpected ..." unless
1129
+ self.lexer.is_local_id(:"*") &&
1130
+ self.lexer.is_local_id(:"**") &&
1131
+ self.lexer.is_local_id(:"&")
1132
+
1133
+ result = call_args val
1134
+ }
1135
+ #endif
1043
1136
 
1044
1137
  opt_paren_args: none
1045
1138
  | paren_args
@@ -1193,8 +1286,9 @@ rule
1193
1286
  | backref
1194
1287
  | tFID
1195
1288
  {
1196
- msg, = val
1289
+ (msg, line), = val
1197
1290
  result = new_call nil, msg.to_sym
1291
+ result.line line
1198
1292
  }
1199
1293
  | k_begin
1200
1294
  {
@@ -1236,15 +1330,15 @@ rule
1236
1330
  }
1237
1331
  | primary_value tCOLON2 tCONSTANT
1238
1332
  {
1239
- expr, _, id = val
1333
+ expr, _, (id, _line) = val
1240
1334
 
1241
1335
  result = s(:colon2, expr, id.to_sym).line expr.line
1242
1336
  }
1243
1337
  | tCOLON3 tCONSTANT
1244
1338
  {
1245
- _, id = val
1339
+ _, (id, line) = val
1246
1340
 
1247
- result = s(:colon3, id.to_sym).line lexer.lineno
1341
+ result = s(:colon3, id.to_sym).line line
1248
1342
  }
1249
1343
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1250
1344
  {
@@ -1268,15 +1362,21 @@ rule
1268
1362
  }
1269
1363
  | kYIELD tLPAREN2 call_args rparen
1270
1364
  {
1271
- result = new_yield val[2]
1365
+ (_, line), _, args, _ = val
1366
+
1367
+ result = new_yield(args).line line
1272
1368
  }
1273
1369
  | kYIELD tLPAREN2 rparen
1274
1370
  {
1275
- result = new_yield
1371
+ (_, line), _, _ = val
1372
+
1373
+ result = new_yield.line line
1276
1374
  }
1277
1375
  | kYIELD
1278
1376
  {
1279
- result = new_yield
1377
+ (_, line), = val
1378
+
1379
+ result = new_yield.line line
1280
1380
  }
1281
1381
  | kDEFINED opt_nl tLPAREN2 expr rparen
1282
1382
  {
@@ -1291,7 +1391,7 @@ rule
1291
1391
  }
1292
1392
  | kNOT tLPAREN2 rparen
1293
1393
  {
1294
- debug20 14, val, result
1394
+ debug 20
1295
1395
  }
1296
1396
  | fcall brace_block
1297
1397
  {
@@ -1309,9 +1409,10 @@ rule
1309
1409
  iter.insert 1, call # FIX
1310
1410
  result = iter
1311
1411
  }
1312
- | tLAMBDA lambda
1412
+ | lambda
1313
1413
  {
1314
- result = val[1] # TODO: fix lineno
1414
+ expr, = val
1415
+ result = expr
1315
1416
  }
1316
1417
  | k_if expr_value then compstmt if_tail k_end
1317
1418
  {
@@ -1343,6 +1444,14 @@ rule
1343
1444
  (_, line), _, body, _ = val
1344
1445
  result = new_case nil, body, line
1345
1446
  }
1447
+ #if V >= 27
1448
+ | k_case expr_value opt_terms p_case_body k_end
1449
+ {
1450
+ (_, line), expr, _, body, _ = val
1451
+
1452
+ result = new_case expr, body, line
1453
+ }
1454
+ #endif
1346
1455
  | k_for for_var kIN expr_value_do compstmt k_end
1347
1456
  {
1348
1457
  _, var, _, iter, body, _ = val
@@ -1354,7 +1463,6 @@ rule
1354
1463
  }
1355
1464
  cpath superclass
1356
1465
  {
1357
- self.comments.push self.lexer.comments
1358
1466
  if (self.in_def || self.in_single > 0) then
1359
1467
  yyerror "class definition in method body"
1360
1468
  end
@@ -1364,7 +1472,7 @@ rule
1364
1472
  {
1365
1473
  result = new_class val
1366
1474
  self.env.unextend
1367
- self.lexer.comments # we don't care about comments in the body
1475
+ self.lexer.ignore_body_comments
1368
1476
  }
1369
1477
  | k_class tLSHFT
1370
1478
  {
@@ -1385,7 +1493,7 @@ rule
1385
1493
  {
1386
1494
  result = new_sclass val
1387
1495
  self.env.unextend
1388
- self.lexer.comments # we don't care about comments in the body
1496
+ self.lexer.ignore_body_comments
1389
1497
  }
1390
1498
  | k_module
1391
1499
  {
@@ -1393,7 +1501,6 @@ rule
1393
1501
  }
1394
1502
  cpath
1395
1503
  {
1396
- self.comments.push self.lexer.comments
1397
1504
  yyerror "module definition in method body" if
1398
1505
  self.in_def or self.in_single > 0
1399
1506
 
@@ -1403,7 +1510,7 @@ rule
1403
1510
  {
1404
1511
  result = new_module val
1405
1512
  self.env.unextend
1406
- self.lexer.comments # we don't care about comments in the body
1513
+ self.lexer.ignore_body_comments
1407
1514
  }
1408
1515
  | k_def fname
1409
1516
  {
@@ -1413,21 +1520,17 @@ rule
1413
1520
  self.env.extend
1414
1521
  lexer.cmdarg.push false
1415
1522
  lexer.cond.push false
1416
-
1417
- self.comments.push self.lexer.comments
1418
1523
  }
1419
- f_arglist bodystmt { result = lexer.lineno } k_end
1524
+ f_arglist bodystmt k_end
1420
1525
  {
1421
- in_def = val[2]
1422
-
1423
- result = new_defn val
1526
+ result, in_def = new_defn val
1424
1527
 
1425
1528
  lexer.cond.pop # group = local_pop
1426
1529
  lexer.cmdarg.pop
1427
1530
  self.env.unextend
1428
1531
  self.in_def = in_def
1429
1532
 
1430
- self.lexer.comments # we don't care about comments in the body
1533
+ self.lexer.ignore_body_comments
1431
1534
  }
1432
1535
  | k_def singleton dot_or_colon
1433
1536
  {
@@ -1435,7 +1538,7 @@ rule
1435
1538
  }
1436
1539
  fname
1437
1540
  {
1438
- result = [self.in_def, lexer.lineno]
1541
+ result = self.in_def
1439
1542
 
1440
1543
  self.in_single += 1 # TODO: remove?
1441
1544
 
@@ -1445,13 +1548,18 @@ rule
1445
1548
  lexer.cond.push false
1446
1549
 
1447
1550
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1448
- self.comments.push self.lexer.comments
1449
1551
  }
1450
1552
  f_arglist bodystmt k_end
1451
1553
  {
1452
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1453
1554
 
1454
- result = new_defs val
1555
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1556
+ # =>
1557
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1558
+
1559
+ val.delete_at 3
1560
+ val.delete_at 2
1561
+
1562
+ result, in_def = new_defs val
1455
1563
 
1456
1564
  lexer.cond.pop # group = local_pop
1457
1565
  lexer.cmdarg.pop
@@ -1462,7 +1570,7 @@ rule
1462
1570
 
1463
1571
  # TODO: restore cur_arg ? what's cur_arg?
1464
1572
 
1465
- self.lexer.comments # we don't care about comments in the body
1573
+ self.lexer.ignore_body_comments
1466
1574
  }
1467
1575
  | kBREAK
1468
1576
  {
@@ -1499,8 +1607,17 @@ rule
1499
1607
  k_case: kCASE
1500
1608
  k_for: kFOR
1501
1609
  k_class: kCLASS
1610
+ {
1611
+ self.comments.push self.lexer.comments
1612
+ }
1502
1613
  k_module: kMODULE
1614
+ {
1615
+ self.comments.push self.lexer.comments
1616
+ }
1503
1617
  k_def: kDEF
1618
+ {
1619
+ self.comments.push self.lexer.comments
1620
+ }
1504
1621
  k_do: kDO
1505
1622
  k_do_block: kDO_BLOCK
1506
1623
  k_rescue: kRESCUE
@@ -1561,51 +1678,42 @@ rule
1561
1678
 
1562
1679
  result = block_var args
1563
1680
  }
1564
- | f_marg_list tCOMMA tSTAR f_norm_arg
1681
+ | f_marg_list tCOMMA f_rest_marg
1565
1682
  {
1566
- args, _, _, splat = val
1683
+ args, _, rest = val
1567
1684
 
1568
- result = block_var args, "*#{splat}".to_sym
1685
+ result = block_var args, rest
1569
1686
  }
1570
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1687
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1571
1688
  {
1572
- args, _, _, splat, _, args2 = val
1689
+ lhs, _, splat, _, rhs = val
1573
1690
 
1574
- result = block_var args, "*#{splat}".to_sym, args2
1691
+ result = block_var lhs, splat, rhs
1575
1692
  }
1576
- | f_marg_list tCOMMA tSTAR
1693
+ | f_rest_marg
1577
1694
  {
1578
- args, _, _ = val
1695
+ rest, = val
1579
1696
 
1580
- result = block_var args, :*
1697
+ result = block_var rest
1581
1698
  }
1582
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1699
+ | f_rest_marg tCOMMA f_marg_list
1583
1700
  {
1584
- args, _, _, _, args2 = val
1701
+ splat, _, rest = val
1585
1702
 
1586
- result = block_var args, :*, args2
1703
+ result = block_var splat, rest
1587
1704
  }
1588
- | tSTAR f_norm_arg
1589
- {
1590
- _, splat = val
1591
1705
 
1592
- result = block_var :"*#{splat}"
1593
- }
1594
- | tSTAR f_norm_arg tCOMMA f_marg_list
1706
+ f_rest_marg: tSTAR f_norm_arg
1595
1707
  {
1596
- _, splat, _, args = val
1708
+ _, (id, line) = val
1597
1709
 
1598
- result = block_var :"*#{splat}", args
1710
+ result = args ["*#{id}".to_sym]
1711
+ result.line line
1599
1712
  }
1600
1713
  | tSTAR
1601
1714
  {
1602
- result = block_var :*
1603
- }
1604
- | tSTAR tCOMMA f_marg_list
1605
- {
1606
- _, _, args = val
1607
-
1608
- result = block_var :*, args
1715
+ result = args [:*]
1716
+ result.line lexer.lineno # FIX: tSTAR -> line
1609
1717
  }
1610
1718
 
1611
1719
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1620,10 +1728,16 @@ rule
1620
1728
  {
1621
1729
  result = call_args val
1622
1730
  }
1731
+ #if V >= 27
1732
+ | f_no_kwarg opt_f_block_arg
1733
+ {
1734
+ result = args val
1735
+ }
1736
+ #endif
1623
1737
  | f_block_arg
1624
1738
  {
1625
- line = lexer.lineno
1626
- result = call_args val # TODO: push line down
1739
+ (id, line), = val
1740
+ result = call_args [id]
1627
1741
  result.line line
1628
1742
  }
1629
1743
 
@@ -1732,13 +1846,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1732
1846
 
1733
1847
  bvar: tIDENTIFIER
1734
1848
  {
1735
- id, = val
1736
- line = lexer.lineno
1849
+ (id, line), = val
1737
1850
  result = s(:shadow, id.to_sym).line line
1738
1851
  }
1739
1852
  | f_bad_arg
1740
1853
 
1741
- lambda: {
1854
+ lambda: tLAMBDA
1855
+ {
1742
1856
  self.env.extend :dynamic
1743
1857
  result = [lexer.lineno, lexer.lpar_beg]
1744
1858
  lexer.paren_nest += 1
@@ -1750,14 +1864,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1864
  }
1751
1865
  lambda_body
1752
1866
  {
1753
- (line, lpar), args, _cmdarg, body = val
1867
+ _, (line, lpar), args, _cmdarg, body = val
1754
1868
  lexer.lpar_beg = lpar
1755
1869
 
1756
1870
  lexer.cmdarg.pop
1757
1871
 
1758
1872
  call = s(:lambda).line line
1759
1873
  result = new_iter call, args, body
1760
- result.line = line
1874
+ result.line line
1761
1875
  self.env.unextend # TODO: dynapush & dynapop
1762
1876
  }
1763
1877
 
@@ -1792,23 +1906,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1792
1906
  ## if (nd_type($1) == NODE_YIELD) {
1793
1907
  ## compile_error(PARSER_ARG "block given to yield");
1794
1908
 
1795
- syntax_error "Both block arg and actual block given." if
1796
- val[0].block_pass?
1909
+ cmd, blk = val
1797
1910
 
1798
- val = invert_block_call val if inverted? val
1911
+ syntax_error "Both block arg and actual block given." if
1912
+ cmd.block_pass?
1799
1913
 
1800
- cmd, blk = val
1914
+ if inverted? val then
1915
+ val = invert_block_call val
1916
+ cmd, blk = val
1917
+ end
1801
1918
 
1802
1919
  result = blk
1803
1920
  result.insert 1, cmd
1804
1921
  }
1805
1922
  | block_call call_op2 operation2 opt_paren_args
1806
1923
  {
1807
- result = new_call val[0], val[2].to_sym, val[3]
1924
+ lhs, _, (id, _line), args = val
1925
+
1926
+ result = new_call lhs, id.to_sym, args
1808
1927
  }
1809
1928
  | block_call call_op2 operation2 opt_paren_args brace_block
1810
1929
  {
1811
- iter1, _, name, args, iter2 = val
1930
+ iter1, _, (name, _line), args, iter2 = val
1812
1931
 
1813
1932
  call = new_call iter1, name.to_sym, args
1814
1933
  iter2.insert 1, call
@@ -1817,7 +1936,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1817
1936
  }
1818
1937
  | block_call call_op2 operation2 command_args do_block
1819
1938
  {
1820
- iter1, _, name, args, iter2 = val
1939
+ iter1, _, (name, _line), args, iter2 = val
1821
1940
 
1822
1941
  call = new_call iter1, name.to_sym, args
1823
1942
  iter2.insert 1, call
@@ -1825,28 +1944,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1825
1944
  result = iter2
1826
1945
  }
1827
1946
 
1828
- method_call: fcall
1829
- {
1830
- result = self.lexer.lineno
1831
- }
1832
- paren_args
1947
+ method_call: fcall paren_args
1833
1948
  {
1834
- call, lineno, args = val
1949
+ call, args = val
1835
1950
 
1836
1951
  result = call.concat args.sexp_body if args
1837
- result.line lineno
1838
1952
  }
1839
1953
  | primary_value call_op operation2 opt_paren_args
1840
1954
  {
1841
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1955
+ recv, call_op, (op, _line), args = val
1956
+
1957
+ result = new_call recv, op.to_sym, args, call_op
1842
1958
  }
1843
1959
  | primary_value tCOLON2 operation2 paren_args
1844
1960
  {
1845
- result = new_call val[0], val[2].to_sym, val[3]
1961
+ recv, _, (op, _line), args = val
1962
+
1963
+ result = new_call recv, op.to_sym, args
1846
1964
  }
1847
1965
  | primary_value tCOLON2 operation3
1848
1966
  {
1849
- result = new_call val[0], val[2].to_sym
1967
+ lhs, _, (id, _line) = val
1968
+
1969
+ result = new_call lhs, id.to_sym
1850
1970
  }
1851
1971
  | primary_value call_op paren_args
1852
1972
  {
@@ -1879,7 +1999,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1879
1999
  _, line, body, _ = val
1880
2000
 
1881
2001
  result = body
1882
- result.line = line
2002
+ result.line line
1883
2003
 
1884
2004
  self.env.unextend
1885
2005
  }
@@ -1893,7 +2013,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1893
2013
  _, line, body, _ = val
1894
2014
 
1895
2015
  result = body
1896
- result.line = line
2016
+ result.line line
1897
2017
 
1898
2018
  self.env.unextend
1899
2019
  }
@@ -1926,18 +2046,548 @@ opt_block_args_tail: tCOMMA block_args_tail
1926
2046
  self.env.unextend
1927
2047
  }
1928
2048
 
2049
+ case_args: arg_value
2050
+ {
2051
+ arg, = val
2052
+
2053
+ result = s(:array, arg).line arg.line
2054
+ }
2055
+ | tSTAR arg_value
2056
+ {
2057
+ _, arg = val
2058
+
2059
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2060
+ }
2061
+ | case_args tCOMMA arg_value
2062
+ {
2063
+ args, _, id = val
2064
+
2065
+ result = self.list_append args, id
2066
+ }
2067
+ | case_args tCOMMA tSTAR arg_value
2068
+ {
2069
+ args, _, _, id = val
2070
+
2071
+ result = self.list_append args, s(:splat, id).line(id.line)
2072
+ }
2073
+
1929
2074
  case_body: k_when
1930
2075
  {
1931
2076
  result = self.lexer.lineno
1932
2077
  }
1933
- args then compstmt cases
2078
+ case_args then compstmt cases
1934
2079
  {
1935
2080
  result = new_when(val[2], val[4])
1936
- result.line = val[1]
2081
+ result.line val[1]
1937
2082
  result << val[5] if val[5]
1938
2083
  }
1939
2084
 
1940
2085
  cases: opt_else | case_body
2086
+ #if V >= 27
2087
+ ######################################################################
2088
+
2089
+ p_case_body: kIN
2090
+ {
2091
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2092
+ self.lexer.command_start = false
2093
+ result = self.in_kwarg
2094
+ self.in_kwarg = true
2095
+ push_pvtbl
2096
+ push_pktbl
2097
+ }
2098
+ p_top_expr then
2099
+ {
2100
+ pop_pktbl
2101
+ pop_pvtbl
2102
+ old_kwargs = _values[-3]
2103
+ self.in_kwarg = old_kwargs
2104
+ }
2105
+ compstmt
2106
+ p_cases
2107
+ {
2108
+ (_, line), _, pat, _, _, body, cases = val
2109
+
2110
+ result = new_in pat, body, cases, line
2111
+ }
2112
+
2113
+ p_cases: opt_else
2114
+ | p_case_body
2115
+
2116
+ p_top_expr: p_top_expr_body
2117
+ | p_top_expr_body kIF_MOD expr_value
2118
+ {
2119
+ body, _, cond = val
2120
+ body = remove_begin body
2121
+
2122
+ result = s(:if, cond, body, nil).line body.line
2123
+ }
2124
+ | p_top_expr_body kUNLESS_MOD expr_value
2125
+ {
2126
+ body, _, cond = val
2127
+ body = remove_begin body
2128
+
2129
+ result = s(:if, cond, nil, body).line body.line
2130
+ }
2131
+
2132
+ p_top_expr_body: p_expr
2133
+ | p_expr tCOMMA
2134
+ {
2135
+ expr, _ = val
2136
+
2137
+ tail = new_array_pattern_tail nil, true, nil, nil
2138
+ result = new_array_pattern nil, expr, tail, expr.line
2139
+ }
2140
+ | p_expr tCOMMA p_args
2141
+ {
2142
+ expr, _, args = val
2143
+
2144
+ result = new_array_pattern nil, expr, args, expr.line
2145
+ }
2146
+ | p_args_tail
2147
+ {
2148
+ args, = val
2149
+ result = new_array_pattern nil, nil, args, args.line
2150
+ }
2151
+ | p_kwargs
2152
+ {
2153
+ kwargs, = val
2154
+ result = new_hash_pattern nil, kwargs, kwargs.line
2155
+ }
2156
+
2157
+ p_expr: p_as
2158
+
2159
+ p_as: p_expr tASSOC p_variable
2160
+ {
2161
+ # NODE *n = NEW_LIST($1, &@$);
2162
+ # n = list_append(p, n, $3);
2163
+ # $$ = new_hash(p, n, &@$);
2164
+
2165
+ expr, _, var = val
2166
+
2167
+ id = var.last
2168
+
2169
+ self.env[id] = :lvar # HACK: need to extend env
2170
+ lhs = s(:lasgn, id).line var.line
2171
+
2172
+ result = new_assign lhs, expr
2173
+ }
2174
+ | p_alt
2175
+
2176
+ p_alt: p_alt tPIPE p_expr_basic
2177
+ {
2178
+ lhs, _, rhs = val
2179
+
2180
+ result = s(:or, lhs, rhs).line lhs.line
2181
+ }
2182
+ | p_expr_basic
2183
+
2184
+ p_lparen: tLPAREN2 { push_pktbl }
2185
+ p_lbracket: tLBRACK2 { push_pktbl }
2186
+
2187
+ p_expr_basic: p_value
2188
+ | p_const p_lparen p_args tRPAREN
2189
+ {
2190
+ lhs, _, args, _ = val
2191
+
2192
+ pop_pktbl
2193
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2194
+ }
2195
+ | p_const p_lparen p_kwargs tRPAREN
2196
+ {
2197
+ lhs, _, kwargs, _ = val
2198
+
2199
+ pop_pktbl
2200
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2201
+ }
2202
+ | p_const tLPAREN2 tRPAREN
2203
+ {
2204
+ const, _, _ = val
2205
+
2206
+ tail = new_array_pattern_tail nil, nil, nil, nil
2207
+ result = new_array_pattern const, nil, tail, const.line
2208
+ }
2209
+ | p_const p_lbracket p_args rbracket
2210
+ {
2211
+ const, _, pre_arg, _ = val
2212
+
2213
+ pop_pktbl
2214
+ result = new_array_pattern const, nil, pre_arg, const.line
2215
+ }
2216
+ | p_const p_lbracket p_kwargs rbracket
2217
+ {
2218
+ const, _, kwargs, _ = val
2219
+
2220
+ result = new_hash_pattern const, kwargs, const.line
2221
+ }
2222
+ | p_const tLBRACK2 rbracket
2223
+ {
2224
+ const, _, _ = val
2225
+
2226
+ tail = new_array_pattern_tail nil, nil, nil, nil
2227
+ result = new_array_pattern const, nil, tail, const.line
2228
+ }
2229
+ | tLBRACK { push_pktbl } p_args rbracket
2230
+ {
2231
+ _, _, pat, _ = val
2232
+
2233
+ pop_pktbl
2234
+ result = new_array_pattern nil, nil, pat, pat.line
2235
+ }
2236
+ | tLBRACK rbracket
2237
+ {
2238
+ (_, line), _ = val
2239
+
2240
+ result = s(:array_pat).line line
2241
+ }
2242
+ | tLBRACE
2243
+ {
2244
+ push_pktbl
2245
+ result = self.in_kwarg
2246
+ self.in_kwarg = false
2247
+ }
2248
+ p_kwargs rbrace
2249
+ {
2250
+ _, in_kwarg, kwargs, _ = val
2251
+
2252
+ pop_pktbl
2253
+ self.in_kwarg = in_kwarg
2254
+
2255
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2256
+ }
2257
+ | tLBRACE rbrace
2258
+ {
2259
+ (_, line), _ = val
2260
+
2261
+ tail = new_hash_pattern_tail nil, nil, line
2262
+ result = new_hash_pattern nil, tail, line
2263
+ }
2264
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2265
+ {
2266
+ _, _, expr, _ = val
2267
+
2268
+ pop_pktbl
2269
+ result = expr
2270
+ }
2271
+
2272
+ p_args: p_expr
2273
+ {
2274
+ expr, = val
2275
+
2276
+ ary = s(:array_TAIL, expr).line expr.line
2277
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2278
+ }
2279
+ | p_args_head
2280
+ {
2281
+ head, = val
2282
+
2283
+ result = new_array_pattern_tail head, true, nil, nil
2284
+ }
2285
+ | p_args_head p_arg
2286
+ {
2287
+ head, tail = val
2288
+
2289
+ both = array_pat_concat head, tail
2290
+
2291
+ result = new_array_pattern_tail both, nil, nil, nil
2292
+ result.line head.line
2293
+ }
2294
+ | p_args_head tSTAR tIDENTIFIER
2295
+ {
2296
+ head, _, (id, _line) = val
2297
+
2298
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2299
+ result.line head.line
2300
+ }
2301
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2302
+ {
2303
+ head, _, (id, _line), _, post = val
2304
+
2305
+ result = new_array_pattern_tail head, true, id.to_sym, post
2306
+ result.line head.line
2307
+ }
2308
+ | p_args_head tSTAR
2309
+ {
2310
+ expr, _ = val
2311
+
2312
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2313
+ }
2314
+ | p_args_head tSTAR tCOMMA p_args_post
2315
+ {
2316
+ head, _, _, post = val
2317
+
2318
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2319
+ }
2320
+ | p_args_tail
2321
+
2322
+ p_args_head: p_arg tCOMMA
2323
+ {
2324
+ arg, _ = val
2325
+ result = arg
2326
+ }
2327
+ | p_args_head p_arg tCOMMA
2328
+ {
2329
+ head, tail, _ = val
2330
+
2331
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2332
+ result.line head.line
2333
+ }
2334
+
2335
+ p_args_tail: tSTAR tIDENTIFIER
2336
+ {
2337
+ _, (id, line) = val
2338
+
2339
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2340
+ result.line line
2341
+ }
2342
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2343
+ {
2344
+ _, (id, line), _, rhs = val
2345
+
2346
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2347
+ result.line line
2348
+ }
2349
+ | tSTAR
2350
+ {
2351
+ (_, line), = val
2352
+
2353
+ result = new_array_pattern_tail nil, true, nil, nil
2354
+ result.line line
2355
+ }
2356
+ | tSTAR tCOMMA p_args_post
2357
+ {
2358
+ (_, line), _, args = val
2359
+
2360
+ result = new_array_pattern_tail nil, true, nil, args
2361
+ result.line line
2362
+ }
2363
+
2364
+ p_args_post: p_arg
2365
+ | p_args_post tCOMMA p_arg
2366
+ {
2367
+ lhs, _, rhs = val
2368
+
2369
+ result = array_pat_concat lhs, rhs
2370
+ }
2371
+
2372
+ p_arg: p_expr
2373
+ {
2374
+ expr, = val
2375
+ expr = s(:array_TAIL, expr).line expr.line unless
2376
+ expr.sexp_type == :array_TAIL
2377
+ result = expr
2378
+ }
2379
+
2380
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2381
+ {
2382
+ kw_arg, _, rest = val
2383
+ # TODO? new_unique_key_hash(p, $1, &@$)
2384
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2385
+ }
2386
+ | p_kwarg
2387
+ {
2388
+ kwarg, = val
2389
+ # TODO? new_unique_key_hash(p, $1, &@$)
2390
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2391
+ }
2392
+ | p_kwarg tCOMMA
2393
+ {
2394
+ kwarg, _ = val
2395
+ # TODO? new_unique_key_hash(p, $1, &@$)
2396
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2397
+ }
2398
+ | p_kwrest
2399
+ {
2400
+ rest, = val
2401
+
2402
+ result = new_hash_pattern_tail nil, rest, rest.line
2403
+ }
2404
+ | p_kwarg tCOMMA p_kwnorest
2405
+ {
2406
+ kwarg, _, norest = val
2407
+
2408
+ # TODO? new_unique_key_hash(p, $1, &@$)
2409
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2410
+ }
2411
+ | p_kwnorest
2412
+ {
2413
+ norest, = val
2414
+
2415
+ result = new_hash_pattern_tail nil, norest, norest.line
2416
+ }
2417
+
2418
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2419
+ | p_kwarg tCOMMA p_kw
2420
+ {
2421
+ kwarg, _, kw = val
2422
+ kwarg.concat kw.sexp_body
2423
+ result = kwarg
2424
+ }
2425
+
2426
+ p_kw: p_kw_label p_expr
2427
+ {
2428
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2429
+ lhs, rhs = val
2430
+
2431
+ result = s(:PAIR, lhs, rhs).line lhs.line
2432
+ }
2433
+ | p_kw_label
2434
+ {
2435
+ lhs, = val
2436
+
2437
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2438
+
2439
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2440
+ # yyerror1(&@1, "key must be valid as local variables");
2441
+ # }
2442
+
2443
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2444
+ # assignable(p, $1, 0, &@$));
2445
+
2446
+
2447
+ case lhs.sexp_type
2448
+ when :lit then
2449
+ assignable [lhs.value, lhs.line]
2450
+ else
2451
+ # TODO or done?
2452
+ debug 666
2453
+ end
2454
+
2455
+ # TODO PAIR -> LIST ?
2456
+ result = s(:PAIR, lhs, nil).line lhs.line
2457
+ }
2458
+
2459
+ p_kw_label: tLABEL
2460
+ {
2461
+ (id, line), = val
2462
+
2463
+ result = s(:lit, id.to_sym).line line
2464
+ }
2465
+
2466
+ p_kwrest: kwrest_mark tIDENTIFIER
2467
+ {
2468
+ _, (id, line) = val
2469
+
2470
+ name = id.to_sym
2471
+ self.assignable [name, line]
2472
+ result = s(:kwrest, :"**#{name}").line line
2473
+ }
2474
+ | kwrest_mark
2475
+ {
2476
+ (_, line), = val
2477
+
2478
+ result = s(:kwrest, :"**").line line
2479
+ }
2480
+
2481
+ p_kwnorest: kwrest_mark kNIL
2482
+ {
2483
+ (_, line), _ = val
2484
+
2485
+ # TODO: or s(:norest)? s(:**nil)?
2486
+ result = s(:kwrest, :"**nil").line line
2487
+ }
2488
+
2489
+ p_value: p_primitive
2490
+ | p_primitive tDOT2 p_primitive
2491
+ {
2492
+ lhs, _, rhs = val
2493
+
2494
+ lhs = value_expr lhs
2495
+ rhs = value_expr rhs
2496
+
2497
+ result = s(:dot2, lhs, rhs).line lhs.line
2498
+ }
2499
+ | p_primitive tDOT3 p_primitive
2500
+ {
2501
+ lhs, _, rhs = val
2502
+
2503
+ lhs = value_expr lhs
2504
+ rhs = value_expr rhs
2505
+
2506
+ result = s(:dot3, lhs, rhs).line lhs.line
2507
+ }
2508
+ | p_primitive tDOT2
2509
+ {
2510
+ v1, _ = val
2511
+
2512
+ result = s(:dot2, v1, nil).line v1.line
2513
+ }
2514
+ | p_primitive tDOT3
2515
+ {
2516
+ v1, _ = val
2517
+
2518
+ result = s(:dot3, v1, nil).line v1.line
2519
+ }
2520
+ | p_variable
2521
+ | p_var_ref
2522
+ | p_const
2523
+ | tBDOT2 p_primitive
2524
+ {
2525
+ _, v1 = val
2526
+
2527
+ result = s(:dot2, nil, v1).line v1.line
2528
+ }
2529
+ | tBDOT3 p_primitive
2530
+ {
2531
+ _, v1 = val
2532
+
2533
+ result = s(:dot3, nil, v1).line v1.line
2534
+ }
2535
+
2536
+ p_primitive: literal
2537
+ | strings
2538
+ | xstring
2539
+ | regexp
2540
+ | words
2541
+ | qwords
2542
+ | symbols
2543
+ | qsymbols
2544
+ | keyword_variable
2545
+ {
2546
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2547
+ var, = val
2548
+
2549
+ result = var
2550
+ }
2551
+ | lambda
2552
+
2553
+ p_variable: tIDENTIFIER
2554
+ {
2555
+ (id, line), = val
2556
+
2557
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2558
+ # TODO: assignable(p, $1, 0, &@$);
2559
+ result = s(:lvar, id.to_sym).line line
2560
+ }
2561
+
2562
+ p_var_ref: tCARET tIDENTIFIER
2563
+ {
2564
+ _, (id, line) = val
2565
+
2566
+ # TODO: check id against env for lvar or dvar
2567
+
2568
+ result = s(:lvar, id.to_sym).line line
2569
+ }
2570
+
2571
+ p_const: tCOLON3 cname
2572
+ {
2573
+ _, (id, line) = val
2574
+ result = s(:colon3, id.to_sym).line line
2575
+ }
2576
+ | p_const tCOLON2 cname
2577
+ {
2578
+ lhs, _, (id, _line) = val
2579
+
2580
+ l = lhs.line
2581
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2582
+ }
2583
+ | tCONSTANT
2584
+ {
2585
+ # TODO $$ = gettable(p, $1, &@$);
2586
+ (id, line), = val
2587
+ result = s(:const, id.to_sym).line line
2588
+ }
2589
+ ######################################################################
2590
+ #endif
1941
2591
 
1942
2592
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1943
2593
  {
@@ -1979,17 +2629,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1979
2629
 
1980
2630
  literal: numeric
1981
2631
  {
1982
- line = lexer.lineno
1983
- result = s(:lit, val[0])
1984
- result.line = line
2632
+ (lit, line), = val
2633
+ result = s(:lit, lit).line line
1985
2634
  }
1986
2635
  | symbol
1987
- {
1988
- line = lexer.lineno
1989
- result = s(:lit, val[0])
1990
- result.line = line
1991
- }
1992
- | dsym
1993
2636
 
1994
2637
  strings: string
1995
2638
  {
@@ -2000,7 +2643,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2000
2643
 
2001
2644
  string: tCHAR
2002
2645
  {
2003
- debug20 23, val, result
2646
+ debug 37
2004
2647
  }
2005
2648
  | string1
2006
2649
  | string string1
@@ -2010,11 +2653,11 @@ opt_block_args_tail: tCOMMA block_args_tail
2010
2653
 
2011
2654
  string1: tSTRING_BEG string_contents tSTRING_END
2012
2655
  {
2013
- _, str, (_, func) = val
2656
+ (_, line), str, (_, func) = val
2014
2657
 
2015
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2658
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2016
2659
 
2017
- result = str
2660
+ result = str.line line
2018
2661
  }
2019
2662
  | tSTRING
2020
2663
  {
@@ -2034,11 +2677,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2034
2677
 
2035
2678
  words: tWORDS_BEG tSPACE tSTRING_END
2036
2679
  {
2037
- result = s(:array).line lexer.lineno
2680
+ (_, line), _, _ = val
2681
+
2682
+ result = s(:array).line line
2038
2683
  }
2039
2684
  | tWORDS_BEG word_list tSTRING_END
2040
2685
  {
2041
- result = val[1]
2686
+ (_, line), list, _ = val
2687
+
2688
+ result = list.line line
2042
2689
  }
2043
2690
 
2044
2691
  word_list: none
@@ -2058,18 +2705,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2705
 
2059
2706
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2060
2707
  {
2061
- result = s(:array).line lexer.lineno
2708
+ (_, line), _, _ = val
2709
+
2710
+ result = s(:array).line line
2062
2711
  }
2063
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2712
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2064
2713
  {
2065
- _, line, list, _, = val
2066
- list.line = line
2714
+ (_, line), list, _, = val
2715
+ list.line line
2067
2716
  result = list
2068
2717
  }
2069
2718
 
2070
2719
  symbol_list: none
2071
2720
  {
2072
- result = new_symbol_list.line lexer.lineno
2721
+ result = new_symbol_list
2073
2722
  }
2074
2723
  | symbol_list word tSPACE
2075
2724
  {
@@ -2079,20 +2728,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2079
2728
 
2080
2729
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2081
2730
  {
2082
- result = s(:array).line lexer.lineno
2731
+ (_, line), _, _ = val
2732
+
2733
+ result = s(:array).line line
2083
2734
  }
2084
2735
  | tQWORDS_BEG qword_list tSTRING_END
2085
2736
  {
2086
- result = val[1]
2737
+ (_, line), list, _ = val
2738
+
2739
+ result = list.line line
2087
2740
  }
2088
2741
 
2089
2742
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2090
2743
  {
2091
- result = s(:array).line lexer.lineno # FIX
2744
+ (_, line), _, _ = val
2745
+
2746
+ result = s(:array).line line
2092
2747
  }
2093
2748
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2094
2749
  {
2095
- result = val[1]
2750
+ (_, line), list, _ = val
2751
+
2752
+ result = list.line line
2096
2753
  }
2097
2754
 
2098
2755
  qword_list: none
@@ -2115,7 +2772,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2115
2772
 
2116
2773
  string_contents: none
2117
2774
  {
2118
- result = s(:str, "").line lexer.lineno
2775
+ line = prev_value_to_lineno _values.last
2776
+ result = s(:str, +"").line line
2119
2777
  }
2120
2778
  | string_contents string_content
2121
2779
  {
@@ -2190,8 +2848,8 @@ regexp_contents: none
2190
2848
  lexer.brace_nest = brace_nest
2191
2849
  lexer.string_nest = string_nest
2192
2850
 
2193
- lexer.cmdarg.pop
2194
2851
  lexer.cond.pop
2852
+ lexer.cmdarg.pop
2195
2853
 
2196
2854
  lexer.lex_state = oldlex_state
2197
2855
 
@@ -2206,29 +2864,49 @@ regexp_contents: none
2206
2864
  when nil then
2207
2865
  result = s(:evstr).line line
2208
2866
  else
2209
- debug20 25
2867
+ debug 38
2210
2868
  raise "unknown string body: #{stmt.inspect}"
2211
2869
  end
2212
2870
  }
2213
2871
 
2214
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2215
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2216
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2872
+ string_dvar: tGVAR
2873
+ {
2874
+ (id, line), = val
2875
+ result = s(:gvar, id.to_sym).line line
2876
+ }
2877
+ | tIVAR
2878
+ {
2879
+ (id, line), = val
2880
+ result = s(:ivar, id.to_sym).line line
2881
+ }
2882
+ | tCVAR
2883
+ {
2884
+ (id, line), = val
2885
+ result = s(:cvar, id.to_sym).line line
2886
+ }
2217
2887
  | backref
2218
2888
 
2219
- symbol: tSYMBEG sym
2889
+ symbol: ssym
2890
+ | dsym
2891
+
2892
+ ssym: tSYMBEG sym
2220
2893
  {
2894
+ _, (id, line) = val
2895
+
2221
2896
  lexer.lex_state = EXPR_END
2222
- result = val[1].to_sym
2897
+ result = s(:lit, id.to_sym).line line
2223
2898
  }
2224
2899
  | tSYMBOL
2225
2900
  {
2226
- result = val[0].to_sym
2901
+ (id, line), = val
2902
+
2903
+ lexer.lex_state = EXPR_END
2904
+ result = s(:lit, id.to_sym).line line
2227
2905
  }
2228
2906
 
2229
2907
  sym: fname | tIVAR | tGVAR | tCVAR
2230
2908
 
2231
- dsym: tSYMBEG xstring_contents tSTRING_END
2909
+ dsym: tSYMBEG string_contents tSTRING_END
2232
2910
  {
2233
2911
  _, result, _ = val
2234
2912
 
@@ -2244,7 +2922,7 @@ regexp_contents: none
2244
2922
  when :evstr then
2245
2923
  result = s(:dsym, "", result).line result.line
2246
2924
  else
2247
- debug20 26, val, result
2925
+ debug 39
2248
2926
  end
2249
2927
  }
2250
2928
 
@@ -2254,15 +2932,17 @@ regexp_contents: none
2254
2932
  | tUMINUS_NUM tINTEGER =tLOWEST
2255
2933
  #else
2256
2934
  numeric: simple_numeric
2257
- | tUMINUS_NUM simple_numeric
2935
+ | tUMINUS_NUM simple_numeric =tLOWEST
2258
2936
  #endif
2259
2937
  {
2260
- result = -val[1] # TODO: pt_testcase
2938
+ _, (num, line) = val
2939
+ result = [-num, line]
2261
2940
  #if V == 20
2262
2941
  }
2263
2942
  | tUMINUS_NUM tFLOAT =tLOWEST
2264
2943
  {
2265
- result = -val[1] # TODO: pt_testcase
2944
+ _, (num, line) = val
2945
+ result = [-num, line]
2266
2946
  #endif
2267
2947
  }
2268
2948
 
@@ -2298,8 +2978,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2298
2978
 
2299
2979
  var_ref: user_variable
2300
2980
  {
2301
- var = val[0]
2981
+ raise "NO: #{val.inspect}" if Sexp === val.first
2982
+ (var, line), = val
2302
2983
  result = Sexp === var ? var : self.gettable(var)
2984
+ result.line line
2303
2985
  }
2304
2986
  | keyword_variable
2305
2987
  {
@@ -2314,11 +2996,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2314
2996
  | keyword_variable
2315
2997
  {
2316
2998
  result = self.assignable val[0]
2317
- debug20 29, val, result
2999
+ debug 40
2318
3000
  }
2319
3001
 
2320
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2321
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
3002
+ backref: tNTH_REF
3003
+ {
3004
+ (ref, line), = val
3005
+ result = s(:nth_ref, ref).line line
3006
+ }
3007
+ | tBACK_REF
3008
+ {
3009
+ (ref, line), = val
3010
+ result = s(:back_ref, ref).line line
3011
+ }
2322
3012
 
2323
3013
  superclass: tLT
2324
3014
  {
@@ -2336,10 +3026,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2336
3026
 
2337
3027
  f_arglist: tLPAREN2 f_args rparen
2338
3028
  {
2339
- result = val[1]
2340
- self.lexer.lex_state = EXPR_BEG
2341
- self.lexer.command_start = true
3029
+ result = end_args val
3030
+ }
3031
+ #if V == 27
3032
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3033
+ {
3034
+ result = end_args val
2342
3035
  }
3036
+ | tLPAREN2 args_forward rparen
3037
+ {
3038
+ result = end_args val
3039
+ }
3040
+ #endif
2343
3041
  | {
2344
3042
  result = self.in_kwarg
2345
3043
  self.in_kwarg = true
@@ -2347,12 +3045,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2347
3045
  }
2348
3046
  f_args term
2349
3047
  {
2350
- kwarg, args, _ = val
2351
-
2352
- self.in_kwarg = kwarg
2353
- result = args
2354
- lexer.lex_state = EXPR_BEG
2355
- lexer.command_start = true
3048
+ result = end_args val
2356
3049
  }
2357
3050
 
2358
3051
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2367,6 +3060,12 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2367
3060
  {
2368
3061
  result = args val
2369
3062
  }
3063
+ #if V >= 27
3064
+ | f_no_kwarg opt_f_block_arg
3065
+ {
3066
+ result = args val
3067
+ }
3068
+ #endif
2370
3069
  | f_block_arg
2371
3070
 
2372
3071
  opt_args_tail: tCOMMA args_tail
@@ -2437,7 +3136,15 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2437
3136
  |
2438
3137
  {
2439
3138
  result = args val
3139
+ # result.line lexer.lineno
3140
+ }
3141
+
3142
+ #if V >= 27
3143
+ args_forward: tBDOT3
3144
+ {
3145
+ result = s(:forward_args).line lexer.lineno
2440
3146
  }
3147
+ #endif
2441
3148
 
2442
3149
  f_bad_arg: tCONSTANT
2443
3150
  {
@@ -2459,10 +3166,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2459
3166
  f_norm_arg: f_bad_arg
2460
3167
  | tIDENTIFIER
2461
3168
  {
2462
- identifier = val[0].to_sym
3169
+ (id, line), = val
3170
+ identifier = id.to_sym
2463
3171
  self.env[identifier] = :lvar
2464
3172
 
2465
- result = identifier
3173
+ result = [identifier, line]
2466
3174
  }
2467
3175
 
2468
3176
  #if V >= 22
@@ -2471,29 +3179,23 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2471
3179
  f_arg_item: f_arg_asgn
2472
3180
  | tLPAREN f_margs rparen
2473
3181
  {
2474
- result = val[1]
3182
+ _, margs, _ = val
3183
+
3184
+ result = margs
2475
3185
  }
2476
3186
  #else
2477
3187
  f_arg_item: f_norm_arg
2478
3188
  | tLPAREN f_margs rparen
2479
3189
  {
2480
- result = val[1]
3190
+ _, margs, _ = val
3191
+
3192
+ result = margs
2481
3193
  }
2482
3194
  #endif
2483
3195
 
2484
3196
  f_arg: f_arg_item
2485
3197
  {
2486
- arg, = val
2487
-
2488
- case arg
2489
- when Symbol then
2490
- result = s(:args, arg).line lexer.lineno
2491
- when Sexp then
2492
- result = arg
2493
- else
2494
- debug20 32
2495
- raise "Unknown f_arg type: #{val.inspect}"
2496
- end
3198
+ result = new_arg val
2497
3199
  }
2498
3200
  | f_arg tCOMMA f_arg_item
2499
3201
  {
@@ -2505,7 +3207,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2505
3207
  result = s(:args, list).line list.line
2506
3208
  end
2507
3209
 
2508
- result << item
3210
+ result << (Sexp === item ? item : item.first)
2509
3211
  }
2510
3212
 
2511
3213
  #if V == 20
@@ -2578,15 +3280,26 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2578
3280
  kwrest_mark: tPOW
2579
3281
  | tDSTAR
2580
3282
 
3283
+ #if V >= 27
3284
+ f_no_kwarg: kwrest_mark kNIL
3285
+ {
3286
+ result = :"**nil"
3287
+ }
3288
+ #endif
3289
+
2581
3290
  f_kwrest: kwrest_mark tIDENTIFIER
2582
3291
  {
2583
- name = val[1].to_sym
2584
- self.assignable name
2585
- result = :"**#{name}"
3292
+ _, (id, line) = val
3293
+
3294
+ name = id.to_sym
3295
+ self.assignable [name, line]
3296
+ result = [:"**#{name}", line]
2586
3297
  }
2587
3298
  | kwrest_mark
2588
3299
  {
2589
- result = :"**"
3300
+ id = :"**"
3301
+ self.env[id] = :lvar # TODO: needed?!?
3302
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2590
3303
  }
2591
3304
 
2592
3305
  #if V == 20
@@ -2597,7 +3310,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2597
3310
  f_opt: f_arg_asgn tEQL arg_value
2598
3311
  #endif
2599
3312
  {
2600
- result = self.assignable val[0], val[2]
3313
+ lhs, _, rhs = val
3314
+ result = self.assignable lhs, rhs
2601
3315
  # TODO: detect duplicate names
2602
3316
  }
2603
3317
 
@@ -2609,7 +3323,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2609
3323
  f_block_opt: f_arg_asgn tEQL primary_value
2610
3324
  #endif
2611
3325
  {
2612
- result = self.assignable val[0], val[2]
3326
+ lhs, _, rhs = val
3327
+ result = self.assignable lhs, rhs
2613
3328
  }
2614
3329
 
2615
3330
  f_block_optarg: f_block_opt
@@ -2639,30 +3354,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2639
3354
  f_rest_arg: restarg_mark tIDENTIFIER
2640
3355
  {
2641
3356
  # TODO: differs from parse.y - needs tests
2642
- name = val[1].to_sym
2643
- self.assignable name
2644
- result = :"*#{name}"
3357
+ _, (id, line) = val
3358
+ name = id.to_sym
3359
+ self.assignable [name, line]
3360
+ result = [:"*#{name}", line]
2645
3361
  }
2646
3362
  | restarg_mark
2647
3363
  {
2648
3364
  name = :"*"
2649
3365
  self.env[name] = :lvar
2650
- result = name
3366
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2651
3367
  }
2652
3368
 
2653
3369
  blkarg_mark: tAMPER2 | tAMPER
2654
3370
 
2655
3371
  f_block_arg: blkarg_mark tIDENTIFIER
2656
3372
  {
2657
- identifier = val[1].to_sym
3373
+ _, (id, line) = val
3374
+ identifier = id.to_sym
2658
3375
 
2659
3376
  self.env[identifier] = :lvar
2660
- result = "&#{identifier}".to_sym
3377
+ result = ["&#{identifier}".to_sym, line]
2661
3378
  }
2662
3379
 
2663
3380
  opt_f_block_arg: tCOMMA f_block_arg
2664
3381
  {
2665
- result = val[1]
3382
+ _, arg = val
3383
+ result = arg
2666
3384
  }
2667
3385
  |
2668
3386
  {
@@ -2712,9 +3430,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2712
3430
  #if V >= 22
2713
3431
  | tSTRING_BEG string_contents tLABEL_END arg_value
2714
3432
  {
2715
- _, sym, _, value = val
3433
+ (_, line), sym, _, value = val
3434
+
2716
3435
  sym.sexp_type = :dsym
2717
- result = s(:array, sym, value).line sym.line
3436
+
3437
+ result = s(:array, sym, value).line line
2718
3438
  }
2719
3439
  #endif
2720
3440
  | tDSTAR arg_value
@@ -2740,6 +3460,9 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2740
3460
  opt_nl: | tNL
2741
3461
  rparen: opt_nl tRPAREN
2742
3462
  rbracket: opt_nl tRBRACK
3463
+ #if V >= 27
3464
+ rbrace: opt_nl tRCURLY
3465
+ #endif
2743
3466
  trailer: | tNL | tCOMMA
2744
3467
 
2745
3468
  term: tSEMI { yyerrok }