ruby_parser 3.15.1 → 3.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 }