ruby_parser 3.15.0 → 3.19.2

Sign up to get free protection for your applications and to get access to all the features.
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/ruby24_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
  {