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/ruby21_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
 
24
24
  preclow
@@ -31,7 +31,7 @@ preclow
31
31
  right tEQL tOP_ASGN
32
32
  left kRESCUE_MOD
33
33
  right tEH tCOLON
34
- nonassoc tDOT2 tDOT3
34
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
35
35
  left tOROP
36
36
  left tANDOP
37
37
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -54,6 +54,9 @@ rule
54
54
  top_compstmt
55
55
  {
56
56
  result = new_compstmt val
57
+
58
+ lexer.cond.pop # local_pop
59
+ lexer.cmdarg.pop
57
60
  }
58
61
 
59
62
  top_compstmt: top_stmts opt_terms
@@ -74,7 +77,7 @@ rule
74
77
  | klBEGIN
75
78
  {
76
79
  if (self.in_def || self.in_single > 0) then
77
- debug20 1
80
+ debug 11
78
81
  yyerror "BEGIN in method"
79
82
  end
80
83
  self.env.extend
@@ -99,7 +102,9 @@ rule
99
102
  bodystmt: compstmt opt_rescue k_else
100
103
  {
101
104
  res = _values[-2]
102
- yyerror "else without rescue is useless" unless res
105
+ # TODO: move down to main match so I can just use val
106
+
107
+ warn "else without rescue is useless" unless res
103
108
  }
104
109
  compstmt
105
110
  opt_ensure
@@ -129,7 +134,7 @@ rule
129
134
  | error stmt
130
135
  {
131
136
  result = val[1]
132
- debug20 2, val, result
137
+ debug 12
133
138
  }
134
139
 
135
140
  stmt_or_begin: stmt
@@ -137,6 +142,10 @@ rule
137
142
  {
138
143
  yyerror "BEGIN is permitted only at toplevel"
139
144
  }
145
+ begin_block
146
+ {
147
+ result = val[2] # wtf?
148
+ }
140
149
 
141
150
  stmt: kALIAS fitem
142
151
  {
@@ -149,12 +158,12 @@ rule
149
158
  }
150
159
  | kALIAS tGVAR tGVAR
151
160
  {
152
- (_, line), lhs, rhs = val
161
+ (_, line), (lhs, _), (rhs, _) = val
153
162
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
154
163
  }
155
164
  | kALIAS tGVAR tBACK_REF
156
165
  {
157
- (_, line), lhs, rhs = val
166
+ (_, line), (lhs, _), (rhs, _) = val
158
167
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
159
168
  }
160
169
  | kALIAS tGVAR tNTH_REF
@@ -197,7 +206,7 @@ rule
197
206
  (_, line), _, stmt, _ = val
198
207
 
199
208
  if (self.in_def || self.in_single > 0) then
200
- debug20 3
209
+ debug 13
201
210
  yyerror "END in method; use at_exit"
202
211
  end
203
212
 
@@ -237,32 +246,31 @@ rule
237
246
  }
238
247
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
239
248
  {
240
- prim, _, id, opasgn, rhs = val
241
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
242
- if val[1] == '&.'
243
- result.sexp_type = :safe_op_asgn
244
- end
245
- result.line = val[0].line
249
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
250
+
251
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
252
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
253
+ result.line prim.line
246
254
  }
247
255
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
248
256
  {
249
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
250
- if val[1] == '&.'
251
- result.sexp_type = :safe_op_asgn
252
- end
253
- result.line = val[0].line
257
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
258
+
259
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
260
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
261
+ result.line prim.line
254
262
  }
255
263
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
264
  {
257
- lhs1, _, lhs2, op, rhs = val
265
+ lhs1, _, (lhs2, line), (id, _), rhs = val
258
266
 
259
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
267
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
260
268
  }
261
269
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
262
270
  {
263
- lhs1, _, lhs2, op, rhs = val
271
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
272
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
273
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
274
  }
267
275
  | backref tOP_ASGN command_rhs
268
276
  {
@@ -300,7 +308,7 @@ rule
300
308
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
301
309
  # REFACTOR: call_uni_op -- see parse26.y
302
310
  }
303
- | arg
311
+ | arg =tLBRACE_ARG
304
312
 
305
313
  expr_value: expr
306
314
  {
@@ -325,7 +333,7 @@ rule
325
333
  block_command: block_call
326
334
  | block_call call_op2 operation2 command_args
327
335
  {
328
- blk, _, msg, args = val
336
+ blk, _, (msg, _line), args = val
329
337
  result = new_call(blk, msg.to_sym, args).line blk.line
330
338
  }
331
339
 
@@ -339,15 +347,15 @@ rule
339
347
  _, line, body, _ = val
340
348
 
341
349
  result = body
342
- result.line = line
350
+ result.line line
343
351
 
344
352
  # self.env.unextend
345
353
  }
346
354
 
347
355
  fcall: operation
348
356
  {
349
- msg, = val
350
- result = new_call(nil, msg.to_sym).line lexer.lineno
357
+ (msg, line), = val
358
+ result = new_call(nil, msg.to_sym).line line
351
359
  }
352
360
 
353
361
  command: fcall command_args =tLOWEST
@@ -370,12 +378,14 @@ rule
370
378
  }
371
379
  | primary_value call_op operation2 command_args =tLOWEST
372
380
  {
373
- lhs, callop, op, args = val
381
+ lhs, callop, (op, _), args = val
382
+
374
383
  result = new_call lhs, op.to_sym, args, callop
384
+ result.line lhs.line
375
385
  }
376
386
  | primary_value call_op operation2 command_args cmd_brace_block
377
387
  {
378
- recv, _, msg, args, block = val
388
+ recv, _, (msg, _line), args, block = val
379
389
  call = new_call recv, msg.to_sym, args, val[1]
380
390
 
381
391
  block_dup_check call, block
@@ -385,11 +395,14 @@ rule
385
395
  }
386
396
  | primary_value tCOLON2 operation2 command_args =tLOWEST
387
397
  {
388
- result = new_call val[0], val[2].to_sym, val[3]
398
+ lhs, _, (id, line), args = val
399
+
400
+ result = new_call lhs, id.to_sym, args
401
+ result.line line
389
402
  }
390
403
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
391
404
  {
392
- recv, _, msg, args, block = val
405
+ recv, _, (msg, _line), args, block = val
393
406
  call = new_call recv, msg.to_sym, args
394
407
 
395
408
  block_dup_check call, block
@@ -547,25 +560,29 @@ rule
547
560
  }
548
561
  | primary_value call_op tIDENTIFIER
549
562
  {
550
- result = new_attrasgn val[0], val[2], val[1]
563
+ lhs, call_op, (id, _line) = val
564
+
565
+ result = new_attrasgn lhs, id, call_op
551
566
  }
552
567
  | primary_value tCOLON2 tIDENTIFIER
553
568
  {
554
- recv, _, id = val
569
+ recv, _, (id, _line) = val
555
570
  result = new_attrasgn recv, id
556
571
  }
557
572
  | primary_value call_op tCONSTANT
558
573
  {
559
- result = new_attrasgn val[0], val[2], val[1]
574
+ lhs, call_op, (id, _line) = val
575
+
576
+ result = new_attrasgn lhs, id, call_op
560
577
  }
561
578
  | primary_value tCOLON2 tCONSTANT
562
579
  {
563
580
  if (self.in_def || self.in_single > 0) then
564
- debug20 7
581
+ debug 14
565
582
  yyerror "dynamic constant assignment"
566
583
  end
567
584
 
568
- expr, _, id = val
585
+ expr, _, (id, _line) = val
569
586
  l = expr.line
570
587
 
571
588
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -573,58 +590,65 @@ rule
573
590
  | tCOLON3 tCONSTANT
574
591
  {
575
592
  if (self.in_def || self.in_single > 0) then
576
- debug20 8
593
+ debug 15
577
594
  yyerror "dynamic constant assignment"
578
595
  end
579
596
 
580
- _, id = val
581
- l = lexer.lineno
597
+ _, (id, l) = val
582
598
 
583
599
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
584
600
  }
585
601
  | backref
586
602
  {
587
- self.backref_assign_error val[0]
603
+ ref, = val
604
+
605
+ self.backref_assign_error ref
588
606
  }
589
607
 
590
608
  lhs: user_variable
591
609
  {
592
- line = lexer.lineno
593
- result = self.assignable val[0]
594
- result.line = line
610
+ var, = val
611
+
612
+ result = self.assignable var
595
613
  }
596
614
  | keyword_variable
597
615
  {
598
- line = lexer.lineno
599
- result = self.assignable val[0]
600
- result.line = line
601
- debug20 9, val, result
616
+ var, = val
617
+
618
+ result = self.assignable var
619
+
620
+ debug 16
602
621
  }
603
622
  | primary_value tLBRACK2 opt_call_args rbracket
604
623
  {
605
624
  lhs, _, args, _ = val
625
+
606
626
  result = self.aryset lhs, args
607
627
  }
608
628
  | primary_value call_op tIDENTIFIER # REFACTOR
609
629
  {
610
- lhs, op, id = val
630
+ lhs, op, (id, _line) = val
631
+
611
632
  result = new_attrasgn lhs, id, op
612
633
  }
613
634
  | primary_value tCOLON2 tIDENTIFIER
614
635
  {
615
- lhs, _, id = val
636
+ lhs, _, (id, _line) = val
637
+
616
638
  result = new_attrasgn lhs, id
617
639
  }
618
640
  | primary_value call_op tCONSTANT # REFACTOR?
619
641
  {
620
- result = new_attrasgn val[0], val[2], val[1]
642
+ lhs, call_op, (id, _line) = val
643
+
644
+ result = new_attrasgn lhs, id, call_op
621
645
  }
622
646
  | primary_value tCOLON2 tCONSTANT
623
647
  {
624
- expr, _, id = val
648
+ expr, _, (id, _line) = val
625
649
 
626
650
  if (self.in_def || self.in_single > 0) then
627
- debug20 10
651
+ debug 17
628
652
  yyerror "dynamic constant assignment"
629
653
  end
630
654
 
@@ -633,14 +657,13 @@ rule
633
657
  }
634
658
  | tCOLON3 tCONSTANT
635
659
  {
636
- _, id = val
660
+ _, (id, l) = val
637
661
 
638
662
  if (self.in_def || self.in_single > 0) then
639
- debug20 11
663
+ debug 18
640
664
  yyerror "dynamic constant assignment"
641
665
  end
642
666
 
643
- l = lexer.lineno
644
667
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
645
668
  }
646
669
  | backref
@@ -656,16 +679,16 @@ rule
656
679
 
657
680
  cpath: tCOLON3 cname
658
681
  {
659
- _, name = val
660
- result = s(:colon3, name.to_sym).line lexer.lineno
682
+ result = wrap :colon3, val[1]
661
683
  }
662
684
  | cname
663
685
  {
664
- result = val[0].to_sym
686
+ (id, line), = val
687
+ result = [id.to_sym, line] # TODO: sexp?
665
688
  }
666
689
  | primary_value tCOLON2 cname
667
690
  {
668
- pval, _, name = val
691
+ pval, _, (name, _line) = val
669
692
 
670
693
  result = s(:colon2, pval, name.to_sym)
671
694
  result.line pval.line
@@ -675,24 +698,15 @@ rule
675
698
  | op
676
699
  {
677
700
  lexer.lex_state = EXPR_END
678
- result = val[0]
679
701
  }
680
702
 
681
703
  | reswords
682
- {
683
- (sym, _line), = val
684
- lexer.lex_state = EXPR_END
685
- result = sym
686
- }
687
-
688
- fsym: fname | symbol
689
704
 
690
- fitem: fsym
705
+ fitem: fname
691
706
  {
692
- id, = val
693
- result = s(:lit, id.to_sym).line lexer.lineno
707
+ result = wrap :lit, val[0]
694
708
  }
695
- | dsym
709
+ | symbol
696
710
 
697
711
  undef_list: fitem
698
712
  {
@@ -713,8 +727,6 @@ rule
713
727
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
714
728
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
715
729
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
716
- # TODO: tUBANG dead?
717
- | tUBANG
718
730
 
719
731
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
720
732
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -748,26 +760,22 @@ rule
748
760
  }
749
761
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
750
762
  {
751
- lhs, _, id, op, rhs = val
763
+ lhs, _, (id, _line), (op, _), rhs = val
752
764
 
753
765
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
754
766
  }
755
767
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
756
768
  {
757
- lhs1, _, lhs2, op, rhs = val
769
+ lhs1, _, (lhs2, _line), op, rhs = val
758
770
 
759
771
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
760
772
  result = new_const_op_asgn [lhs, op, rhs]
761
773
  }
762
- | tCOLON3 tCONSTANT
774
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
763
775
  {
764
- result = self.lexer.lineno
765
- }
766
- tOP_ASGN arg_rhs
767
- {
768
- _, lhs, line, op, rhs = val
776
+ _, lhs, op, rhs = val
769
777
 
770
- lhs = s(:colon3, lhs.to_sym).line line
778
+ lhs = wrap :colon3, lhs
771
779
  result = new_const_op_asgn [lhs, op, rhs]
772
780
  }
773
781
  | backref tOP_ASGN arg_rhs
@@ -779,7 +787,7 @@ rule
779
787
  | arg tDOT2 arg
780
788
  {
781
789
  v1, v2 = val[0], val[2]
782
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
790
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
783
791
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
784
792
  else
785
793
  result = s(:dot2, v1, v2).line v1.line
@@ -788,12 +796,14 @@ rule
788
796
  | arg tDOT3 arg
789
797
  {
790
798
  v1, v2 = val[0], val[2]
791
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
799
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
792
800
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
793
801
  else
794
802
  result = s(:dot3, v1, v2).line v1.line
795
803
  end
796
804
  }
805
+
806
+
797
807
  | arg tPLUS arg
798
808
  {
799
809
  result = new_call val[0], :+, argl(val[2])
@@ -820,8 +830,9 @@ rule
820
830
  }
821
831
  | tUMINUS_NUM simple_numeric tPOW arg
822
832
  {
823
- lit = s(:lit, val[1]).line lexer.lineno
824
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
833
+ _, (num, line), _, arg = val
834
+ lit = s(:lit, num).line line
835
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
825
836
 
826
837
  }
827
838
  | tUPLUS arg
@@ -920,12 +931,12 @@ rule
920
931
 
921
932
  rel_expr: arg relop arg =tGT
922
933
  {
923
- lhs, op, rhs = val
934
+ lhs, (op, _), rhs = val
924
935
  result = new_call lhs, op.to_sym, argl(rhs)
925
936
  }
926
937
  | rel_expr relop arg =tGT
927
938
  {
928
- lhs, op, rhs = val
939
+ lhs, (op, _), rhs = val
929
940
  warn "comparison '%s' after comparison", op
930
941
  result = new_call lhs, op.to_sym, argl(rhs)
931
942
  }
@@ -1116,8 +1127,9 @@ rule
1116
1127
  | backref
1117
1128
  | tFID
1118
1129
  {
1119
- msg, = val
1130
+ (msg, line), = val
1120
1131
  result = new_call nil, msg.to_sym
1132
+ result.line line
1121
1133
  }
1122
1134
  | k_begin
1123
1135
  {
@@ -1159,15 +1171,13 @@ rule
1159
1171
  }
1160
1172
  | primary_value tCOLON2 tCONSTANT
1161
1173
  {
1162
- expr, _, id = val
1174
+ expr, _, (id, _line) = val
1163
1175
 
1164
1176
  result = s(:colon2, expr, id.to_sym).line expr.line
1165
1177
  }
1166
1178
  | tCOLON3 tCONSTANT
1167
1179
  {
1168
- _, id = val
1169
-
1170
- result = s(:colon3, id.to_sym).line lexer.lineno
1180
+ result = wrap :colon3, val[1]
1171
1181
  }
1172
1182
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1173
1183
  {
@@ -1191,15 +1201,21 @@ rule
1191
1201
  }
1192
1202
  | kYIELD tLPAREN2 call_args rparen
1193
1203
  {
1194
- result = new_yield val[2]
1204
+ (_, line), _, args, _ = val
1205
+
1206
+ result = new_yield(args).line line
1195
1207
  }
1196
1208
  | kYIELD tLPAREN2 rparen
1197
1209
  {
1198
- result = new_yield
1210
+ (_, line), _, _ = val
1211
+
1212
+ result = new_yield.line line
1199
1213
  }
1200
1214
  | kYIELD
1201
1215
  {
1202
- result = new_yield
1216
+ (_, line), = val
1217
+
1218
+ result = new_yield.line line
1203
1219
  }
1204
1220
  | kDEFINED opt_nl tLPAREN2 expr rparen
1205
1221
  {
@@ -1214,7 +1230,7 @@ rule
1214
1230
  }
1215
1231
  | kNOT tLPAREN2 rparen
1216
1232
  {
1217
- debug20 14, val, result
1233
+ debug 20
1218
1234
  }
1219
1235
  | fcall brace_block
1220
1236
  {
@@ -1232,9 +1248,10 @@ rule
1232
1248
  iter.insert 1, call # FIX
1233
1249
  result = iter
1234
1250
  }
1235
- | tLAMBDA lambda
1251
+ | lambda
1236
1252
  {
1237
- result = val[1] # TODO: fix lineno
1253
+ expr, = val
1254
+ result = expr
1238
1255
  }
1239
1256
  | k_if expr_value then compstmt if_tail k_end
1240
1257
  {
@@ -1277,7 +1294,6 @@ rule
1277
1294
  }
1278
1295
  cpath superclass
1279
1296
  {
1280
- self.comments.push self.lexer.comments
1281
1297
  if (self.in_def || self.in_single > 0) then
1282
1298
  yyerror "class definition in method body"
1283
1299
  end
@@ -1287,7 +1303,7 @@ rule
1287
1303
  {
1288
1304
  result = new_class val
1289
1305
  self.env.unextend
1290
- self.lexer.comments # we don't care about comments in the body
1306
+ self.lexer.ignore_body_comments
1291
1307
  }
1292
1308
  | k_class tLSHFT
1293
1309
  {
@@ -1308,7 +1324,7 @@ rule
1308
1324
  {
1309
1325
  result = new_sclass val
1310
1326
  self.env.unextend
1311
- self.lexer.comments # we don't care about comments in the body
1327
+ self.lexer.ignore_body_comments
1312
1328
  }
1313
1329
  | k_module
1314
1330
  {
@@ -1316,7 +1332,6 @@ rule
1316
1332
  }
1317
1333
  cpath
1318
1334
  {
1319
- self.comments.push self.lexer.comments
1320
1335
  yyerror "module definition in method body" if
1321
1336
  self.in_def or self.in_single > 0
1322
1337
 
@@ -1326,7 +1341,7 @@ rule
1326
1341
  {
1327
1342
  result = new_module val
1328
1343
  self.env.unextend
1329
- self.lexer.comments # we don't care about comments in the body
1344
+ self.lexer.ignore_body_comments
1330
1345
  }
1331
1346
  | k_def fname
1332
1347
  {
@@ -1336,21 +1351,17 @@ rule
1336
1351
  self.env.extend
1337
1352
  lexer.cmdarg.push false
1338
1353
  lexer.cond.push false
1339
-
1340
- self.comments.push self.lexer.comments
1341
1354
  }
1342
- f_arglist bodystmt { result = lexer.lineno } k_end
1355
+ f_arglist bodystmt k_end
1343
1356
  {
1344
- in_def = val[2]
1345
-
1346
- result = new_defn val
1357
+ result, in_def = new_defn val
1347
1358
 
1348
1359
  lexer.cond.pop # group = local_pop
1349
1360
  lexer.cmdarg.pop
1350
1361
  self.env.unextend
1351
1362
  self.in_def = in_def
1352
1363
 
1353
- self.lexer.comments # we don't care about comments in the body
1364
+ self.lexer.ignore_body_comments
1354
1365
  }
1355
1366
  | k_def singleton dot_or_colon
1356
1367
  {
@@ -1358,7 +1369,7 @@ rule
1358
1369
  }
1359
1370
  fname
1360
1371
  {
1361
- result = [self.in_def, lexer.lineno]
1372
+ result = self.in_def
1362
1373
 
1363
1374
  self.in_single += 1 # TODO: remove?
1364
1375
 
@@ -1368,13 +1379,18 @@ rule
1368
1379
  lexer.cond.push false
1369
1380
 
1370
1381
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1371
- self.comments.push self.lexer.comments
1372
1382
  }
1373
1383
  f_arglist bodystmt k_end
1374
1384
  {
1375
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1376
1385
 
1377
- result = new_defs val
1386
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1387
+ # =>
1388
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1389
+
1390
+ val.delete_at 3
1391
+ val.delete_at 2
1392
+
1393
+ result, in_def = new_defs val
1378
1394
 
1379
1395
  lexer.cond.pop # group = local_pop
1380
1396
  lexer.cmdarg.pop
@@ -1385,7 +1401,7 @@ rule
1385
1401
 
1386
1402
  # TODO: restore cur_arg ? what's cur_arg?
1387
1403
 
1388
- self.lexer.comments # we don't care about comments in the body
1404
+ self.lexer.ignore_body_comments
1389
1405
  }
1390
1406
  | kBREAK
1391
1407
  {
@@ -1422,8 +1438,17 @@ rule
1422
1438
  k_case: kCASE
1423
1439
  k_for: kFOR
1424
1440
  k_class: kCLASS
1441
+ {
1442
+ self.comments.push self.lexer.comments
1443
+ }
1425
1444
  k_module: kMODULE
1445
+ {
1446
+ self.comments.push self.lexer.comments
1447
+ }
1426
1448
  k_def: kDEF
1449
+ {
1450
+ self.comments.push self.lexer.comments
1451
+ }
1427
1452
  k_do: kDO
1428
1453
  k_do_block: kDO_BLOCK
1429
1454
  k_rescue: kRESCUE
@@ -1484,51 +1509,42 @@ rule
1484
1509
 
1485
1510
  result = block_var args
1486
1511
  }
1487
- | f_marg_list tCOMMA tSTAR f_norm_arg
1512
+ | f_marg_list tCOMMA f_rest_marg
1488
1513
  {
1489
- args, _, _, splat = val
1514
+ args, _, rest = val
1490
1515
 
1491
- result = block_var args, "*#{splat}".to_sym
1516
+ result = block_var args, rest
1492
1517
  }
1493
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1518
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1494
1519
  {
1495
- args, _, _, splat, _, args2 = val
1520
+ lhs, _, splat, _, rhs = val
1496
1521
 
1497
- result = block_var args, "*#{splat}".to_sym, args2
1522
+ result = block_var lhs, splat, rhs
1498
1523
  }
1499
- | f_marg_list tCOMMA tSTAR
1524
+ | f_rest_marg
1500
1525
  {
1501
- args, _, _ = val
1526
+ rest, = val
1502
1527
 
1503
- result = block_var args, :*
1528
+ result = block_var rest
1504
1529
  }
1505
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1530
+ | f_rest_marg tCOMMA f_marg_list
1506
1531
  {
1507
- args, _, _, _, args2 = val
1532
+ splat, _, rest = val
1508
1533
 
1509
- result = block_var args, :*, args2
1534
+ result = block_var splat, rest
1510
1535
  }
1511
- | tSTAR f_norm_arg
1512
- {
1513
- _, splat = val
1514
1536
 
1515
- result = block_var :"*#{splat}"
1516
- }
1517
- | tSTAR f_norm_arg tCOMMA f_marg_list
1537
+ f_rest_marg: tSTAR f_norm_arg
1518
1538
  {
1519
- _, splat, _, args = val
1539
+ _, (id, line) = val
1520
1540
 
1521
- result = block_var :"*#{splat}", args
1541
+ result = args ["*#{id}".to_sym]
1542
+ result.line line
1522
1543
  }
1523
1544
  | tSTAR
1524
1545
  {
1525
- result = block_var :*
1526
- }
1527
- | tSTAR tCOMMA f_marg_list
1528
- {
1529
- _, _, args = val
1530
-
1531
- result = block_var :*, args
1546
+ result = args [:*]
1547
+ result.line lexer.lineno # FIX: tSTAR -> line
1532
1548
  }
1533
1549
 
1534
1550
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1545,8 +1561,8 @@ rule
1545
1561
  }
1546
1562
  | f_block_arg
1547
1563
  {
1548
- line = lexer.lineno
1549
- result = call_args val # TODO: push line down
1564
+ (id, line), = val
1565
+ result = call_args [id]
1550
1566
  result.line line
1551
1567
  }
1552
1568
 
@@ -1655,13 +1671,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1655
1671
 
1656
1672
  bvar: tIDENTIFIER
1657
1673
  {
1658
- id, = val
1659
- line = lexer.lineno
1660
- result = s(:shadow, id.to_sym).line line
1674
+ result = wrap :shadow, val[0]
1661
1675
  }
1662
1676
  | f_bad_arg
1663
1677
 
1664
- lambda: {
1678
+ lambda: tLAMBDA
1679
+ {
1665
1680
  self.env.extend :dynamic
1666
1681
  result = [lexer.lineno, lexer.lpar_beg]
1667
1682
  lexer.paren_nest += 1
@@ -1673,14 +1688,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1673
1688
  }
1674
1689
  lambda_body
1675
1690
  {
1676
- (line, lpar), args, _cmdarg, body = val
1691
+ _, (line, lpar), args, _cmdarg, body = val
1677
1692
  lexer.lpar_beg = lpar
1678
1693
 
1679
1694
  lexer.cmdarg.pop
1680
1695
 
1681
1696
  call = s(:lambda).line line
1682
1697
  result = new_iter call, args, body
1683
- result.line = line
1698
+ result.line line
1684
1699
  self.env.unextend # TODO: dynapush & dynapop
1685
1700
  }
1686
1701
 
@@ -1715,23 +1730,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1715
1730
  ## if (nd_type($1) == NODE_YIELD) {
1716
1731
  ## compile_error(PARSER_ARG "block given to yield");
1717
1732
 
1718
- syntax_error "Both block arg and actual block given." if
1719
- val[0].block_pass?
1733
+ cmd, blk = val
1720
1734
 
1721
- val = invert_block_call val if inverted? val
1735
+ syntax_error "Both block arg and actual block given." if
1736
+ cmd.block_pass?
1722
1737
 
1723
- cmd, blk = val
1738
+ if inverted? val then
1739
+ val = invert_block_call val
1740
+ cmd, blk = val
1741
+ end
1724
1742
 
1725
1743
  result = blk
1726
1744
  result.insert 1, cmd
1727
1745
  }
1728
1746
  | block_call call_op2 operation2 opt_paren_args
1729
1747
  {
1730
- result = new_call val[0], val[2].to_sym, val[3]
1748
+ lhs, _, (id, _line), args = val
1749
+
1750
+ result = new_call lhs, id.to_sym, args
1731
1751
  }
1732
1752
  | block_call call_op2 operation2 opt_paren_args brace_block
1733
1753
  {
1734
- iter1, _, name, args, iter2 = val
1754
+ iter1, _, (name, _line), args, iter2 = val
1735
1755
 
1736
1756
  call = new_call iter1, name.to_sym, args
1737
1757
  iter2.insert 1, call
@@ -1740,7 +1760,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1740
1760
  }
1741
1761
  | block_call call_op2 operation2 command_args do_block
1742
1762
  {
1743
- iter1, _, name, args, iter2 = val
1763
+ iter1, _, (name, _line), args, iter2 = val
1744
1764
 
1745
1765
  call = new_call iter1, name.to_sym, args
1746
1766
  iter2.insert 1, call
@@ -1748,28 +1768,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1748
1768
  result = iter2
1749
1769
  }
1750
1770
 
1751
- method_call: fcall
1771
+ method_call: fcall paren_args
1752
1772
  {
1753
- result = self.lexer.lineno
1754
- }
1755
- paren_args
1756
- {
1757
- call, lineno, args = val
1773
+ call, args = val
1758
1774
 
1759
1775
  result = call.concat args.sexp_body if args
1760
- result.line lineno
1761
1776
  }
1762
1777
  | primary_value call_op operation2 opt_paren_args
1763
1778
  {
1764
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1779
+ recv, call_op, (op, _line), args = val
1780
+
1781
+ result = new_call recv, op.to_sym, args, call_op
1765
1782
  }
1766
1783
  | primary_value tCOLON2 operation2 paren_args
1767
1784
  {
1768
- result = new_call val[0], val[2].to_sym, val[3]
1785
+ recv, _, (op, _line), args = val
1786
+
1787
+ result = new_call recv, op.to_sym, args
1769
1788
  }
1770
1789
  | primary_value tCOLON2 operation3
1771
1790
  {
1772
- result = new_call val[0], val[2].to_sym
1791
+ lhs, _, (id, _line) = val
1792
+
1793
+ result = new_call lhs, id.to_sym
1773
1794
  }
1774
1795
  | primary_value call_op paren_args
1775
1796
  {
@@ -1802,7 +1823,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1823
  _, line, body, _ = val
1803
1824
 
1804
1825
  result = body
1805
- result.line = line
1826
+ result.line line
1806
1827
 
1807
1828
  self.env.unextend
1808
1829
  }
@@ -1816,7 +1837,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1816
1837
  _, line, body, _ = val
1817
1838
 
1818
1839
  result = body
1819
- result.line = line
1840
+ result.line line
1820
1841
 
1821
1842
  self.env.unextend
1822
1843
  }
@@ -1845,14 +1866,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1845
1866
  self.env.unextend
1846
1867
  }
1847
1868
 
1869
+ case_args: arg_value
1870
+ {
1871
+ arg, = val
1872
+
1873
+ result = s(:array, arg).line arg.line
1874
+ }
1875
+ | tSTAR arg_value
1876
+ {
1877
+ _, arg = val
1878
+
1879
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1880
+ }
1881
+ | case_args tCOMMA arg_value
1882
+ {
1883
+ args, _, id = val
1884
+
1885
+ result = self.list_append args, id
1886
+ }
1887
+ | case_args tCOMMA tSTAR arg_value
1888
+ {
1889
+ args, _, _, id = val
1890
+
1891
+ result = self.list_append args, s(:splat, id).line(id.line)
1892
+ }
1893
+
1848
1894
  case_body: k_when
1849
1895
  {
1850
1896
  result = self.lexer.lineno
1851
1897
  }
1852
- args then compstmt cases
1898
+ case_args then compstmt cases
1853
1899
  {
1854
1900
  result = new_when(val[2], val[4])
1855
- result.line = val[1]
1901
+ result.line val[1]
1856
1902
  result << val[5] if val[5]
1857
1903
  }
1858
1904
 
@@ -1898,17 +1944,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
1944
 
1899
1945
  literal: numeric
1900
1946
  {
1901
- line = lexer.lineno
1902
- result = s(:lit, val[0])
1903
- result.line = line
1947
+ (lit, line), = val
1948
+ result = s(:lit, lit).line line
1904
1949
  }
1905
1950
  | symbol
1906
- {
1907
- line = lexer.lineno
1908
- result = s(:lit, val[0])
1909
- result.line = line
1910
- }
1911
- | dsym
1912
1951
 
1913
1952
  strings: string
1914
1953
  {
@@ -1919,7 +1958,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1919
1958
 
1920
1959
  string: tCHAR
1921
1960
  {
1922
- debug20 23, val, result
1961
+ debug 37
1923
1962
  }
1924
1963
  | string1
1925
1964
  | string string1
@@ -1929,11 +1968,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1929
1968
 
1930
1969
  string1: tSTRING_BEG string_contents tSTRING_END
1931
1970
  {
1932
- _, str, (_, func) = val
1971
+ (_, line), str, (_, func) = val
1933
1972
 
1934
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1973
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1935
1974
 
1936
- result = str
1975
+ result = str.line line
1937
1976
  }
1938
1977
  | tSTRING
1939
1978
  {
@@ -1953,11 +1992,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
1992
 
1954
1993
  words: tWORDS_BEG tSPACE tSTRING_END
1955
1994
  {
1956
- result = s(:array).line lexer.lineno
1995
+ (_, line), _, _ = val
1996
+
1997
+ result = s(:array).line line
1957
1998
  }
1958
1999
  | tWORDS_BEG word_list tSTRING_END
1959
2000
  {
1960
- result = val[1]
2001
+ (_, line), list, _ = val
2002
+
2003
+ result = list.line line
1961
2004
  }
1962
2005
 
1963
2006
  word_list: none
@@ -1977,18 +2020,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2020
 
1978
2021
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1979
2022
  {
1980
- result = s(:array).line lexer.lineno
2023
+ (_, line), _, _ = val
2024
+
2025
+ result = s(:array).line line
1981
2026
  }
1982
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2027
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1983
2028
  {
1984
- _, line, list, _, = val
1985
- list.line = line
2029
+ (_, line), list, _, = val
2030
+ list.line line
1986
2031
  result = list
1987
2032
  }
1988
2033
 
1989
2034
  symbol_list: none
1990
2035
  {
1991
- result = new_symbol_list.line lexer.lineno
2036
+ result = new_symbol_list
1992
2037
  }
1993
2038
  | symbol_list word tSPACE
1994
2039
  {
@@ -1998,20 +2043,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1998
2043
 
1999
2044
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2000
2045
  {
2001
- result = s(:array).line lexer.lineno
2046
+ (_, line), _, _ = val
2047
+
2048
+ result = s(:array).line line
2002
2049
  }
2003
2050
  | tQWORDS_BEG qword_list tSTRING_END
2004
2051
  {
2005
- result = val[1]
2052
+ (_, line), list, _ = val
2053
+
2054
+ result = list.line line
2006
2055
  }
2007
2056
 
2008
2057
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2009
2058
  {
2010
- result = s(:array).line lexer.lineno # FIX
2059
+ (_, line), _, _ = val
2060
+
2061
+ result = s(:array).line line
2011
2062
  }
2012
2063
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2013
2064
  {
2014
- result = val[1]
2065
+ (_, line), list, _ = val
2066
+
2067
+ result = list.line line
2015
2068
  }
2016
2069
 
2017
2070
  qword_list: none
@@ -2034,7 +2087,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2034
2087
 
2035
2088
  string_contents: none
2036
2089
  {
2037
- result = s(:str, "").line lexer.lineno
2090
+ line = prev_value_to_lineno _values.last
2091
+ result = s(:str, +"").line line
2038
2092
  }
2039
2093
  | string_contents string_content
2040
2094
  {
@@ -2109,8 +2163,8 @@ regexp_contents: none
2109
2163
  lexer.brace_nest = brace_nest
2110
2164
  lexer.string_nest = string_nest
2111
2165
 
2112
- lexer.cmdarg.pop
2113
2166
  lexer.cond.pop
2167
+ lexer.cmdarg.pop
2114
2168
 
2115
2169
  lexer.lex_state = oldlex_state
2116
2170
 
@@ -2125,29 +2179,42 @@ regexp_contents: none
2125
2179
  when nil then
2126
2180
  result = s(:evstr).line line
2127
2181
  else
2128
- debug20 25
2182
+ debug 38
2129
2183
  raise "unknown string body: #{stmt.inspect}"
2130
2184
  end
2131
2185
  }
2132
2186
 
2133
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2134
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2135
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2187
+ string_dvar: tGVAR
2188
+ {
2189
+ result = wrap :gvar, val[0]
2190
+ }
2191
+ | tIVAR
2192
+ {
2193
+ result = wrap :ivar, val[0]
2194
+ }
2195
+ | tCVAR
2196
+ {
2197
+ result = wrap :cvar, val[0]
2198
+ }
2136
2199
  | backref
2137
2200
 
2138
- symbol: tSYMBEG sym
2201
+ symbol: ssym
2202
+ | dsym
2203
+
2204
+ ssym: tSYMBEG sym
2139
2205
  {
2140
2206
  lexer.lex_state = EXPR_END
2141
- result = val[1].to_sym
2207
+ result = wrap :lit, val[1]
2142
2208
  }
2143
2209
  | tSYMBOL
2144
2210
  {
2145
- result = val[0].to_sym
2211
+ lexer.lex_state = EXPR_END
2212
+ result = wrap :lit, val[0]
2146
2213
  }
2147
2214
 
2148
2215
  sym: fname | tIVAR | tGVAR | tCVAR
2149
2216
 
2150
- dsym: tSYMBEG xstring_contents tSTRING_END
2217
+ dsym: tSYMBEG string_contents tSTRING_END
2151
2218
  {
2152
2219
  _, result, _ = val
2153
2220
 
@@ -2163,14 +2230,15 @@ regexp_contents: none
2163
2230
  when :evstr then
2164
2231
  result = s(:dsym, "", result).line result.line
2165
2232
  else
2166
- debug20 26, val, result
2233
+ debug 39
2167
2234
  end
2168
2235
  }
2169
2236
 
2170
2237
  numeric: simple_numeric
2171
- | tUMINUS_NUM simple_numeric
2238
+ | tUMINUS_NUM simple_numeric =tLOWEST
2172
2239
  {
2173
- result = -val[1] # TODO: pt_testcase
2240
+ _, (num, line) = val
2241
+ result = [-num, line]
2174
2242
  }
2175
2243
 
2176
2244
  simple_numeric: tINTEGER
@@ -2203,8 +2271,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2203
2271
 
2204
2272
  var_ref: user_variable
2205
2273
  {
2206
- var = val[0]
2274
+ raise "NO: #{val.inspect}" if Sexp === val.first
2275
+ (var, line), = val
2207
2276
  result = Sexp === var ? var : self.gettable(var)
2277
+ result.line line
2208
2278
  }
2209
2279
  | keyword_variable
2210
2280
  {
@@ -2219,11 +2289,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2219
2289
  | keyword_variable
2220
2290
  {
2221
2291
  result = self.assignable val[0]
2222
- debug20 29, val, result
2292
+ debug 40
2223
2293
  }
2224
2294
 
2225
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2226
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2295
+ backref: tNTH_REF
2296
+ {
2297
+ (ref, line), = val
2298
+ result = s(:nth_ref, ref).line line
2299
+ }
2300
+ | tBACK_REF
2301
+ {
2302
+ (ref, line), = val
2303
+ result = s(:back_ref, ref).line line
2304
+ }
2227
2305
 
2228
2306
  superclass: tLT
2229
2307
  {
@@ -2241,9 +2319,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2241
2319
 
2242
2320
  f_arglist: tLPAREN2 f_args rparen
2243
2321
  {
2244
- result = val[1]
2245
- self.lexer.lex_state = EXPR_BEG
2246
- self.lexer.command_start = true
2322
+ result = end_args val
2247
2323
  }
2248
2324
  | {
2249
2325
  result = self.in_kwarg
@@ -2252,12 +2328,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2252
2328
  }
2253
2329
  f_args term
2254
2330
  {
2255
- kwarg, args, _ = val
2256
-
2257
- self.in_kwarg = kwarg
2258
- result = args
2259
- lexer.lex_state = EXPR_BEG
2260
- lexer.command_start = true
2331
+ result = end_args val
2261
2332
  }
2262
2333
 
2263
2334
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2342,8 +2413,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2342
2413
  |
2343
2414
  {
2344
2415
  result = args val
2416
+ # result.line lexer.lineno
2345
2417
  }
2346
2418
 
2419
+
2347
2420
  f_bad_arg: tCONSTANT
2348
2421
  {
2349
2422
  yyerror "formal argument cannot be a constant"
@@ -2364,31 +2437,24 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2364
2437
  f_norm_arg: f_bad_arg
2365
2438
  | tIDENTIFIER
2366
2439
  {
2367
- identifier = val[0].to_sym
2440
+ (id, line), = val
2441
+ identifier = id.to_sym
2368
2442
  self.env[identifier] = :lvar
2369
2443
 
2370
- result = identifier
2444
+ result = [identifier, line]
2371
2445
  }
2372
2446
 
2373
2447
  f_arg_item: f_norm_arg
2374
2448
  | tLPAREN f_margs rparen
2375
2449
  {
2376
- result = val[1]
2450
+ _, margs, _ = val
2451
+
2452
+ result = margs
2377
2453
  }
2378
2454
 
2379
2455
  f_arg: f_arg_item
2380
2456
  {
2381
- arg, = val
2382
-
2383
- case arg
2384
- when Symbol then
2385
- result = s(:args, arg).line lexer.lineno
2386
- when Sexp then
2387
- result = arg
2388
- else
2389
- debug20 32
2390
- raise "Unknown f_arg type: #{val.inspect}"
2391
- end
2457
+ result = new_arg val
2392
2458
  }
2393
2459
  | f_arg tCOMMA f_arg_item
2394
2460
  {
@@ -2400,7 +2466,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2400
2466
  result = s(:args, list).line list.line
2401
2467
  end
2402
2468
 
2403
- result << item
2469
+ result << (Sexp === item ? item : item.first)
2404
2470
  }
2405
2471
 
2406
2472
  f_label: tLABEL
@@ -2461,26 +2527,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2461
2527
  kwrest_mark: tPOW
2462
2528
  | tDSTAR
2463
2529
 
2530
+
2464
2531
  f_kwrest: kwrest_mark tIDENTIFIER
2465
2532
  {
2466
- name = val[1].to_sym
2467
- self.assignable name
2468
- result = :"**#{name}"
2533
+ _, (id, line) = val
2534
+
2535
+ name = id.to_sym
2536
+ self.assignable [name, line]
2537
+ result = [:"**#{name}", line]
2469
2538
  }
2470
2539
  | kwrest_mark
2471
2540
  {
2472
- result = :"**"
2541
+ id = :"**"
2542
+ self.env[id] = :lvar # TODO: needed?!?
2543
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2473
2544
  }
2474
2545
 
2475
2546
  f_opt: f_norm_arg tEQL arg_value
2476
2547
  {
2477
- result = self.assignable val[0], val[2]
2548
+ lhs, _, rhs = val
2549
+ result = self.assignable lhs, rhs
2478
2550
  # TODO: detect duplicate names
2479
2551
  }
2480
2552
 
2481
2553
  f_block_opt: f_norm_arg tEQL primary_value
2482
2554
  {
2483
- result = self.assignable val[0], val[2]
2555
+ lhs, _, rhs = val
2556
+ result = self.assignable lhs, rhs
2484
2557
  }
2485
2558
 
2486
2559
  f_block_optarg: f_block_opt
@@ -2510,30 +2583,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2510
2583
  f_rest_arg: restarg_mark tIDENTIFIER
2511
2584
  {
2512
2585
  # TODO: differs from parse.y - needs tests
2513
- name = val[1].to_sym
2514
- self.assignable name
2515
- result = :"*#{name}"
2586
+ _, (id, line) = val
2587
+ name = id.to_sym
2588
+ self.assignable [name, line]
2589
+ result = [:"*#{name}", line]
2516
2590
  }
2517
2591
  | restarg_mark
2518
2592
  {
2519
2593
  name = :"*"
2520
2594
  self.env[name] = :lvar
2521
- result = name
2595
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2522
2596
  }
2523
2597
 
2524
2598
  blkarg_mark: tAMPER2 | tAMPER
2525
2599
 
2526
2600
  f_block_arg: blkarg_mark tIDENTIFIER
2527
2601
  {
2528
- identifier = val[1].to_sym
2602
+ _, (id, line) = val
2603
+ identifier = id.to_sym
2529
2604
 
2530
2605
  self.env[identifier] = :lvar
2531
- result = "&#{identifier}".to_sym
2606
+ result = ["&#{identifier}".to_sym, line]
2532
2607
  }
2533
2608
 
2534
2609
  opt_f_block_arg: tCOMMA f_block_arg
2535
2610
  {
2536
- result = val[1]
2611
+ _, arg = val
2612
+ result = arg
2537
2613
  }
2538
2614
  |
2539
2615
  {
@@ -2575,10 +2651,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2575
2651
  }
2576
2652
  | tLABEL arg_value
2577
2653
  {
2578
- (label, line), arg = val
2654
+ label, arg = val
2579
2655
 
2580
- lit = s(:lit, label.to_sym).line line
2581
- result = s(:array, lit, arg).line line
2656
+ lit = wrap :lit, label
2657
+ result = s(:array, lit, arg).line lit.line
2582
2658
  }
2583
2659
  | tDSTAR arg_value
2584
2660
  {