ruby_parser 3.15.0 → 3.19.2

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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +151 -0
  4. data/Manifest.txt +7 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +141 -31
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +8 -3
  9. data/debugging.md +133 -0
  10. data/gauntlet.md +107 -0
  11. data/lib/rp_extensions.rb +15 -36
  12. data/lib/rp_stringscanner.rb +20 -51
  13. data/lib/ruby20_parser.rb +7544 -3633
  14. data/lib/ruby20_parser.y +335 -257
  15. data/lib/ruby21_parser.rb +7518 -3678
  16. data/lib/ruby21_parser.y +330 -254
  17. data/lib/ruby22_parser.rb +7652 -3689
  18. data/lib/ruby22_parser.y +334 -256
  19. data/lib/ruby23_parser.rb +7659 -3702
  20. data/lib/ruby23_parser.y +334 -256
  21. data/lib/ruby24_parser.rb +7748 -3721
  22. data/lib/ruby24_parser.y +334 -256
  23. data/lib/ruby25_parser.rb +7748 -3721
  24. data/lib/ruby25_parser.y +334 -256
  25. data/lib/ruby26_parser.rb +7755 -3726
  26. data/lib/ruby26_parser.y +334 -255
  27. data/lib/ruby27_parser.rb +10290 -4518
  28. data/lib/ruby27_parser.y +933 -254
  29. data/lib/ruby30_parser.rb +13258 -0
  30. data/lib/ruby30_parser.y +3459 -0
  31. data/lib/ruby31_parser.rb +13638 -0
  32. data/lib/ruby31_parser.y +3493 -0
  33. data/lib/ruby3_parser.yy +3548 -0
  34. data/lib/ruby_lexer.rb +277 -599
  35. data/lib/ruby_lexer.rex +28 -21
  36. data/lib/ruby_lexer.rex.rb +60 -24
  37. data/lib/ruby_lexer_strings.rb +638 -0
  38. data/lib/ruby_parser.rb +4 -0
  39. data/lib/ruby_parser.yy +974 -261
  40. data/lib/ruby_parser_extras.rb +355 -114
  41. data/test/test_ruby_lexer.rb +226 -129
  42. data/test/test_ruby_parser.rb +1653 -267
  43. data/tools/munge.rb +36 -8
  44. data/tools/ripper.rb +15 -10
  45. data.tar.gz.sig +0 -0
  46. metadata +55 -37
  47. metadata.gz.sig +0 -0
data/lib/ruby25_parser.y CHANGED
@@ -18,7 +18,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
@@ -33,7 +33,7 @@ preclow
33
33
  right tEQL tOP_ASGN
34
34
  left kRESCUE_MOD
35
35
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
36
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
37
  left tOROP
38
38
  left tANDOP
39
39
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +56,9 @@ rule
56
56
  top_compstmt
57
57
  {
58
58
  result = new_compstmt val
59
+
60
+ lexer.cond.pop # local_pop
61
+ lexer.cmdarg.pop
59
62
  }
60
63
 
61
64
  top_compstmt: top_stmts opt_terms
@@ -76,7 +79,7 @@ rule
76
79
  | klBEGIN
77
80
  {
78
81
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
82
+ debug 11
80
83
  yyerror "BEGIN in method"
81
84
  end
82
85
  self.env.extend
@@ -101,7 +104,9 @@ rule
101
104
  bodystmt: compstmt opt_rescue k_else
102
105
  {
103
106
  res = _values[-2]
104
- yyerror "else without rescue is useless" unless res
107
+ # TODO: move down to main match so I can just use val
108
+
109
+ warn "else without rescue is useless" unless res
105
110
  }
106
111
  compstmt
107
112
  opt_ensure
@@ -131,7 +136,7 @@ rule
131
136
  | error stmt
132
137
  {
133
138
  result = val[1]
134
- debug20 2, val, result
139
+ debug 12
135
140
  }
136
141
 
137
142
  stmt_or_begin: stmt
@@ -139,6 +144,10 @@ rule
139
144
  {
140
145
  yyerror "BEGIN is permitted only at toplevel"
141
146
  }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
150
+ }
142
151
 
143
152
  stmt: kALIAS fitem
144
153
  {
@@ -151,12 +160,12 @@ rule
151
160
  }
152
161
  | kALIAS tGVAR tGVAR
153
162
  {
154
- (_, line), lhs, rhs = val
163
+ (_, line), (lhs, _), (rhs, _) = val
155
164
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
165
  }
157
166
  | kALIAS tGVAR tBACK_REF
158
167
  {
159
- (_, line), lhs, rhs = val
168
+ (_, line), (lhs, _), (rhs, _) = val
160
169
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
170
  }
162
171
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +208,7 @@ rule
199
208
  (_, line), _, stmt, _ = val
200
209
 
201
210
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
211
+ debug 13
203
212
  yyerror "END in method; use at_exit"
204
213
  end
205
214
 
@@ -239,32 +248,31 @@ rule
239
248
  }
240
249
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
250
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
251
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
252
+
253
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
254
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
255
+ result.line prim.line
248
256
  }
249
257
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
258
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
256
264
  }
257
265
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
266
  {
259
- lhs1, _, lhs2, op, rhs = val
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
268
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
269
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
270
  }
263
271
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
272
  {
265
- lhs1, _, lhs2, op, rhs = val
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
274
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
275
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
276
  }
269
277
  | backref tOP_ASGN command_rhs
270
278
  {
@@ -310,7 +318,7 @@ rule
310
318
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
319
  # REFACTOR: call_uni_op -- see parse26.y
312
320
  }
313
- | arg
321
+ | arg =tLBRACE_ARG
314
322
 
315
323
  expr_value: expr
316
324
  {
@@ -335,7 +343,7 @@ rule
335
343
  block_command: block_call
336
344
  | block_call call_op2 operation2 command_args
337
345
  {
338
- blk, _, msg, args = val
346
+ blk, _, (msg, _line), args = val
339
347
  result = new_call(blk, msg.to_sym, args).line blk.line
340
348
  }
341
349
 
@@ -349,15 +357,15 @@ rule
349
357
  _, line, body, _ = val
350
358
 
351
359
  result = body
352
- result.line = line
360
+ result.line line
353
361
 
354
362
  # self.env.unextend
355
363
  }
356
364
 
357
365
  fcall: operation
358
366
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
367
+ (msg, line), = val
368
+ result = new_call(nil, msg.to_sym).line line
361
369
  }
362
370
 
363
371
  command: fcall command_args =tLOWEST
@@ -380,12 +388,14 @@ rule
380
388
  }
381
389
  | primary_value call_op operation2 command_args =tLOWEST
382
390
  {
383
- lhs, callop, op, args = val
391
+ lhs, callop, (op, _), args = val
392
+
384
393
  result = new_call lhs, op.to_sym, args, callop
394
+ result.line lhs.line
385
395
  }
386
396
  | primary_value call_op operation2 command_args cmd_brace_block
387
397
  {
388
- recv, _, msg, args, block = val
398
+ recv, _, (msg, _line), args, block = val
389
399
  call = new_call recv, msg.to_sym, args, val[1]
390
400
 
391
401
  block_dup_check call, block
@@ -395,11 +405,14 @@ rule
395
405
  }
396
406
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
407
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
408
+ lhs, _, (id, line), args = val
409
+
410
+ result = new_call lhs, id.to_sym, args
411
+ result.line line
399
412
  }
400
413
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
414
  {
402
- recv, _, msg, args, block = val
415
+ recv, _, (msg, _line), args, block = val
403
416
  call = new_call recv, msg.to_sym, args
404
417
 
405
418
  block_dup_check call, block
@@ -557,25 +570,29 @@ rule
557
570
  }
558
571
  | primary_value call_op tIDENTIFIER
559
572
  {
560
- result = new_attrasgn val[0], val[2], val[1]
573
+ lhs, call_op, (id, _line) = val
574
+
575
+ result = new_attrasgn lhs, id, call_op
561
576
  }
562
577
  | primary_value tCOLON2 tIDENTIFIER
563
578
  {
564
- recv, _, id = val
579
+ recv, _, (id, _line) = val
565
580
  result = new_attrasgn recv, id
566
581
  }
567
582
  | primary_value call_op tCONSTANT
568
583
  {
569
- result = new_attrasgn val[0], val[2], val[1]
584
+ lhs, call_op, (id, _line) = val
585
+
586
+ result = new_attrasgn lhs, id, call_op
570
587
  }
571
588
  | primary_value tCOLON2 tCONSTANT
572
589
  {
573
590
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
591
+ debug 14
575
592
  yyerror "dynamic constant assignment"
576
593
  end
577
594
 
578
- expr, _, id = val
595
+ expr, _, (id, _line) = val
579
596
  l = expr.line
580
597
 
581
598
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +600,65 @@ rule
583
600
  | tCOLON3 tCONSTANT
584
601
  {
585
602
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
603
+ debug 15
587
604
  yyerror "dynamic constant assignment"
588
605
  end
589
606
 
590
- _, id = val
591
- l = lexer.lineno
607
+ _, (id, l) = val
592
608
 
593
609
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
610
  }
595
611
  | backref
596
612
  {
597
- self.backref_assign_error val[0]
613
+ ref, = val
614
+
615
+ self.backref_assign_error ref
598
616
  }
599
617
 
600
618
  lhs: user_variable
601
619
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
620
+ var, = val
621
+
622
+ result = self.assignable var
605
623
  }
606
624
  | keyword_variable
607
625
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
626
+ var, = val
627
+
628
+ result = self.assignable var
629
+
630
+ debug 16
612
631
  }
613
632
  | primary_value tLBRACK2 opt_call_args rbracket
614
633
  {
615
634
  lhs, _, args, _ = val
635
+
616
636
  result = self.aryset lhs, args
617
637
  }
618
638
  | primary_value call_op tIDENTIFIER # REFACTOR
619
639
  {
620
- lhs, op, id = val
640
+ lhs, op, (id, _line) = val
641
+
621
642
  result = new_attrasgn lhs, id, op
622
643
  }
623
644
  | primary_value tCOLON2 tIDENTIFIER
624
645
  {
625
- lhs, _, id = val
646
+ lhs, _, (id, _line) = val
647
+
626
648
  result = new_attrasgn lhs, id
627
649
  }
628
650
  | primary_value call_op tCONSTANT # REFACTOR?
629
651
  {
630
- result = new_attrasgn val[0], val[2], val[1]
652
+ lhs, call_op, (id, _line) = val
653
+
654
+ result = new_attrasgn lhs, id, call_op
631
655
  }
632
656
  | primary_value tCOLON2 tCONSTANT
633
657
  {
634
- expr, _, id = val
658
+ expr, _, (id, _line) = val
635
659
 
636
660
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
661
+ debug 17
638
662
  yyerror "dynamic constant assignment"
639
663
  end
640
664
 
@@ -643,14 +667,13 @@ rule
643
667
  }
644
668
  | tCOLON3 tCONSTANT
645
669
  {
646
- _, id = val
670
+ _, (id, l) = val
647
671
 
648
672
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
673
+ debug 18
650
674
  yyerror "dynamic constant assignment"
651
675
  end
652
676
 
653
- l = lexer.lineno
654
677
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
678
  }
656
679
  | backref
@@ -666,16 +689,16 @@ rule
666
689
 
667
690
  cpath: tCOLON3 cname
668
691
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
692
+ result = wrap :colon3, val[1]
671
693
  }
672
694
  | cname
673
695
  {
674
- result = val[0].to_sym
696
+ (id, line), = val
697
+ result = [id.to_sym, line] # TODO: sexp?
675
698
  }
676
699
  | primary_value tCOLON2 cname
677
700
  {
678
- pval, _, name = val
701
+ pval, _, (name, _line) = val
679
702
 
680
703
  result = s(:colon2, pval, name.to_sym)
681
704
  result.line pval.line
@@ -685,24 +708,15 @@ rule
685
708
  | op
686
709
  {
687
710
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
711
  }
690
712
 
691
713
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
714
 
698
- fsym: fname | symbol
699
-
700
- fitem: fsym
715
+ fitem: fname
701
716
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
717
+ result = wrap :lit, val[0]
704
718
  }
705
- | dsym
719
+ | symbol
706
720
 
707
721
  undef_list: fitem
708
722
  {
@@ -723,8 +737,6 @@ rule
723
737
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
738
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
739
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
740
 
729
741
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
742
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,26 +770,22 @@ rule
758
770
  }
759
771
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
772
  {
761
- lhs, _, id, op, rhs = val
773
+ lhs, _, (id, _line), (op, _), rhs = val
762
774
 
763
775
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
776
  }
765
777
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
778
  {
767
- lhs1, _, lhs2, op, rhs = val
779
+ lhs1, _, (lhs2, _line), op, rhs = val
768
780
 
769
781
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
782
  result = new_const_op_asgn [lhs, op, rhs]
771
783
  }
772
- | tCOLON3 tCONSTANT
784
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
785
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
786
+ _, lhs, op, rhs = val
779
787
 
780
- lhs = s(:colon3, lhs.to_sym).line line
788
+ lhs = wrap :colon3, lhs
781
789
  result = new_const_op_asgn [lhs, op, rhs]
782
790
  }
783
791
  | backref tOP_ASGN arg_rhs
@@ -789,7 +797,7 @@ rule
789
797
  | arg tDOT2 arg
790
798
  {
791
799
  v1, v2 = val[0], val[2]
792
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
800
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
801
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
802
  else
795
803
  result = s(:dot2, v1, v2).line v1.line
@@ -798,12 +806,14 @@ rule
798
806
  | arg tDOT3 arg
799
807
  {
800
808
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
809
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
810
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
811
  else
804
812
  result = s(:dot3, v1, v2).line v1.line
805
813
  end
806
814
  }
815
+
816
+
807
817
  | arg tPLUS arg
808
818
  {
809
819
  result = new_call val[0], :+, argl(val[2])
@@ -830,8 +840,9 @@ rule
830
840
  }
831
841
  | tUMINUS_NUM simple_numeric tPOW arg
832
842
  {
833
- lit = s(:lit, val[1]).line lexer.lineno
834
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
843
+ _, (num, line), _, arg = val
844
+ lit = s(:lit, num).line line
845
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
835
846
 
836
847
  }
837
848
  | tUPLUS arg
@@ -930,12 +941,12 @@ rule
930
941
 
931
942
  rel_expr: arg relop arg =tGT
932
943
  {
933
- lhs, op, rhs = val
944
+ lhs, (op, _), rhs = val
934
945
  result = new_call lhs, op.to_sym, argl(rhs)
935
946
  }
936
947
  | rel_expr relop arg =tGT
937
948
  {
938
- lhs, op, rhs = val
949
+ lhs, (op, _), rhs = val
939
950
  warn "comparison '%s' after comparison", op
940
951
  result = new_call lhs, op.to_sym, argl(rhs)
941
952
  }
@@ -1126,8 +1137,9 @@ rule
1126
1137
  | backref
1127
1138
  | tFID
1128
1139
  {
1129
- msg, = val
1140
+ (msg, line), = val
1130
1141
  result = new_call nil, msg.to_sym
1142
+ result.line line
1131
1143
  }
1132
1144
  | k_begin
1133
1145
  {
@@ -1169,15 +1181,13 @@ rule
1169
1181
  }
1170
1182
  | primary_value tCOLON2 tCONSTANT
1171
1183
  {
1172
- expr, _, id = val
1184
+ expr, _, (id, _line) = val
1173
1185
 
1174
1186
  result = s(:colon2, expr, id.to_sym).line expr.line
1175
1187
  }
1176
1188
  | tCOLON3 tCONSTANT
1177
1189
  {
1178
- _, id = val
1179
-
1180
- result = s(:colon3, id.to_sym).line lexer.lineno
1190
+ result = wrap :colon3, val[1]
1181
1191
  }
1182
1192
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1183
1193
  {
@@ -1201,15 +1211,21 @@ rule
1201
1211
  }
1202
1212
  | kYIELD tLPAREN2 call_args rparen
1203
1213
  {
1204
- result = new_yield val[2]
1214
+ (_, line), _, args, _ = val
1215
+
1216
+ result = new_yield(args).line line
1205
1217
  }
1206
1218
  | kYIELD tLPAREN2 rparen
1207
1219
  {
1208
- result = new_yield
1220
+ (_, line), _, _ = val
1221
+
1222
+ result = new_yield.line line
1209
1223
  }
1210
1224
  | kYIELD
1211
1225
  {
1212
- result = new_yield
1226
+ (_, line), = val
1227
+
1228
+ result = new_yield.line line
1213
1229
  }
1214
1230
  | kDEFINED opt_nl tLPAREN2 expr rparen
1215
1231
  {
@@ -1224,7 +1240,7 @@ rule
1224
1240
  }
1225
1241
  | kNOT tLPAREN2 rparen
1226
1242
  {
1227
- debug20 14, val, result
1243
+ debug 20
1228
1244
  }
1229
1245
  | fcall brace_block
1230
1246
  {
@@ -1242,9 +1258,10 @@ rule
1242
1258
  iter.insert 1, call # FIX
1243
1259
  result = iter
1244
1260
  }
1245
- | tLAMBDA lambda
1261
+ | lambda
1246
1262
  {
1247
- result = val[1] # TODO: fix lineno
1263
+ expr, = val
1264
+ result = expr
1248
1265
  }
1249
1266
  | k_if expr_value then compstmt if_tail k_end
1250
1267
  {
@@ -1287,7 +1304,6 @@ rule
1287
1304
  }
1288
1305
  cpath superclass
1289
1306
  {
1290
- self.comments.push self.lexer.comments
1291
1307
  if (self.in_def || self.in_single > 0) then
1292
1308
  yyerror "class definition in method body"
1293
1309
  end
@@ -1297,7 +1313,7 @@ rule
1297
1313
  {
1298
1314
  result = new_class val
1299
1315
  self.env.unextend
1300
- self.lexer.comments # we don't care about comments in the body
1316
+ self.lexer.ignore_body_comments
1301
1317
  }
1302
1318
  | k_class tLSHFT
1303
1319
  {
@@ -1318,7 +1334,7 @@ rule
1318
1334
  {
1319
1335
  result = new_sclass val
1320
1336
  self.env.unextend
1321
- self.lexer.comments # we don't care about comments in the body
1337
+ self.lexer.ignore_body_comments
1322
1338
  }
1323
1339
  | k_module
1324
1340
  {
@@ -1326,7 +1342,6 @@ rule
1326
1342
  }
1327
1343
  cpath
1328
1344
  {
1329
- self.comments.push self.lexer.comments
1330
1345
  yyerror "module definition in method body" if
1331
1346
  self.in_def or self.in_single > 0
1332
1347
 
@@ -1336,7 +1351,7 @@ rule
1336
1351
  {
1337
1352
  result = new_module val
1338
1353
  self.env.unextend
1339
- self.lexer.comments # we don't care about comments in the body
1354
+ self.lexer.ignore_body_comments
1340
1355
  }
1341
1356
  | k_def fname
1342
1357
  {
@@ -1346,21 +1361,17 @@ rule
1346
1361
  self.env.extend
1347
1362
  lexer.cmdarg.push false
1348
1363
  lexer.cond.push false
1349
-
1350
- self.comments.push self.lexer.comments
1351
1364
  }
1352
- f_arglist bodystmt { result = lexer.lineno } k_end
1365
+ f_arglist bodystmt k_end
1353
1366
  {
1354
- in_def = val[2]
1355
-
1356
- result = new_defn val
1367
+ result, in_def = new_defn val
1357
1368
 
1358
1369
  lexer.cond.pop # group = local_pop
1359
1370
  lexer.cmdarg.pop
1360
1371
  self.env.unextend
1361
1372
  self.in_def = in_def
1362
1373
 
1363
- self.lexer.comments # we don't care about comments in the body
1374
+ self.lexer.ignore_body_comments
1364
1375
  }
1365
1376
  | k_def singleton dot_or_colon
1366
1377
  {
@@ -1368,7 +1379,7 @@ rule
1368
1379
  }
1369
1380
  fname
1370
1381
  {
1371
- result = [self.in_def, lexer.lineno]
1382
+ result = self.in_def
1372
1383
 
1373
1384
  self.in_single += 1 # TODO: remove?
1374
1385
 
@@ -1378,13 +1389,18 @@ rule
1378
1389
  lexer.cond.push false
1379
1390
 
1380
1391
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1381
- self.comments.push self.lexer.comments
1382
1392
  }
1383
1393
  f_arglist bodystmt k_end
1384
1394
  {
1385
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1386
1395
 
1387
- result = new_defs val
1396
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1397
+ # =>
1398
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1399
+
1400
+ val.delete_at 3
1401
+ val.delete_at 2
1402
+
1403
+ result, in_def = new_defs val
1388
1404
 
1389
1405
  lexer.cond.pop # group = local_pop
1390
1406
  lexer.cmdarg.pop
@@ -1395,7 +1411,7 @@ rule
1395
1411
 
1396
1412
  # TODO: restore cur_arg ? what's cur_arg?
1397
1413
 
1398
- self.lexer.comments # we don't care about comments in the body
1414
+ self.lexer.ignore_body_comments
1399
1415
  }
1400
1416
  | kBREAK
1401
1417
  {
@@ -1432,8 +1448,17 @@ rule
1432
1448
  k_case: kCASE
1433
1449
  k_for: kFOR
1434
1450
  k_class: kCLASS
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1435
1454
  k_module: kMODULE
1455
+ {
1456
+ self.comments.push self.lexer.comments
1457
+ }
1436
1458
  k_def: kDEF
1459
+ {
1460
+ self.comments.push self.lexer.comments
1461
+ }
1437
1462
  k_do: kDO
1438
1463
  k_do_block: kDO_BLOCK
1439
1464
  k_rescue: kRESCUE
@@ -1494,51 +1519,42 @@ rule
1494
1519
 
1495
1520
  result = block_var args
1496
1521
  }
1497
- | f_marg_list tCOMMA tSTAR f_norm_arg
1522
+ | f_marg_list tCOMMA f_rest_marg
1498
1523
  {
1499
- args, _, _, splat = val
1524
+ args, _, rest = val
1500
1525
 
1501
- result = block_var args, "*#{splat}".to_sym
1526
+ result = block_var args, rest
1502
1527
  }
1503
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1528
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1504
1529
  {
1505
- args, _, _, splat, _, args2 = val
1530
+ lhs, _, splat, _, rhs = val
1506
1531
 
1507
- result = block_var args, "*#{splat}".to_sym, args2
1532
+ result = block_var lhs, splat, rhs
1508
1533
  }
1509
- | f_marg_list tCOMMA tSTAR
1534
+ | f_rest_marg
1510
1535
  {
1511
- args, _, _ = val
1536
+ rest, = val
1512
1537
 
1513
- result = block_var args, :*
1538
+ result = block_var rest
1514
1539
  }
1515
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1540
+ | f_rest_marg tCOMMA f_marg_list
1516
1541
  {
1517
- args, _, _, _, args2 = val
1542
+ splat, _, rest = val
1518
1543
 
1519
- result = block_var args, :*, args2
1544
+ result = block_var splat, rest
1520
1545
  }
1521
- | tSTAR f_norm_arg
1522
- {
1523
- _, splat = val
1524
1546
 
1525
- result = block_var :"*#{splat}"
1526
- }
1527
- | tSTAR f_norm_arg tCOMMA f_marg_list
1547
+ f_rest_marg: tSTAR f_norm_arg
1528
1548
  {
1529
- _, splat, _, args = val
1549
+ _, (id, line) = val
1530
1550
 
1531
- result = block_var :"*#{splat}", args
1551
+ result = args ["*#{id}".to_sym]
1552
+ result.line line
1532
1553
  }
1533
1554
  | tSTAR
1534
1555
  {
1535
- result = block_var :*
1536
- }
1537
- | tSTAR tCOMMA f_marg_list
1538
- {
1539
- _, _, args = val
1540
-
1541
- result = block_var :*, args
1556
+ result = args [:*]
1557
+ result.line lexer.lineno # FIX: tSTAR -> line
1542
1558
  }
1543
1559
 
1544
1560
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1555,8 +1571,8 @@ rule
1555
1571
  }
1556
1572
  | f_block_arg
1557
1573
  {
1558
- line = lexer.lineno
1559
- result = call_args val # TODO: push line down
1574
+ (id, line), = val
1575
+ result = call_args [id]
1560
1576
  result.line line
1561
1577
  }
1562
1578
 
@@ -1665,13 +1681,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1665
1681
 
1666
1682
  bvar: tIDENTIFIER
1667
1683
  {
1668
- id, = val
1669
- line = lexer.lineno
1670
- result = s(:shadow, id.to_sym).line line
1684
+ result = wrap :shadow, val[0]
1671
1685
  }
1672
1686
  | f_bad_arg
1673
1687
 
1674
- lambda: {
1688
+ lambda: tLAMBDA
1689
+ {
1675
1690
  self.env.extend :dynamic
1676
1691
  result = [lexer.lineno, lexer.lpar_beg]
1677
1692
  lexer.paren_nest += 1
@@ -1683,14 +1698,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1683
1698
  }
1684
1699
  lambda_body
1685
1700
  {
1686
- (line, lpar), args, _cmdarg, body = val
1701
+ _, (line, lpar), args, _cmdarg, body = val
1687
1702
  lexer.lpar_beg = lpar
1688
1703
 
1689
1704
  lexer.cmdarg.pop
1690
1705
 
1691
1706
  call = s(:lambda).line line
1692
1707
  result = new_iter call, args, body
1693
- result.line = line
1708
+ result.line line
1694
1709
  self.env.unextend # TODO: dynapush & dynapop
1695
1710
  }
1696
1711
 
@@ -1725,23 +1740,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1725
1740
  ## if (nd_type($1) == NODE_YIELD) {
1726
1741
  ## compile_error(PARSER_ARG "block given to yield");
1727
1742
 
1728
- syntax_error "Both block arg and actual block given." if
1729
- val[0].block_pass?
1743
+ cmd, blk = val
1730
1744
 
1731
- val = invert_block_call val if inverted? val
1745
+ syntax_error "Both block arg and actual block given." if
1746
+ cmd.block_pass?
1732
1747
 
1733
- cmd, blk = val
1748
+ if inverted? val then
1749
+ val = invert_block_call val
1750
+ cmd, blk = val
1751
+ end
1734
1752
 
1735
1753
  result = blk
1736
1754
  result.insert 1, cmd
1737
1755
  }
1738
1756
  | block_call call_op2 operation2 opt_paren_args
1739
1757
  {
1740
- result = new_call val[0], val[2].to_sym, val[3]
1758
+ lhs, _, (id, _line), args = val
1759
+
1760
+ result = new_call lhs, id.to_sym, args
1741
1761
  }
1742
1762
  | block_call call_op2 operation2 opt_paren_args brace_block
1743
1763
  {
1744
- iter1, _, name, args, iter2 = val
1764
+ iter1, _, (name, _line), args, iter2 = val
1745
1765
 
1746
1766
  call = new_call iter1, name.to_sym, args
1747
1767
  iter2.insert 1, call
@@ -1750,7 +1770,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1770
  }
1751
1771
  | block_call call_op2 operation2 command_args do_block
1752
1772
  {
1753
- iter1, _, name, args, iter2 = val
1773
+ iter1, _, (name, _line), args, iter2 = val
1754
1774
 
1755
1775
  call = new_call iter1, name.to_sym, args
1756
1776
  iter2.insert 1, call
@@ -1758,28 +1778,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1758
1778
  result = iter2
1759
1779
  }
1760
1780
 
1761
- method_call: fcall
1762
- {
1763
- result = self.lexer.lineno
1764
- }
1765
- paren_args
1781
+ method_call: fcall paren_args
1766
1782
  {
1767
- call, lineno, args = val
1783
+ call, args = val
1768
1784
 
1769
1785
  result = call.concat args.sexp_body if args
1770
- result.line lineno
1771
1786
  }
1772
1787
  | primary_value call_op operation2 opt_paren_args
1773
1788
  {
1774
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1789
+ recv, call_op, (op, _line), args = val
1790
+
1791
+ result = new_call recv, op.to_sym, args, call_op
1775
1792
  }
1776
1793
  | primary_value tCOLON2 operation2 paren_args
1777
1794
  {
1778
- result = new_call val[0], val[2].to_sym, val[3]
1795
+ recv, _, (op, _line), args = val
1796
+
1797
+ result = new_call recv, op.to_sym, args
1779
1798
  }
1780
1799
  | primary_value tCOLON2 operation3
1781
1800
  {
1782
- result = new_call val[0], val[2].to_sym
1801
+ lhs, _, (id, _line) = val
1802
+
1803
+ result = new_call lhs, id.to_sym
1783
1804
  }
1784
1805
  | primary_value call_op paren_args
1785
1806
  {
@@ -1812,7 +1833,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1812
1833
  _, line, body, _ = val
1813
1834
 
1814
1835
  result = body
1815
- result.line = line
1836
+ result.line line
1816
1837
 
1817
1838
  self.env.unextend
1818
1839
  }
@@ -1826,7 +1847,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1847
  _, line, body, _ = val
1827
1848
 
1828
1849
  result = body
1829
- result.line = line
1850
+ result.line line
1830
1851
 
1831
1852
  self.env.unextend
1832
1853
  }
@@ -1855,14 +1876,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
1876
  self.env.unextend
1856
1877
  }
1857
1878
 
1879
+ case_args: arg_value
1880
+ {
1881
+ arg, = val
1882
+
1883
+ result = s(:array, arg).line arg.line
1884
+ }
1885
+ | tSTAR arg_value
1886
+ {
1887
+ _, arg = val
1888
+
1889
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1890
+ }
1891
+ | case_args tCOMMA arg_value
1892
+ {
1893
+ args, _, id = val
1894
+
1895
+ result = self.list_append args, id
1896
+ }
1897
+ | case_args tCOMMA tSTAR arg_value
1898
+ {
1899
+ args, _, _, id = val
1900
+
1901
+ result = self.list_append args, s(:splat, id).line(id.line)
1902
+ }
1903
+
1858
1904
  case_body: k_when
1859
1905
  {
1860
1906
  result = self.lexer.lineno
1861
1907
  }
1862
- args then compstmt cases
1908
+ case_args then compstmt cases
1863
1909
  {
1864
1910
  result = new_when(val[2], val[4])
1865
- result.line = val[1]
1911
+ result.line val[1]
1866
1912
  result << val[5] if val[5]
1867
1913
  }
1868
1914
 
@@ -1908,17 +1954,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1908
1954
 
1909
1955
  literal: numeric
1910
1956
  {
1911
- line = lexer.lineno
1912
- result = s(:lit, val[0])
1913
- result.line = line
1957
+ (lit, line), = val
1958
+ result = s(:lit, lit).line line
1914
1959
  }
1915
1960
  | symbol
1916
- {
1917
- line = lexer.lineno
1918
- result = s(:lit, val[0])
1919
- result.line = line
1920
- }
1921
- | dsym
1922
1961
 
1923
1962
  strings: string
1924
1963
  {
@@ -1929,7 +1968,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1929
1968
 
1930
1969
  string: tCHAR
1931
1970
  {
1932
- debug20 23, val, result
1971
+ debug 37
1933
1972
  }
1934
1973
  | string1
1935
1974
  | string string1
@@ -1939,11 +1978,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1939
1978
 
1940
1979
  string1: tSTRING_BEG string_contents tSTRING_END
1941
1980
  {
1942
- _, str, (_, func) = val
1981
+ (_, line), str, (_, func) = val
1943
1982
 
1944
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1983
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1945
1984
 
1946
- result = str
1985
+ result = str.line line
1947
1986
  }
1948
1987
  | tSTRING
1949
1988
  {
@@ -1963,11 +2002,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1963
2002
 
1964
2003
  words: tWORDS_BEG tSPACE tSTRING_END
1965
2004
  {
1966
- result = s(:array).line lexer.lineno
2005
+ (_, line), _, _ = val
2006
+
2007
+ result = s(:array).line line
1967
2008
  }
1968
2009
  | tWORDS_BEG word_list tSTRING_END
1969
2010
  {
1970
- result = val[1]
2011
+ (_, line), list, _ = val
2012
+
2013
+ result = list.line line
1971
2014
  }
1972
2015
 
1973
2016
  word_list: none
@@ -1987,18 +2030,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1987
2030
 
1988
2031
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1989
2032
  {
1990
- result = s(:array).line lexer.lineno
2033
+ (_, line), _, _ = val
2034
+
2035
+ result = s(:array).line line
1991
2036
  }
1992
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2037
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1993
2038
  {
1994
- _, line, list, _, = val
1995
- list.line = line
2039
+ (_, line), list, _, = val
2040
+ list.line line
1996
2041
  result = list
1997
2042
  }
1998
2043
 
1999
2044
  symbol_list: none
2000
2045
  {
2001
- result = new_symbol_list.line lexer.lineno
2046
+ result = new_symbol_list
2002
2047
  }
2003
2048
  | symbol_list word tSPACE
2004
2049
  {
@@ -2008,20 +2053,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2008
2053
 
2009
2054
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2010
2055
  {
2011
- result = s(:array).line lexer.lineno
2056
+ (_, line), _, _ = val
2057
+
2058
+ result = s(:array).line line
2012
2059
  }
2013
2060
  | tQWORDS_BEG qword_list tSTRING_END
2014
2061
  {
2015
- result = val[1]
2062
+ (_, line), list, _ = val
2063
+
2064
+ result = list.line line
2016
2065
  }
2017
2066
 
2018
2067
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2019
2068
  {
2020
- result = s(:array).line lexer.lineno # FIX
2069
+ (_, line), _, _ = val
2070
+
2071
+ result = s(:array).line line
2021
2072
  }
2022
2073
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2023
2074
  {
2024
- result = val[1]
2075
+ (_, line), list, _ = val
2076
+
2077
+ result = list.line line
2025
2078
  }
2026
2079
 
2027
2080
  qword_list: none
@@ -2044,7 +2097,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2044
2097
 
2045
2098
  string_contents: none
2046
2099
  {
2047
- result = s(:str, "").line lexer.lineno
2100
+ line = prev_value_to_lineno _values.last
2101
+ result = s(:str, +"").line line
2048
2102
  }
2049
2103
  | string_contents string_content
2050
2104
  {
@@ -2119,8 +2173,8 @@ regexp_contents: none
2119
2173
  lexer.brace_nest = brace_nest
2120
2174
  lexer.string_nest = string_nest
2121
2175
 
2122
- lexer.cmdarg.pop
2123
2176
  lexer.cond.pop
2177
+ lexer.cmdarg.pop
2124
2178
 
2125
2179
  lexer.lex_state = oldlex_state
2126
2180
 
@@ -2135,29 +2189,42 @@ regexp_contents: none
2135
2189
  when nil then
2136
2190
  result = s(:evstr).line line
2137
2191
  else
2138
- debug20 25
2192
+ debug 38
2139
2193
  raise "unknown string body: #{stmt.inspect}"
2140
2194
  end
2141
2195
  }
2142
2196
 
2143
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2144
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2145
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2197
+ string_dvar: tGVAR
2198
+ {
2199
+ result = wrap :gvar, val[0]
2200
+ }
2201
+ | tIVAR
2202
+ {
2203
+ result = wrap :ivar, val[0]
2204
+ }
2205
+ | tCVAR
2206
+ {
2207
+ result = wrap :cvar, val[0]
2208
+ }
2146
2209
  | backref
2147
2210
 
2148
- symbol: tSYMBEG sym
2211
+ symbol: ssym
2212
+ | dsym
2213
+
2214
+ ssym: tSYMBEG sym
2149
2215
  {
2150
2216
  lexer.lex_state = EXPR_END
2151
- result = val[1].to_sym
2217
+ result = wrap :lit, val[1]
2152
2218
  }
2153
2219
  | tSYMBOL
2154
2220
  {
2155
- result = val[0].to_sym
2221
+ lexer.lex_state = EXPR_END
2222
+ result = wrap :lit, val[0]
2156
2223
  }
2157
2224
 
2158
2225
  sym: fname | tIVAR | tGVAR | tCVAR
2159
2226
 
2160
- dsym: tSYMBEG xstring_contents tSTRING_END
2227
+ dsym: tSYMBEG string_contents tSTRING_END
2161
2228
  {
2162
2229
  _, result, _ = val
2163
2230
 
@@ -2173,14 +2240,15 @@ regexp_contents: none
2173
2240
  when :evstr then
2174
2241
  result = s(:dsym, "", result).line result.line
2175
2242
  else
2176
- debug20 26, val, result
2243
+ debug 39
2177
2244
  end
2178
2245
  }
2179
2246
 
2180
2247
  numeric: simple_numeric
2181
- | tUMINUS_NUM simple_numeric
2248
+ | tUMINUS_NUM simple_numeric =tLOWEST
2182
2249
  {
2183
- result = -val[1] # TODO: pt_testcase
2250
+ _, (num, line) = val
2251
+ result = [-num, line]
2184
2252
  }
2185
2253
 
2186
2254
  simple_numeric: tINTEGER
@@ -2213,8 +2281,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2213
2281
 
2214
2282
  var_ref: user_variable
2215
2283
  {
2216
- var = val[0]
2284
+ raise "NO: #{val.inspect}" if Sexp === val.first
2285
+ (var, line), = val
2217
2286
  result = Sexp === var ? var : self.gettable(var)
2287
+ result.line line
2218
2288
  }
2219
2289
  | keyword_variable
2220
2290
  {
@@ -2229,11 +2299,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2229
2299
  | keyword_variable
2230
2300
  {
2231
2301
  result = self.assignable val[0]
2232
- debug20 29, val, result
2302
+ debug 40
2233
2303
  }
2234
2304
 
2235
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2236
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2305
+ backref: tNTH_REF
2306
+ {
2307
+ (ref, line), = val
2308
+ result = s(:nth_ref, ref).line line
2309
+ }
2310
+ | tBACK_REF
2311
+ {
2312
+ (ref, line), = val
2313
+ result = s(:back_ref, ref).line line
2314
+ }
2237
2315
 
2238
2316
  superclass: tLT
2239
2317
  {
@@ -2251,9 +2329,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2251
2329
 
2252
2330
  f_arglist: tLPAREN2 f_args rparen
2253
2331
  {
2254
- result = val[1]
2255
- self.lexer.lex_state = EXPR_BEG
2256
- self.lexer.command_start = true
2332
+ result = end_args val
2257
2333
  }
2258
2334
  | {
2259
2335
  result = self.in_kwarg
@@ -2262,12 +2338,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2262
2338
  }
2263
2339
  f_args term
2264
2340
  {
2265
- kwarg, args, _ = val
2266
-
2267
- self.in_kwarg = kwarg
2268
- result = args
2269
- lexer.lex_state = EXPR_BEG
2270
- lexer.command_start = true
2341
+ result = end_args val
2271
2342
  }
2272
2343
 
2273
2344
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2352,8 +2423,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2352
2423
  |
2353
2424
  {
2354
2425
  result = args val
2426
+ # result.line lexer.lineno
2355
2427
  }
2356
2428
 
2429
+
2357
2430
  f_bad_arg: tCONSTANT
2358
2431
  {
2359
2432
  yyerror "formal argument cannot be a constant"
@@ -2374,10 +2447,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2374
2447
  f_norm_arg: f_bad_arg
2375
2448
  | tIDENTIFIER
2376
2449
  {
2377
- identifier = val[0].to_sym
2450
+ (id, line), = val
2451
+ identifier = id.to_sym
2378
2452
  self.env[identifier] = :lvar
2379
2453
 
2380
- result = identifier
2454
+ result = [identifier, line]
2381
2455
  }
2382
2456
 
2383
2457
  f_arg_asgn: f_norm_arg
@@ -2385,22 +2459,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2385
2459
  f_arg_item: f_arg_asgn
2386
2460
  | tLPAREN f_margs rparen
2387
2461
  {
2388
- result = val[1]
2462
+ _, margs, _ = val
2463
+
2464
+ result = margs
2389
2465
  }
2390
2466
 
2391
2467
  f_arg: f_arg_item
2392
2468
  {
2393
- arg, = val
2394
-
2395
- case arg
2396
- when Symbol then
2397
- result = s(:args, arg).line lexer.lineno
2398
- when Sexp then
2399
- result = arg
2400
- else
2401
- debug20 32
2402
- raise "Unknown f_arg type: #{val.inspect}"
2403
- end
2469
+ result = new_arg val
2404
2470
  }
2405
2471
  | f_arg tCOMMA f_arg_item
2406
2472
  {
@@ -2412,7 +2478,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2412
2478
  result = s(:args, list).line list.line
2413
2479
  end
2414
2480
 
2415
- result << item
2481
+ result << (Sexp === item ? item : item.first)
2416
2482
  }
2417
2483
 
2418
2484
  f_label: tLABEL
@@ -2473,26 +2539,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2473
2539
  kwrest_mark: tPOW
2474
2540
  | tDSTAR
2475
2541
 
2542
+
2476
2543
  f_kwrest: kwrest_mark tIDENTIFIER
2477
2544
  {
2478
- name = val[1].to_sym
2479
- self.assignable name
2480
- result = :"**#{name}"
2545
+ _, (id, line) = val
2546
+
2547
+ name = id.to_sym
2548
+ self.assignable [name, line]
2549
+ result = [:"**#{name}", line]
2481
2550
  }
2482
2551
  | kwrest_mark
2483
2552
  {
2484
- result = :"**"
2553
+ id = :"**"
2554
+ self.env[id] = :lvar # TODO: needed?!?
2555
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2485
2556
  }
2486
2557
 
2487
2558
  f_opt: f_arg_asgn tEQL arg_value
2488
2559
  {
2489
- result = self.assignable val[0], val[2]
2560
+ lhs, _, rhs = val
2561
+ result = self.assignable lhs, rhs
2490
2562
  # TODO: detect duplicate names
2491
2563
  }
2492
2564
 
2493
2565
  f_block_opt: f_arg_asgn tEQL primary_value
2494
2566
  {
2495
- result = self.assignable val[0], val[2]
2567
+ lhs, _, rhs = val
2568
+ result = self.assignable lhs, rhs
2496
2569
  }
2497
2570
 
2498
2571
  f_block_optarg: f_block_opt
@@ -2522,30 +2595,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2522
2595
  f_rest_arg: restarg_mark tIDENTIFIER
2523
2596
  {
2524
2597
  # TODO: differs from parse.y - needs tests
2525
- name = val[1].to_sym
2526
- self.assignable name
2527
- result = :"*#{name}"
2598
+ _, (id, line) = val
2599
+ name = id.to_sym
2600
+ self.assignable [name, line]
2601
+ result = [:"*#{name}", line]
2528
2602
  }
2529
2603
  | restarg_mark
2530
2604
  {
2531
2605
  name = :"*"
2532
2606
  self.env[name] = :lvar
2533
- result = name
2607
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2534
2608
  }
2535
2609
 
2536
2610
  blkarg_mark: tAMPER2 | tAMPER
2537
2611
 
2538
2612
  f_block_arg: blkarg_mark tIDENTIFIER
2539
2613
  {
2540
- identifier = val[1].to_sym
2614
+ _, (id, line) = val
2615
+ identifier = id.to_sym
2541
2616
 
2542
2617
  self.env[identifier] = :lvar
2543
- result = "&#{identifier}".to_sym
2618
+ result = ["&#{identifier}".to_sym, line]
2544
2619
  }
2545
2620
 
2546
2621
  opt_f_block_arg: tCOMMA f_block_arg
2547
2622
  {
2548
- result = val[1]
2623
+ _, arg = val
2624
+ result = arg
2549
2625
  }
2550
2626
  |
2551
2627
  {
@@ -2587,16 +2663,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2587
2663
  }
2588
2664
  | tLABEL arg_value
2589
2665
  {
2590
- (label, line), arg = val
2666
+ label, arg = val
2591
2667
 
2592
- lit = s(:lit, label.to_sym).line line
2593
- result = s(:array, lit, arg).line line
2668
+ lit = wrap :lit, label
2669
+ result = s(:array, lit, arg).line lit.line
2594
2670
  }
2595
2671
  | tSTRING_BEG string_contents tLABEL_END arg_value
2596
2672
  {
2597
- _, sym, _, value = val
2673
+ (_, line), sym, _, value = val
2674
+
2598
2675
  sym.sexp_type = :dsym
2599
- result = s(:array, sym, value).line sym.line
2676
+
2677
+ result = s(:array, sym, value).line line
2600
2678
  }
2601
2679
  | tDSTAR arg_value
2602
2680
  {