ruby_parser 3.17.0 → 3.19.0

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 (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. metadata.gz.sig +0 -0
data/lib/ruby23_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
@@ -79,7 +79,7 @@ rule
79
79
  | klBEGIN
80
80
  {
81
81
  if (self.in_def || self.in_single > 0) then
82
- debug20 1
82
+ debug 11
83
83
  yyerror "BEGIN in method"
84
84
  end
85
85
  self.env.extend
@@ -104,7 +104,9 @@ rule
104
104
  bodystmt: compstmt opt_rescue k_else
105
105
  {
106
106
  res = _values[-2]
107
- 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
108
110
  }
109
111
  compstmt
110
112
  opt_ensure
@@ -134,7 +136,7 @@ rule
134
136
  | error stmt
135
137
  {
136
138
  result = val[1]
137
- debug20 2, val, result
139
+ debug 12
138
140
  }
139
141
 
140
142
  stmt_or_begin: stmt
@@ -142,6 +144,10 @@ rule
142
144
  {
143
145
  yyerror "BEGIN is permitted only at toplevel"
144
146
  }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
150
+ }
145
151
 
146
152
  stmt: kALIAS fitem
147
153
  {
@@ -154,12 +160,12 @@ rule
154
160
  }
155
161
  | kALIAS tGVAR tGVAR
156
162
  {
157
- (_, line), lhs, rhs = val
163
+ (_, line), (lhs, _), (rhs, _) = val
158
164
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
159
165
  }
160
166
  | kALIAS tGVAR tBACK_REF
161
167
  {
162
- (_, line), lhs, rhs = val
168
+ (_, line), (lhs, _), (rhs, _) = val
163
169
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
164
170
  }
165
171
  | kALIAS tGVAR tNTH_REF
@@ -202,7 +208,7 @@ rule
202
208
  (_, line), _, stmt, _ = val
203
209
 
204
210
  if (self.in_def || self.in_single > 0) then
205
- debug20 3
211
+ debug 13
206
212
  yyerror "END in method; use at_exit"
207
213
  end
208
214
 
@@ -242,32 +248,31 @@ rule
242
248
  }
243
249
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
244
250
  {
245
- prim, _, id, opasgn, rhs = val
246
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
247
- if val[1] == '&.'
248
- result.sexp_type = :safe_op_asgn
249
- end
250
- 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
251
256
  }
252
257
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
253
258
  {
254
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
255
- if val[1] == '&.'
256
- result.sexp_type = :safe_op_asgn
257
- end
258
- 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
259
264
  }
260
265
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
261
266
  {
262
- lhs1, _, lhs2, op, rhs = val
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
263
268
 
264
- 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
265
270
  }
266
271
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
267
272
  {
268
- lhs1, _, lhs2, op, rhs = val
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
269
274
 
270
- 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
271
276
  }
272
277
  | backref tOP_ASGN command_rhs
273
278
  {
@@ -305,7 +310,7 @@ rule
305
310
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
306
311
  # REFACTOR: call_uni_op -- see parse26.y
307
312
  }
308
- | arg
313
+ | arg =tLBRACE_ARG
309
314
 
310
315
  expr_value: expr
311
316
  {
@@ -330,7 +335,7 @@ rule
330
335
  block_command: block_call
331
336
  | block_call call_op2 operation2 command_args
332
337
  {
333
- blk, _, msg, args = val
338
+ blk, _, (msg, _line), args = val
334
339
  result = new_call(blk, msg.to_sym, args).line blk.line
335
340
  }
336
341
 
@@ -344,15 +349,15 @@ rule
344
349
  _, line, body, _ = val
345
350
 
346
351
  result = body
347
- result.line = line
352
+ result.line line
348
353
 
349
354
  # self.env.unextend
350
355
  }
351
356
 
352
357
  fcall: operation
353
358
  {
354
- msg, = val
355
- result = new_call(nil, msg.to_sym).line lexer.lineno
359
+ (msg, line), = val
360
+ result = new_call(nil, msg.to_sym).line line
356
361
  }
357
362
 
358
363
  command: fcall command_args =tLOWEST
@@ -375,12 +380,14 @@ rule
375
380
  }
376
381
  | primary_value call_op operation2 command_args =tLOWEST
377
382
  {
378
- lhs, callop, op, args = val
383
+ lhs, callop, (op, _), args = val
384
+
379
385
  result = new_call lhs, op.to_sym, args, callop
386
+ result.line lhs.line
380
387
  }
381
388
  | primary_value call_op operation2 command_args cmd_brace_block
382
389
  {
383
- recv, _, msg, args, block = val
390
+ recv, _, (msg, _line), args, block = val
384
391
  call = new_call recv, msg.to_sym, args, val[1]
385
392
 
386
393
  block_dup_check call, block
@@ -390,11 +397,14 @@ rule
390
397
  }
391
398
  | primary_value tCOLON2 operation2 command_args =tLOWEST
392
399
  {
393
- result = new_call val[0], val[2].to_sym, val[3]
400
+ lhs, _, (id, line), args = val
401
+
402
+ result = new_call lhs, id.to_sym, args
403
+ result.line line
394
404
  }
395
405
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
396
406
  {
397
- recv, _, msg, args, block = val
407
+ recv, _, (msg, _line), args, block = val
398
408
  call = new_call recv, msg.to_sym, args
399
409
 
400
410
  block_dup_check call, block
@@ -552,25 +562,29 @@ rule
552
562
  }
553
563
  | primary_value call_op tIDENTIFIER
554
564
  {
555
- result = new_attrasgn val[0], val[2], val[1]
565
+ lhs, call_op, (id, _line) = val
566
+
567
+ result = new_attrasgn lhs, id, call_op
556
568
  }
557
569
  | primary_value tCOLON2 tIDENTIFIER
558
570
  {
559
- recv, _, id = val
571
+ recv, _, (id, _line) = val
560
572
  result = new_attrasgn recv, id
561
573
  }
562
574
  | primary_value call_op tCONSTANT
563
575
  {
564
- result = new_attrasgn val[0], val[2], val[1]
576
+ lhs, call_op, (id, _line) = val
577
+
578
+ result = new_attrasgn lhs, id, call_op
565
579
  }
566
580
  | primary_value tCOLON2 tCONSTANT
567
581
  {
568
582
  if (self.in_def || self.in_single > 0) then
569
- debug20 7
583
+ debug 14
570
584
  yyerror "dynamic constant assignment"
571
585
  end
572
586
 
573
- expr, _, id = val
587
+ expr, _, (id, _line) = val
574
588
  l = expr.line
575
589
 
576
590
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -578,58 +592,65 @@ rule
578
592
  | tCOLON3 tCONSTANT
579
593
  {
580
594
  if (self.in_def || self.in_single > 0) then
581
- debug20 8
595
+ debug 15
582
596
  yyerror "dynamic constant assignment"
583
597
  end
584
598
 
585
- _, id = val
586
- l = lexer.lineno
599
+ _, (id, l) = val
587
600
 
588
601
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
589
602
  }
590
603
  | backref
591
604
  {
592
- self.backref_assign_error val[0]
605
+ ref, = val
606
+
607
+ self.backref_assign_error ref
593
608
  }
594
609
 
595
610
  lhs: user_variable
596
611
  {
597
- line = lexer.lineno
598
- result = self.assignable val[0]
599
- result.line = line
612
+ var, = val
613
+
614
+ result = self.assignable var
600
615
  }
601
616
  | keyword_variable
602
617
  {
603
- line = lexer.lineno
604
- result = self.assignable val[0]
605
- result.line = line
606
- debug20 9, val, result
618
+ var, = val
619
+
620
+ result = self.assignable var
621
+
622
+ debug 16
607
623
  }
608
624
  | primary_value tLBRACK2 opt_call_args rbracket
609
625
  {
610
626
  lhs, _, args, _ = val
627
+
611
628
  result = self.aryset lhs, args
612
629
  }
613
630
  | primary_value call_op tIDENTIFIER # REFACTOR
614
631
  {
615
- lhs, op, id = val
632
+ lhs, op, (id, _line) = val
633
+
616
634
  result = new_attrasgn lhs, id, op
617
635
  }
618
636
  | primary_value tCOLON2 tIDENTIFIER
619
637
  {
620
- lhs, _, id = val
638
+ lhs, _, (id, _line) = val
639
+
621
640
  result = new_attrasgn lhs, id
622
641
  }
623
642
  | primary_value call_op tCONSTANT # REFACTOR?
624
643
  {
625
- result = new_attrasgn val[0], val[2], val[1]
644
+ lhs, call_op, (id, _line) = val
645
+
646
+ result = new_attrasgn lhs, id, call_op
626
647
  }
627
648
  | primary_value tCOLON2 tCONSTANT
628
649
  {
629
- expr, _, id = val
650
+ expr, _, (id, _line) = val
630
651
 
631
652
  if (self.in_def || self.in_single > 0) then
632
- debug20 10
653
+ debug 17
633
654
  yyerror "dynamic constant assignment"
634
655
  end
635
656
 
@@ -638,14 +659,13 @@ rule
638
659
  }
639
660
  | tCOLON3 tCONSTANT
640
661
  {
641
- _, id = val
662
+ _, (id, l) = val
642
663
 
643
664
  if (self.in_def || self.in_single > 0) then
644
- debug20 11
665
+ debug 18
645
666
  yyerror "dynamic constant assignment"
646
667
  end
647
668
 
648
- l = lexer.lineno
649
669
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
650
670
  }
651
671
  | backref
@@ -661,16 +681,16 @@ rule
661
681
 
662
682
  cpath: tCOLON3 cname
663
683
  {
664
- _, name = val
665
- result = s(:colon3, name.to_sym).line lexer.lineno
684
+ result = wrap :colon3, val[1]
666
685
  }
667
686
  | cname
668
687
  {
669
- result = val[0].to_sym
688
+ (id, line), = val
689
+ result = [id.to_sym, line] # TODO: sexp?
670
690
  }
671
691
  | primary_value tCOLON2 cname
672
692
  {
673
- pval, _, name = val
693
+ pval, _, (name, _line) = val
674
694
 
675
695
  result = s(:colon2, pval, name.to_sym)
676
696
  result.line pval.line
@@ -680,24 +700,15 @@ rule
680
700
  | op
681
701
  {
682
702
  lexer.lex_state = EXPR_END
683
- result = val[0]
684
703
  }
685
704
 
686
705
  | reswords
687
- {
688
- (sym, _line), = val
689
- lexer.lex_state = EXPR_END
690
- result = sym
691
- }
692
-
693
- fsym: fname | symbol
694
706
 
695
- fitem: fsym
707
+ fitem: fname
696
708
  {
697
- id, = val
698
- result = s(:lit, id.to_sym).line lexer.lineno
709
+ result = wrap :lit, val[0]
699
710
  }
700
- | dsym
711
+ | symbol
701
712
 
702
713
  undef_list: fitem
703
714
  {
@@ -718,8 +729,6 @@ rule
718
729
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
719
730
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
720
731
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
721
- # TODO: tUBANG dead?
722
- | tUBANG
723
732
 
724
733
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
725
734
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -753,26 +762,22 @@ rule
753
762
  }
754
763
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
755
764
  {
756
- lhs, _, id, op, rhs = val
765
+ lhs, _, (id, _line), (op, _), rhs = val
757
766
 
758
767
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
759
768
  }
760
769
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
761
770
  {
762
- lhs1, _, lhs2, op, rhs = val
771
+ lhs1, _, (lhs2, _line), op, rhs = val
763
772
 
764
773
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
765
774
  result = new_const_op_asgn [lhs, op, rhs]
766
775
  }
767
- | tCOLON3 tCONSTANT
768
- {
769
- result = self.lexer.lineno
770
- }
771
- tOP_ASGN arg_rhs
776
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
772
777
  {
773
- _, lhs, line, op, rhs = val
778
+ _, lhs, op, rhs = val
774
779
 
775
- lhs = s(:colon3, lhs.to_sym).line line
780
+ lhs = wrap :colon3, lhs
776
781
  result = new_const_op_asgn [lhs, op, rhs]
777
782
  }
778
783
  | backref tOP_ASGN arg_rhs
@@ -784,7 +789,7 @@ rule
784
789
  | arg tDOT2 arg
785
790
  {
786
791
  v1, v2 = val[0], val[2]
787
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
792
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
788
793
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
789
794
  else
790
795
  result = s(:dot2, v1, v2).line v1.line
@@ -793,7 +798,7 @@ rule
793
798
  | arg tDOT3 arg
794
799
  {
795
800
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
801
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
802
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
798
803
  else
799
804
  result = s(:dot3, v1, v2).line v1.line
@@ -827,8 +832,9 @@ rule
827
832
  }
828
833
  | tUMINUS_NUM simple_numeric tPOW arg
829
834
  {
830
- lit = s(:lit, val[1]).line lexer.lineno
831
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
835
+ _, (num, line), _, arg = val
836
+ lit = s(:lit, num).line line
837
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
832
838
 
833
839
  }
834
840
  | tUPLUS arg
@@ -927,12 +933,12 @@ rule
927
933
 
928
934
  rel_expr: arg relop arg =tGT
929
935
  {
930
- lhs, op, rhs = val
936
+ lhs, (op, _), rhs = val
931
937
  result = new_call lhs, op.to_sym, argl(rhs)
932
938
  }
933
939
  | rel_expr relop arg =tGT
934
940
  {
935
- lhs, op, rhs = val
941
+ lhs, (op, _), rhs = val
936
942
  warn "comparison '%s' after comparison", op
937
943
  result = new_call lhs, op.to_sym, argl(rhs)
938
944
  }
@@ -1123,8 +1129,9 @@ rule
1123
1129
  | backref
1124
1130
  | tFID
1125
1131
  {
1126
- msg, = val
1132
+ (msg, line), = val
1127
1133
  result = new_call nil, msg.to_sym
1134
+ result.line line
1128
1135
  }
1129
1136
  | k_begin
1130
1137
  {
@@ -1166,15 +1173,13 @@ rule
1166
1173
  }
1167
1174
  | primary_value tCOLON2 tCONSTANT
1168
1175
  {
1169
- expr, _, id = val
1176
+ expr, _, (id, _line) = val
1170
1177
 
1171
1178
  result = s(:colon2, expr, id.to_sym).line expr.line
1172
1179
  }
1173
1180
  | tCOLON3 tCONSTANT
1174
1181
  {
1175
- _, id = val
1176
-
1177
- result = s(:colon3, id.to_sym).line lexer.lineno
1182
+ result = wrap :colon3, val[1]
1178
1183
  }
1179
1184
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1180
1185
  {
@@ -1198,15 +1203,21 @@ rule
1198
1203
  }
1199
1204
  | kYIELD tLPAREN2 call_args rparen
1200
1205
  {
1201
- result = new_yield val[2]
1206
+ (_, line), _, args, _ = val
1207
+
1208
+ result = new_yield(args).line line
1202
1209
  }
1203
1210
  | kYIELD tLPAREN2 rparen
1204
1211
  {
1205
- result = new_yield
1212
+ (_, line), _, _ = val
1213
+
1214
+ result = new_yield.line line
1206
1215
  }
1207
1216
  | kYIELD
1208
1217
  {
1209
- result = new_yield
1218
+ (_, line), = val
1219
+
1220
+ result = new_yield.line line
1210
1221
  }
1211
1222
  | kDEFINED opt_nl tLPAREN2 expr rparen
1212
1223
  {
@@ -1221,7 +1232,7 @@ rule
1221
1232
  }
1222
1233
  | kNOT tLPAREN2 rparen
1223
1234
  {
1224
- debug20 14, val, result
1235
+ debug 20
1225
1236
  }
1226
1237
  | fcall brace_block
1227
1238
  {
@@ -1239,9 +1250,10 @@ rule
1239
1250
  iter.insert 1, call # FIX
1240
1251
  result = iter
1241
1252
  }
1242
- | tLAMBDA lambda
1253
+ | lambda
1243
1254
  {
1244
- result = val[1] # TODO: fix lineno
1255
+ expr, = val
1256
+ result = expr
1245
1257
  }
1246
1258
  | k_if expr_value then compstmt if_tail k_end
1247
1259
  {
@@ -1284,7 +1296,6 @@ rule
1284
1296
  }
1285
1297
  cpath superclass
1286
1298
  {
1287
- self.comments.push self.lexer.comments
1288
1299
  if (self.in_def || self.in_single > 0) then
1289
1300
  yyerror "class definition in method body"
1290
1301
  end
@@ -1294,7 +1305,7 @@ rule
1294
1305
  {
1295
1306
  result = new_class val
1296
1307
  self.env.unextend
1297
- self.lexer.comments # we don't care about comments in the body
1308
+ self.lexer.ignore_body_comments
1298
1309
  }
1299
1310
  | k_class tLSHFT
1300
1311
  {
@@ -1315,7 +1326,7 @@ rule
1315
1326
  {
1316
1327
  result = new_sclass val
1317
1328
  self.env.unextend
1318
- self.lexer.comments # we don't care about comments in the body
1329
+ self.lexer.ignore_body_comments
1319
1330
  }
1320
1331
  | k_module
1321
1332
  {
@@ -1323,7 +1334,6 @@ rule
1323
1334
  }
1324
1335
  cpath
1325
1336
  {
1326
- self.comments.push self.lexer.comments
1327
1337
  yyerror "module definition in method body" if
1328
1338
  self.in_def or self.in_single > 0
1329
1339
 
@@ -1333,7 +1343,7 @@ rule
1333
1343
  {
1334
1344
  result = new_module val
1335
1345
  self.env.unextend
1336
- self.lexer.comments # we don't care about comments in the body
1346
+ self.lexer.ignore_body_comments
1337
1347
  }
1338
1348
  | k_def fname
1339
1349
  {
@@ -1343,21 +1353,17 @@ rule
1343
1353
  self.env.extend
1344
1354
  lexer.cmdarg.push false
1345
1355
  lexer.cond.push false
1346
-
1347
- self.comments.push self.lexer.comments
1348
1356
  }
1349
- f_arglist bodystmt { result = lexer.lineno } k_end
1357
+ f_arglist bodystmt k_end
1350
1358
  {
1351
- in_def = val[2]
1352
-
1353
- result = new_defn val
1359
+ result, in_def = new_defn val
1354
1360
 
1355
1361
  lexer.cond.pop # group = local_pop
1356
1362
  lexer.cmdarg.pop
1357
1363
  self.env.unextend
1358
1364
  self.in_def = in_def
1359
1365
 
1360
- self.lexer.comments # we don't care about comments in the body
1366
+ self.lexer.ignore_body_comments
1361
1367
  }
1362
1368
  | k_def singleton dot_or_colon
1363
1369
  {
@@ -1365,7 +1371,7 @@ rule
1365
1371
  }
1366
1372
  fname
1367
1373
  {
1368
- result = [self.in_def, lexer.lineno]
1374
+ result = self.in_def
1369
1375
 
1370
1376
  self.in_single += 1 # TODO: remove?
1371
1377
 
@@ -1375,13 +1381,18 @@ rule
1375
1381
  lexer.cond.push false
1376
1382
 
1377
1383
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1378
- self.comments.push self.lexer.comments
1379
1384
  }
1380
1385
  f_arglist bodystmt k_end
1381
1386
  {
1382
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1383
1387
 
1384
- result = new_defs val
1388
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1389
+ # =>
1390
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1391
+
1392
+ val.delete_at 3
1393
+ val.delete_at 2
1394
+
1395
+ result, in_def = new_defs val
1385
1396
 
1386
1397
  lexer.cond.pop # group = local_pop
1387
1398
  lexer.cmdarg.pop
@@ -1392,7 +1403,7 @@ rule
1392
1403
 
1393
1404
  # TODO: restore cur_arg ? what's cur_arg?
1394
1405
 
1395
- self.lexer.comments # we don't care about comments in the body
1406
+ self.lexer.ignore_body_comments
1396
1407
  }
1397
1408
  | kBREAK
1398
1409
  {
@@ -1429,8 +1440,17 @@ rule
1429
1440
  k_case: kCASE
1430
1441
  k_for: kFOR
1431
1442
  k_class: kCLASS
1443
+ {
1444
+ self.comments.push self.lexer.comments
1445
+ }
1432
1446
  k_module: kMODULE
1447
+ {
1448
+ self.comments.push self.lexer.comments
1449
+ }
1433
1450
  k_def: kDEF
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1434
1454
  k_do: kDO
1435
1455
  k_do_block: kDO_BLOCK
1436
1456
  k_rescue: kRESCUE
@@ -1491,51 +1511,42 @@ rule
1491
1511
 
1492
1512
  result = block_var args
1493
1513
  }
1494
- | f_marg_list tCOMMA tSTAR f_norm_arg
1514
+ | f_marg_list tCOMMA f_rest_marg
1495
1515
  {
1496
- args, _, _, splat = val
1516
+ args, _, rest = val
1497
1517
 
1498
- result = block_var args, "*#{splat}".to_sym
1518
+ result = block_var args, rest
1499
1519
  }
1500
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1520
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1501
1521
  {
1502
- args, _, _, splat, _, args2 = val
1522
+ lhs, _, splat, _, rhs = val
1503
1523
 
1504
- result = block_var args, "*#{splat}".to_sym, args2
1524
+ result = block_var lhs, splat, rhs
1505
1525
  }
1506
- | f_marg_list tCOMMA tSTAR
1526
+ | f_rest_marg
1507
1527
  {
1508
- args, _, _ = val
1528
+ rest, = val
1509
1529
 
1510
- result = block_var args, :*
1530
+ result = block_var rest
1511
1531
  }
1512
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1532
+ | f_rest_marg tCOMMA f_marg_list
1513
1533
  {
1514
- args, _, _, _, args2 = val
1534
+ splat, _, rest = val
1515
1535
 
1516
- result = block_var args, :*, args2
1536
+ result = block_var splat, rest
1517
1537
  }
1518
- | tSTAR f_norm_arg
1519
- {
1520
- _, splat = val
1521
1538
 
1522
- result = block_var :"*#{splat}"
1523
- }
1524
- | tSTAR f_norm_arg tCOMMA f_marg_list
1539
+ f_rest_marg: tSTAR f_norm_arg
1525
1540
  {
1526
- _, splat, _, args = val
1541
+ _, (id, line) = val
1527
1542
 
1528
- result = block_var :"*#{splat}", args
1543
+ result = args ["*#{id}".to_sym]
1544
+ result.line line
1529
1545
  }
1530
1546
  | tSTAR
1531
1547
  {
1532
- result = block_var :*
1533
- }
1534
- | tSTAR tCOMMA f_marg_list
1535
- {
1536
- _, _, args = val
1537
-
1538
- result = block_var :*, args
1548
+ result = args [:*]
1549
+ result.line lexer.lineno # FIX: tSTAR -> line
1539
1550
  }
1540
1551
 
1541
1552
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1552,8 +1563,8 @@ rule
1552
1563
  }
1553
1564
  | f_block_arg
1554
1565
  {
1555
- line = lexer.lineno
1556
- result = call_args val # TODO: push line down
1566
+ (id, line), = val
1567
+ result = call_args [id]
1557
1568
  result.line line
1558
1569
  }
1559
1570
 
@@ -1662,13 +1673,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1662
1673
 
1663
1674
  bvar: tIDENTIFIER
1664
1675
  {
1665
- id, = val
1666
- line = lexer.lineno
1667
- result = s(:shadow, id.to_sym).line line
1676
+ result = wrap :shadow, val[0]
1668
1677
  }
1669
1678
  | f_bad_arg
1670
1679
 
1671
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1672
1682
  self.env.extend :dynamic
1673
1683
  result = [lexer.lineno, lexer.lpar_beg]
1674
1684
  lexer.paren_nest += 1
@@ -1680,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1680
1690
  }
1681
1691
  lambda_body
1682
1692
  {
1683
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1684
1694
  lexer.lpar_beg = lpar
1685
1695
 
1686
1696
  lexer.cmdarg.pop
1687
1697
 
1688
1698
  call = s(:lambda).line line
1689
1699
  result = new_iter call, args, body
1690
- result.line = line
1700
+ result.line line
1691
1701
  self.env.unextend # TODO: dynapush & dynapop
1692
1702
  }
1693
1703
 
@@ -1722,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1722
1732
  ## if (nd_type($1) == NODE_YIELD) {
1723
1733
  ## compile_error(PARSER_ARG "block given to yield");
1724
1734
 
1725
- syntax_error "Both block arg and actual block given." if
1726
- val[0].block_pass?
1735
+ cmd, blk = val
1727
1736
 
1728
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1729
1739
 
1730
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1731
1744
 
1732
1745
  result = blk
1733
1746
  result.insert 1, cmd
1734
1747
  }
1735
1748
  | block_call call_op2 operation2 opt_paren_args
1736
1749
  {
1737
- result = new_call val[0], val[2].to_sym, val[3]
1750
+ lhs, _, (id, _line), args = val
1751
+
1752
+ result = new_call lhs, id.to_sym, args
1738
1753
  }
1739
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1740
1755
  {
1741
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1742
1757
 
1743
1758
  call = new_call iter1, name.to_sym, args
1744
1759
  iter2.insert 1, call
@@ -1747,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1747
1762
  }
1748
1763
  | block_call call_op2 operation2 command_args do_block
1749
1764
  {
1750
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1751
1766
 
1752
1767
  call = new_call iter1, name.to_sym, args
1753
1768
  iter2.insert 1, call
@@ -1755,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1755
1770
  result = iter2
1756
1771
  }
1757
1772
 
1758
- method_call: fcall
1773
+ method_call: fcall paren_args
1759
1774
  {
1760
- result = self.lexer.lineno
1761
- }
1762
- paren_args
1763
- {
1764
- call, lineno, args = val
1775
+ call, args = val
1765
1776
 
1766
1777
  result = call.concat args.sexp_body if args
1767
- result.line lineno
1768
1778
  }
1769
1779
  | primary_value call_op operation2 opt_paren_args
1770
1780
  {
1771
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1781
+ recv, call_op, (op, _line), args = val
1782
+
1783
+ result = new_call recv, op.to_sym, args, call_op
1772
1784
  }
1773
1785
  | primary_value tCOLON2 operation2 paren_args
1774
1786
  {
1775
- result = new_call val[0], val[2].to_sym, val[3]
1787
+ recv, _, (op, _line), args = val
1788
+
1789
+ result = new_call recv, op.to_sym, args
1776
1790
  }
1777
1791
  | primary_value tCOLON2 operation3
1778
1792
  {
1779
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1780
1796
  }
1781
1797
  | primary_value call_op paren_args
1782
1798
  {
@@ -1809,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1809
1825
  _, line, body, _ = val
1810
1826
 
1811
1827
  result = body
1812
- result.line = line
1828
+ result.line line
1813
1829
 
1814
1830
  self.env.unextend
1815
1831
  }
@@ -1823,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1823
1839
  _, line, body, _ = val
1824
1840
 
1825
1841
  result = body
1826
- result.line = line
1842
+ result.line line
1827
1843
 
1828
1844
  self.env.unextend
1829
1845
  }
@@ -1852,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1852
1868
  self.env.unextend
1853
1869
  }
1854
1870
 
1871
+ case_args: arg_value
1872
+ {
1873
+ arg, = val
1874
+
1875
+ result = s(:array, arg).line arg.line
1876
+ }
1877
+ | tSTAR arg_value
1878
+ {
1879
+ _, arg = val
1880
+
1881
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1882
+ }
1883
+ | case_args tCOMMA arg_value
1884
+ {
1885
+ args, _, id = val
1886
+
1887
+ result = self.list_append args, id
1888
+ }
1889
+ | case_args tCOMMA tSTAR arg_value
1890
+ {
1891
+ args, _, _, id = val
1892
+
1893
+ result = self.list_append args, s(:splat, id).line(id.line)
1894
+ }
1895
+
1855
1896
  case_body: k_when
1856
1897
  {
1857
1898
  result = self.lexer.lineno
1858
1899
  }
1859
- args then compstmt cases
1900
+ case_args then compstmt cases
1860
1901
  {
1861
1902
  result = new_when(val[2], val[4])
1862
- result.line = val[1]
1903
+ result.line val[1]
1863
1904
  result << val[5] if val[5]
1864
1905
  }
1865
1906
 
@@ -1905,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1905
1946
 
1906
1947
  literal: numeric
1907
1948
  {
1908
- line = lexer.lineno
1909
- result = s(:lit, val[0])
1910
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1911
1951
  }
1912
1952
  | symbol
1913
- {
1914
- line = lexer.lineno
1915
- result = s(:lit, val[0])
1916
- result.line = line
1917
- }
1918
- | dsym
1919
1953
 
1920
1954
  strings: string
1921
1955
  {
@@ -1926,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1926
1960
 
1927
1961
  string: tCHAR
1928
1962
  {
1929
- debug20 23, val, result
1963
+ debug 37
1930
1964
  }
1931
1965
  | string1
1932
1966
  | string string1
@@ -1936,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1936
1970
 
1937
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1938
1972
  {
1939
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1940
1974
 
1941
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1942
1976
 
1943
- result = str
1977
+ result = str.line line
1944
1978
  }
1945
1979
  | tSTRING
1946
1980
  {
@@ -1960,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1960
1994
 
1961
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1962
1996
  {
1963
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1964
2000
  }
1965
2001
  | tWORDS_BEG word_list tSTRING_END
1966
2002
  {
1967
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1968
2006
  }
1969
2007
 
1970
2008
  word_list: none
@@ -1984,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1984
2022
 
1985
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1986
2024
  {
1987
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1988
2028
  }
1989
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1990
2030
  {
1991
- _, line, list, _, = val
1992
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1993
2033
  result = list
1994
2034
  }
1995
2035
 
1996
2036
  symbol_list: none
1997
2037
  {
1998
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1999
2039
  }
2000
2040
  | symbol_list word tSPACE
2001
2041
  {
@@ -2005,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2005
2045
 
2006
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2007
2047
  {
2008
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2009
2051
  }
2010
2052
  | tQWORDS_BEG qword_list tSTRING_END
2011
2053
  {
2012
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2013
2057
  }
2014
2058
 
2015
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2016
2060
  {
2017
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2018
2064
  }
2019
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2020
2066
  {
2021
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2022
2070
  }
2023
2071
 
2024
2072
  qword_list: none
@@ -2041,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2041
2089
 
2042
2090
  string_contents: none
2043
2091
  {
2044
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2045
2094
  }
2046
2095
  | string_contents string_content
2047
2096
  {
@@ -2116,8 +2165,8 @@ regexp_contents: none
2116
2165
  lexer.brace_nest = brace_nest
2117
2166
  lexer.string_nest = string_nest
2118
2167
 
2119
- lexer.cmdarg.pop
2120
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2121
2170
 
2122
2171
  lexer.lex_state = oldlex_state
2123
2172
 
@@ -2132,29 +2181,42 @@ regexp_contents: none
2132
2181
  when nil then
2133
2182
  result = s(:evstr).line line
2134
2183
  else
2135
- debug20 25
2184
+ debug 38
2136
2185
  raise "unknown string body: #{stmt.inspect}"
2137
2186
  end
2138
2187
  }
2139
2188
 
2140
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2141
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2142
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2189
+ string_dvar: tGVAR
2190
+ {
2191
+ result = wrap :gvar, val[0]
2192
+ }
2193
+ | tIVAR
2194
+ {
2195
+ result = wrap :ivar, val[0]
2196
+ }
2197
+ | tCVAR
2198
+ {
2199
+ result = wrap :cvar, val[0]
2200
+ }
2143
2201
  | backref
2144
2202
 
2145
- symbol: tSYMBEG sym
2203
+ symbol: ssym
2204
+ | dsym
2205
+
2206
+ ssym: tSYMBEG sym
2146
2207
  {
2147
2208
  lexer.lex_state = EXPR_END
2148
- result = val[1].to_sym
2209
+ result = wrap :lit, val[1]
2149
2210
  }
2150
2211
  | tSYMBOL
2151
2212
  {
2152
- result = val[0].to_sym
2213
+ lexer.lex_state = EXPR_END
2214
+ result = wrap :lit, val[0]
2153
2215
  }
2154
2216
 
2155
2217
  sym: fname | tIVAR | tGVAR | tCVAR
2156
2218
 
2157
- dsym: tSYMBEG xstring_contents tSTRING_END
2219
+ dsym: tSYMBEG string_contents tSTRING_END
2158
2220
  {
2159
2221
  _, result, _ = val
2160
2222
 
@@ -2170,14 +2232,15 @@ regexp_contents: none
2170
2232
  when :evstr then
2171
2233
  result = s(:dsym, "", result).line result.line
2172
2234
  else
2173
- debug20 26, val, result
2235
+ debug 39
2174
2236
  end
2175
2237
  }
2176
2238
 
2177
2239
  numeric: simple_numeric
2178
- | tUMINUS_NUM simple_numeric
2240
+ | tUMINUS_NUM simple_numeric =tLOWEST
2179
2241
  {
2180
- result = -val[1] # TODO: pt_testcase
2242
+ _, (num, line) = val
2243
+ result = [-num, line]
2181
2244
  }
2182
2245
 
2183
2246
  simple_numeric: tINTEGER
@@ -2210,8 +2273,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2210
2273
 
2211
2274
  var_ref: user_variable
2212
2275
  {
2213
- var = val[0]
2276
+ raise "NO: #{val.inspect}" if Sexp === val.first
2277
+ (var, line), = val
2214
2278
  result = Sexp === var ? var : self.gettable(var)
2279
+ result.line line
2215
2280
  }
2216
2281
  | keyword_variable
2217
2282
  {
@@ -2226,11 +2291,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2226
2291
  | keyword_variable
2227
2292
  {
2228
2293
  result = self.assignable val[0]
2229
- debug20 29, val, result
2294
+ debug 40
2230
2295
  }
2231
2296
 
2232
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2233
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2297
+ backref: tNTH_REF
2298
+ {
2299
+ (ref, line), = val
2300
+ result = s(:nth_ref, ref).line line
2301
+ }
2302
+ | tBACK_REF
2303
+ {
2304
+ (ref, line), = val
2305
+ result = s(:back_ref, ref).line line
2306
+ }
2234
2307
 
2235
2308
  superclass: tLT
2236
2309
  {
@@ -2248,9 +2321,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2248
2321
 
2249
2322
  f_arglist: tLPAREN2 f_args rparen
2250
2323
  {
2251
- result = val[1]
2252
- self.lexer.lex_state = EXPR_BEG
2253
- self.lexer.command_start = true
2324
+ result = end_args val
2254
2325
  }
2255
2326
  | {
2256
2327
  result = self.in_kwarg
@@ -2259,12 +2330,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2259
2330
  }
2260
2331
  f_args term
2261
2332
  {
2262
- kwarg, args, _ = val
2263
-
2264
- self.in_kwarg = kwarg
2265
- result = args
2266
- lexer.lex_state = EXPR_BEG
2267
- lexer.command_start = true
2333
+ result = end_args val
2268
2334
  }
2269
2335
 
2270
2336
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2349,6 +2415,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2349
2415
  |
2350
2416
  {
2351
2417
  result = args val
2418
+ # result.line lexer.lineno
2352
2419
  }
2353
2420
 
2354
2421
 
@@ -2372,10 +2439,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2372
2439
  f_norm_arg: f_bad_arg
2373
2440
  | tIDENTIFIER
2374
2441
  {
2375
- identifier = val[0].to_sym
2442
+ (id, line), = val
2443
+ identifier = id.to_sym
2376
2444
  self.env[identifier] = :lvar
2377
2445
 
2378
- result = identifier
2446
+ result = [identifier, line]
2379
2447
  }
2380
2448
 
2381
2449
  f_arg_asgn: f_norm_arg
@@ -2383,22 +2451,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2383
2451
  f_arg_item: f_arg_asgn
2384
2452
  | tLPAREN f_margs rparen
2385
2453
  {
2386
- result = val[1]
2454
+ _, margs, _ = val
2455
+
2456
+ result = margs
2387
2457
  }
2388
2458
 
2389
2459
  f_arg: f_arg_item
2390
2460
  {
2391
- arg, = val
2392
-
2393
- case arg
2394
- when Symbol then
2395
- result = s(:args, arg).line lexer.lineno
2396
- when Sexp then
2397
- result = arg
2398
- else
2399
- debug20 32
2400
- raise "Unknown f_arg type: #{val.inspect}"
2401
- end
2461
+ result = new_arg val
2402
2462
  }
2403
2463
  | f_arg tCOMMA f_arg_item
2404
2464
  {
@@ -2410,7 +2470,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2410
2470
  result = s(:args, list).line list.line
2411
2471
  end
2412
2472
 
2413
- result << item
2473
+ result << (Sexp === item ? item : item.first)
2414
2474
  }
2415
2475
 
2416
2476
  f_label: tLABEL
@@ -2471,27 +2531,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2471
2531
  kwrest_mark: tPOW
2472
2532
  | tDSTAR
2473
2533
 
2534
+
2474
2535
  f_kwrest: kwrest_mark tIDENTIFIER
2475
2536
  {
2476
- name = val[1].to_sym
2477
- self.assignable name
2478
- result = :"**#{name}"
2537
+ _, (id, line) = val
2538
+
2539
+ name = id.to_sym
2540
+ self.assignable [name, line]
2541
+ result = [:"**#{name}", line]
2479
2542
  }
2480
2543
  | kwrest_mark
2481
2544
  {
2482
- result = :"**"
2483
- self.env[result] = :lvar
2545
+ id = :"**"
2546
+ self.env[id] = :lvar # TODO: needed?!?
2547
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2484
2548
  }
2485
2549
 
2486
2550
  f_opt: f_arg_asgn tEQL arg_value
2487
2551
  {
2488
- result = self.assignable val[0], val[2]
2552
+ lhs, _, rhs = val
2553
+ result = self.assignable lhs, rhs
2489
2554
  # TODO: detect duplicate names
2490
2555
  }
2491
2556
 
2492
2557
  f_block_opt: f_arg_asgn tEQL primary_value
2493
2558
  {
2494
- result = self.assignable val[0], val[2]
2559
+ lhs, _, rhs = val
2560
+ result = self.assignable lhs, rhs
2495
2561
  }
2496
2562
 
2497
2563
  f_block_optarg: f_block_opt
@@ -2521,30 +2587,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2521
2587
  f_rest_arg: restarg_mark tIDENTIFIER
2522
2588
  {
2523
2589
  # TODO: differs from parse.y - needs tests
2524
- name = val[1].to_sym
2525
- self.assignable name
2526
- result = :"*#{name}"
2590
+ _, (id, line) = val
2591
+ name = id.to_sym
2592
+ self.assignable [name, line]
2593
+ result = [:"*#{name}", line]
2527
2594
  }
2528
2595
  | restarg_mark
2529
2596
  {
2530
2597
  name = :"*"
2531
2598
  self.env[name] = :lvar
2532
- result = name
2599
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2533
2600
  }
2534
2601
 
2535
2602
  blkarg_mark: tAMPER2 | tAMPER
2536
2603
 
2537
2604
  f_block_arg: blkarg_mark tIDENTIFIER
2538
2605
  {
2539
- identifier = val[1].to_sym
2606
+ _, (id, line) = val
2607
+ identifier = id.to_sym
2540
2608
 
2541
2609
  self.env[identifier] = :lvar
2542
- result = "&#{identifier}".to_sym
2610
+ result = ["&#{identifier}".to_sym, line]
2543
2611
  }
2544
2612
 
2545
2613
  opt_f_block_arg: tCOMMA f_block_arg
2546
2614
  {
2547
- result = val[1]
2615
+ _, arg = val
2616
+ result = arg
2548
2617
  }
2549
2618
  |
2550
2619
  {
@@ -2586,16 +2655,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2586
2655
  }
2587
2656
  | tLABEL arg_value
2588
2657
  {
2589
- (label, line), arg = val
2658
+ label, arg = val
2590
2659
 
2591
- lit = s(:lit, label.to_sym).line line
2592
- result = s(:array, lit, arg).line line
2660
+ lit = wrap :lit, label
2661
+ result = s(:array, lit, arg).line lit.line
2593
2662
  }
2594
2663
  | tSTRING_BEG string_contents tLABEL_END arg_value
2595
2664
  {
2596
- _, sym, _, value = val
2665
+ (_, line), sym, _, value = val
2666
+
2597
2667
  sym.sexp_type = :dsym
2598
- result = s(:array, sym, value).line sym.line
2668
+
2669
+ result = s(:array, sym, value).line line
2599
2670
  }
2600
2671
  | tDSTAR arg_value
2601
2672
  {