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/ruby26_parser.y CHANGED
@@ -18,10 +18,11 @@ 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
25
+ tBDOT2 tBDOT3
25
26
 
26
27
  preclow
27
28
  nonassoc tLOWEST
@@ -33,7 +34,7 @@ preclow
33
34
  right tEQL tOP_ASGN
34
35
  left kRESCUE_MOD
35
36
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
38
  left tOROP
38
39
  left tANDOP
39
40
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +57,9 @@ rule
56
57
  top_compstmt
57
58
  {
58
59
  result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
59
63
  }
60
64
 
61
65
  top_compstmt: top_stmts opt_terms
@@ -76,7 +80,7 @@ rule
76
80
  | klBEGIN
77
81
  {
78
82
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
83
+ debug 11
80
84
  yyerror "BEGIN in method"
81
85
  end
82
86
  self.env.extend
@@ -101,6 +105,8 @@ rule
101
105
  bodystmt: compstmt opt_rescue k_else
102
106
  {
103
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
104
110
  yyerror "else without rescue is useless" unless res
105
111
  }
106
112
  compstmt
@@ -131,7 +137,7 @@ rule
131
137
  | error stmt
132
138
  {
133
139
  result = val[1]
134
- debug20 2, val, result
140
+ debug 12
135
141
  }
136
142
 
137
143
  stmt_or_begin: stmt
@@ -139,6 +145,10 @@ rule
139
145
  {
140
146
  yyerror "BEGIN is permitted only at toplevel"
141
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
142
152
 
143
153
  stmt: kALIAS fitem
144
154
  {
@@ -151,12 +161,12 @@ rule
151
161
  }
152
162
  | kALIAS tGVAR tGVAR
153
163
  {
154
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
155
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
166
  }
157
167
  | kALIAS tGVAR tBACK_REF
158
168
  {
159
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
160
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
171
  }
162
172
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +209,7 @@ rule
199
209
  (_, line), _, stmt, _ = val
200
210
 
201
211
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
212
+ debug 13
203
213
  yyerror "END in method; use at_exit"
204
214
  end
205
215
 
@@ -239,32 +249,31 @@ rule
239
249
  }
240
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
251
  {
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
252
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
253
+
254
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
255
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
256
+ result.line prim.line
248
257
  }
249
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
259
  {
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
260
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
261
+
262
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
263
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
264
+ result.line prim.line
256
265
  }
257
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
267
  {
259
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
269
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
270
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
271
  }
263
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
273
  {
265
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
275
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
276
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
277
  }
269
278
  | backref tOP_ASGN command_rhs
270
279
  {
@@ -310,7 +319,7 @@ rule
310
319
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
320
  # REFACTOR: call_uni_op -- see parse26.y
312
321
  }
313
- | arg
322
+ | arg =tLBRACE_ARG
314
323
 
315
324
  expr_value: expr
316
325
  {
@@ -335,7 +344,7 @@ rule
335
344
  block_command: block_call
336
345
  | block_call call_op2 operation2 command_args
337
346
  {
338
- blk, _, msg, args = val
347
+ blk, _, (msg, _line), args = val
339
348
  result = new_call(blk, msg.to_sym, args).line blk.line
340
349
  }
341
350
 
@@ -349,15 +358,15 @@ rule
349
358
  _, line, body, _ = val
350
359
 
351
360
  result = body
352
- result.line = line
361
+ result.line line
353
362
 
354
363
  # self.env.unextend
355
364
  }
356
365
 
357
366
  fcall: operation
358
367
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
368
+ (msg, line), = val
369
+ result = new_call(nil, msg.to_sym).line line
361
370
  }
362
371
 
363
372
  command: fcall command_args =tLOWEST
@@ -380,12 +389,14 @@ rule
380
389
  }
381
390
  | primary_value call_op operation2 command_args =tLOWEST
382
391
  {
383
- lhs, callop, op, args = val
392
+ lhs, callop, (op, _), args = val
393
+
384
394
  result = new_call lhs, op.to_sym, args, callop
395
+ result.line lhs.line
385
396
  }
386
397
  | primary_value call_op operation2 command_args cmd_brace_block
387
398
  {
388
- recv, _, msg, args, block = val
399
+ recv, _, (msg, _line), args, block = val
389
400
  call = new_call recv, msg.to_sym, args, val[1]
390
401
 
391
402
  block_dup_check call, block
@@ -395,11 +406,14 @@ rule
395
406
  }
396
407
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
408
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
409
+ lhs, _, (id, line), args = val
410
+
411
+ result = new_call lhs, id.to_sym, args
412
+ result.line line
399
413
  }
400
414
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
415
  {
402
- recv, _, msg, args, block = val
416
+ recv, _, (msg, _line), args, block = val
403
417
  call = new_call recv, msg.to_sym, args
404
418
 
405
419
  block_dup_check call, block
@@ -557,25 +571,29 @@ rule
557
571
  }
558
572
  | primary_value call_op tIDENTIFIER
559
573
  {
560
- 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
561
577
  }
562
578
  | primary_value tCOLON2 tIDENTIFIER
563
579
  {
564
- recv, _, id = val
580
+ recv, _, (id, _line) = val
565
581
  result = new_attrasgn recv, id
566
582
  }
567
583
  | primary_value call_op tCONSTANT
568
584
  {
569
- result = new_attrasgn val[0], val[2], val[1]
585
+ lhs, call_op, (id, _line) = val
586
+
587
+ result = new_attrasgn lhs, id, call_op
570
588
  }
571
589
  | primary_value tCOLON2 tCONSTANT
572
590
  {
573
591
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
592
+ debug 14
575
593
  yyerror "dynamic constant assignment"
576
594
  end
577
595
 
578
- expr, _, id = val
596
+ expr, _, (id, _line) = val
579
597
  l = expr.line
580
598
 
581
599
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +601,65 @@ rule
583
601
  | tCOLON3 tCONSTANT
584
602
  {
585
603
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
604
+ debug 15
587
605
  yyerror "dynamic constant assignment"
588
606
  end
589
607
 
590
- _, id = val
591
- l = lexer.lineno
608
+ _, (id, l) = val
592
609
 
593
610
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
611
  }
595
612
  | backref
596
613
  {
597
- self.backref_assign_error val[0]
614
+ ref, = val
615
+
616
+ self.backref_assign_error ref
598
617
  }
599
618
 
600
619
  lhs: user_variable
601
620
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
621
+ var, = val
622
+
623
+ result = self.assignable var
605
624
  }
606
625
  | keyword_variable
607
626
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
627
+ var, = val
628
+
629
+ result = self.assignable var
630
+
631
+ debug 16
612
632
  }
613
633
  | primary_value tLBRACK2 opt_call_args rbracket
614
634
  {
615
635
  lhs, _, args, _ = val
636
+
616
637
  result = self.aryset lhs, args
617
638
  }
618
639
  | primary_value call_op tIDENTIFIER # REFACTOR
619
640
  {
620
- lhs, op, id = val
641
+ lhs, op, (id, _line) = val
642
+
621
643
  result = new_attrasgn lhs, id, op
622
644
  }
623
645
  | primary_value tCOLON2 tIDENTIFIER
624
646
  {
625
- lhs, _, id = val
647
+ lhs, _, (id, _line) = val
648
+
626
649
  result = new_attrasgn lhs, id
627
650
  }
628
651
  | primary_value call_op tCONSTANT # REFACTOR?
629
652
  {
630
- result = new_attrasgn val[0], val[2], val[1]
653
+ lhs, call_op, (id, _line) = val
654
+
655
+ result = new_attrasgn lhs, id, call_op
631
656
  }
632
657
  | primary_value tCOLON2 tCONSTANT
633
658
  {
634
- expr, _, id = val
659
+ expr, _, (id, _line) = val
635
660
 
636
661
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
662
+ debug 17
638
663
  yyerror "dynamic constant assignment"
639
664
  end
640
665
 
@@ -643,14 +668,13 @@ rule
643
668
  }
644
669
  | tCOLON3 tCONSTANT
645
670
  {
646
- _, id = val
671
+ _, (id, l) = val
647
672
 
648
673
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
674
+ debug 18
650
675
  yyerror "dynamic constant assignment"
651
676
  end
652
677
 
653
- l = lexer.lineno
654
678
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
679
  }
656
680
  | backref
@@ -666,16 +690,16 @@ rule
666
690
 
667
691
  cpath: tCOLON3 cname
668
692
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
693
+ result = wrap :colon3, val[1]
671
694
  }
672
695
  | cname
673
696
  {
674
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
675
699
  }
676
700
  | primary_value tCOLON2 cname
677
701
  {
678
- pval, _, name = val
702
+ pval, _, (name, _line) = val
679
703
 
680
704
  result = s(:colon2, pval, name.to_sym)
681
705
  result.line pval.line
@@ -685,24 +709,15 @@ rule
685
709
  | op
686
710
  {
687
711
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
712
  }
690
713
 
691
714
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
715
 
698
- fsym: fname | symbol
699
-
700
- fitem: fsym
716
+ fitem: fname
701
717
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
718
+ result = wrap :lit, val[0]
704
719
  }
705
- | dsym
720
+ | symbol
706
721
 
707
722
  undef_list: fitem
708
723
  {
@@ -723,8 +738,6 @@ rule
723
738
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
739
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
740
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
741
 
729
742
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
743
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,26 +771,22 @@ rule
758
771
  }
759
772
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
773
  {
761
- lhs, _, id, op, rhs = val
774
+ lhs, _, (id, _line), (op, _), rhs = val
762
775
 
763
776
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
777
  }
765
778
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
779
  {
767
- lhs1, _, lhs2, op, rhs = val
780
+ lhs1, _, (lhs2, _line), op, rhs = val
768
781
 
769
782
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
783
  result = new_const_op_asgn [lhs, op, rhs]
771
784
  }
772
- | tCOLON3 tCONSTANT
785
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
786
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
787
+ _, lhs, op, rhs = val
779
788
 
780
- lhs = s(:colon3, lhs.to_sym).line line
789
+ lhs = wrap :colon3, lhs
781
790
  result = new_const_op_asgn [lhs, op, rhs]
782
791
  }
783
792
  | backref tOP_ASGN arg_rhs
@@ -789,7 +798,7 @@ rule
789
798
  | arg tDOT2 arg
790
799
  {
791
800
  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
801
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
802
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
803
  else
795
804
  result = s(:dot2, v1, v2).line v1.line
@@ -798,7 +807,7 @@ rule
798
807
  | arg tDOT3 arg
799
808
  {
800
809
  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
810
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
811
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
812
  else
804
813
  result = s(:dot3, v1, v2).line v1.line
@@ -818,6 +827,8 @@ rule
818
827
 
819
828
  result = s(:dot3, v1, v2).line v1.line
820
829
  }
830
+
831
+
821
832
  | arg tPLUS arg
822
833
  {
823
834
  result = new_call val[0], :+, argl(val[2])
@@ -844,8 +855,9 @@ rule
844
855
  }
845
856
  | tUMINUS_NUM simple_numeric tPOW arg
846
857
  {
847
- lit = s(:lit, val[1]).line lexer.lineno
848
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
858
+ _, (num, line), _, arg = val
859
+ lit = s(:lit, num).line line
860
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
861
 
850
862
  }
851
863
  | tUPLUS arg
@@ -944,12 +956,12 @@ rule
944
956
 
945
957
  rel_expr: arg relop arg =tGT
946
958
  {
947
- lhs, op, rhs = val
959
+ lhs, (op, _), rhs = val
948
960
  result = new_call lhs, op.to_sym, argl(rhs)
949
961
  }
950
962
  | rel_expr relop arg =tGT
951
963
  {
952
- lhs, op, rhs = val
964
+ lhs, (op, _), rhs = val
953
965
  warn "comparison '%s' after comparison", op
954
966
  result = new_call lhs, op.to_sym, argl(rhs)
955
967
  }
@@ -1140,8 +1152,9 @@ rule
1140
1152
  | backref
1141
1153
  | tFID
1142
1154
  {
1143
- msg, = val
1155
+ (msg, line), = val
1144
1156
  result = new_call nil, msg.to_sym
1157
+ result.line line
1145
1158
  }
1146
1159
  | k_begin
1147
1160
  {
@@ -1183,15 +1196,13 @@ rule
1183
1196
  }
1184
1197
  | primary_value tCOLON2 tCONSTANT
1185
1198
  {
1186
- expr, _, id = val
1199
+ expr, _, (id, _line) = val
1187
1200
 
1188
1201
  result = s(:colon2, expr, id.to_sym).line expr.line
1189
1202
  }
1190
1203
  | tCOLON3 tCONSTANT
1191
1204
  {
1192
- _, id = val
1193
-
1194
- result = s(:colon3, id.to_sym).line lexer.lineno
1205
+ result = wrap :colon3, val[1]
1195
1206
  }
1196
1207
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1197
1208
  {
@@ -1215,15 +1226,21 @@ rule
1215
1226
  }
1216
1227
  | kYIELD tLPAREN2 call_args rparen
1217
1228
  {
1218
- result = new_yield val[2]
1229
+ (_, line), _, args, _ = val
1230
+
1231
+ result = new_yield(args).line line
1219
1232
  }
1220
1233
  | kYIELD tLPAREN2 rparen
1221
1234
  {
1222
- result = new_yield
1235
+ (_, line), _, _ = val
1236
+
1237
+ result = new_yield.line line
1223
1238
  }
1224
1239
  | kYIELD
1225
1240
  {
1226
- result = new_yield
1241
+ (_, line), = val
1242
+
1243
+ result = new_yield.line line
1227
1244
  }
1228
1245
  | kDEFINED opt_nl tLPAREN2 expr rparen
1229
1246
  {
@@ -1238,7 +1255,7 @@ rule
1238
1255
  }
1239
1256
  | kNOT tLPAREN2 rparen
1240
1257
  {
1241
- debug20 14, val, result
1258
+ debug 20
1242
1259
  }
1243
1260
  | fcall brace_block
1244
1261
  {
@@ -1256,9 +1273,10 @@ rule
1256
1273
  iter.insert 1, call # FIX
1257
1274
  result = iter
1258
1275
  }
1259
- | tLAMBDA lambda
1276
+ | lambda
1260
1277
  {
1261
- result = val[1] # TODO: fix lineno
1278
+ expr, = val
1279
+ result = expr
1262
1280
  }
1263
1281
  | k_if expr_value then compstmt if_tail k_end
1264
1282
  {
@@ -1301,7 +1319,6 @@ rule
1301
1319
  }
1302
1320
  cpath superclass
1303
1321
  {
1304
- self.comments.push self.lexer.comments
1305
1322
  if (self.in_def || self.in_single > 0) then
1306
1323
  yyerror "class definition in method body"
1307
1324
  end
@@ -1311,7 +1328,7 @@ rule
1311
1328
  {
1312
1329
  result = new_class val
1313
1330
  self.env.unextend
1314
- self.lexer.comments # we don't care about comments in the body
1331
+ self.lexer.ignore_body_comments
1315
1332
  }
1316
1333
  | k_class tLSHFT
1317
1334
  {
@@ -1332,7 +1349,7 @@ rule
1332
1349
  {
1333
1350
  result = new_sclass val
1334
1351
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1352
+ self.lexer.ignore_body_comments
1336
1353
  }
1337
1354
  | k_module
1338
1355
  {
@@ -1340,7 +1357,6 @@ rule
1340
1357
  }
1341
1358
  cpath
1342
1359
  {
1343
- self.comments.push self.lexer.comments
1344
1360
  yyerror "module definition in method body" if
1345
1361
  self.in_def or self.in_single > 0
1346
1362
 
@@ -1350,7 +1366,7 @@ rule
1350
1366
  {
1351
1367
  result = new_module val
1352
1368
  self.env.unextend
1353
- self.lexer.comments # we don't care about comments in the body
1369
+ self.lexer.ignore_body_comments
1354
1370
  }
1355
1371
  | k_def fname
1356
1372
  {
@@ -1360,21 +1376,17 @@ rule
1360
1376
  self.env.extend
1361
1377
  lexer.cmdarg.push false
1362
1378
  lexer.cond.push false
1363
-
1364
- self.comments.push self.lexer.comments
1365
1379
  }
1366
- f_arglist bodystmt { result = lexer.lineno } k_end
1380
+ f_arglist bodystmt k_end
1367
1381
  {
1368
- in_def = val[2]
1369
-
1370
- result = new_defn val
1382
+ result, in_def = new_defn val
1371
1383
 
1372
1384
  lexer.cond.pop # group = local_pop
1373
1385
  lexer.cmdarg.pop
1374
1386
  self.env.unextend
1375
1387
  self.in_def = in_def
1376
1388
 
1377
- self.lexer.comments # we don't care about comments in the body
1389
+ self.lexer.ignore_body_comments
1378
1390
  }
1379
1391
  | k_def singleton dot_or_colon
1380
1392
  {
@@ -1382,7 +1394,7 @@ rule
1382
1394
  }
1383
1395
  fname
1384
1396
  {
1385
- result = [self.in_def, lexer.lineno]
1397
+ result = self.in_def
1386
1398
 
1387
1399
  self.in_single += 1 # TODO: remove?
1388
1400
 
@@ -1392,13 +1404,18 @@ rule
1392
1404
  lexer.cond.push false
1393
1405
 
1394
1406
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
- self.comments.push self.lexer.comments
1396
1407
  }
1397
1408
  f_arglist bodystmt k_end
1398
1409
  {
1399
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1400
1410
 
1401
- result = new_defs val
1411
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1412
+ # =>
1413
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1414
+
1415
+ val.delete_at 3
1416
+ val.delete_at 2
1417
+
1418
+ result, in_def = new_defs val
1402
1419
 
1403
1420
  lexer.cond.pop # group = local_pop
1404
1421
  lexer.cmdarg.pop
@@ -1409,7 +1426,7 @@ rule
1409
1426
 
1410
1427
  # TODO: restore cur_arg ? what's cur_arg?
1411
1428
 
1412
- self.lexer.comments # we don't care about comments in the body
1429
+ self.lexer.ignore_body_comments
1413
1430
  }
1414
1431
  | kBREAK
1415
1432
  {
@@ -1446,8 +1463,17 @@ rule
1446
1463
  k_case: kCASE
1447
1464
  k_for: kFOR
1448
1465
  k_class: kCLASS
1466
+ {
1467
+ self.comments.push self.lexer.comments
1468
+ }
1449
1469
  k_module: kMODULE
1470
+ {
1471
+ self.comments.push self.lexer.comments
1472
+ }
1450
1473
  k_def: kDEF
1474
+ {
1475
+ self.comments.push self.lexer.comments
1476
+ }
1451
1477
  k_do: kDO
1452
1478
  k_do_block: kDO_BLOCK
1453
1479
  k_rescue: kRESCUE
@@ -1508,51 +1534,42 @@ rule
1508
1534
 
1509
1535
  result = block_var args
1510
1536
  }
1511
- | f_marg_list tCOMMA tSTAR f_norm_arg
1537
+ | f_marg_list tCOMMA f_rest_marg
1512
1538
  {
1513
- args, _, _, splat = val
1539
+ args, _, rest = val
1514
1540
 
1515
- result = block_var args, "*#{splat}".to_sym
1541
+ result = block_var args, rest
1516
1542
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1543
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1518
1544
  {
1519
- args, _, _, splat, _, args2 = val
1545
+ lhs, _, splat, _, rhs = val
1520
1546
 
1521
- result = block_var args, "*#{splat}".to_sym, args2
1547
+ result = block_var lhs, splat, rhs
1522
1548
  }
1523
- | f_marg_list tCOMMA tSTAR
1549
+ | f_rest_marg
1524
1550
  {
1525
- args, _, _ = val
1551
+ rest, = val
1526
1552
 
1527
- result = block_var args, :*
1553
+ result = block_var rest
1528
1554
  }
1529
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1555
+ | f_rest_marg tCOMMA f_marg_list
1530
1556
  {
1531
- args, _, _, _, args2 = val
1557
+ splat, _, rest = val
1532
1558
 
1533
- result = block_var args, :*, args2
1559
+ result = block_var splat, rest
1534
1560
  }
1535
- | tSTAR f_norm_arg
1536
- {
1537
- _, splat = val
1538
1561
 
1539
- result = block_var :"*#{splat}"
1540
- }
1541
- | tSTAR f_norm_arg tCOMMA f_marg_list
1562
+ f_rest_marg: tSTAR f_norm_arg
1542
1563
  {
1543
- _, splat, _, args = val
1564
+ _, (id, line) = val
1544
1565
 
1545
- result = block_var :"*#{splat}", args
1566
+ result = args ["*#{id}".to_sym]
1567
+ result.line line
1546
1568
  }
1547
1569
  | tSTAR
1548
1570
  {
1549
- result = block_var :*
1550
- }
1551
- | tSTAR tCOMMA f_marg_list
1552
- {
1553
- _, _, args = val
1554
-
1555
- result = block_var :*, args
1571
+ result = args [:*]
1572
+ result.line lexer.lineno # FIX: tSTAR -> line
1556
1573
  }
1557
1574
 
1558
1575
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1569,8 +1586,8 @@ rule
1569
1586
  }
1570
1587
  | f_block_arg
1571
1588
  {
1572
- line = lexer.lineno
1573
- result = call_args val # TODO: push line down
1589
+ (id, line), = val
1590
+ result = call_args [id]
1574
1591
  result.line line
1575
1592
  }
1576
1593
 
@@ -1679,13 +1696,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1696
 
1680
1697
  bvar: tIDENTIFIER
1681
1698
  {
1682
- id, = val
1683
- line = lexer.lineno
1684
- result = s(:shadow, id.to_sym).line line
1699
+ result = wrap :shadow, val[0]
1685
1700
  }
1686
1701
  | f_bad_arg
1687
1702
 
1688
- lambda: {
1703
+ lambda: tLAMBDA
1704
+ {
1689
1705
  self.env.extend :dynamic
1690
1706
  result = [lexer.lineno, lexer.lpar_beg]
1691
1707
  lexer.paren_nest += 1
@@ -1697,14 +1713,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1697
1713
  }
1698
1714
  lambda_body
1699
1715
  {
1700
- (line, lpar), args, _cmdarg, body = val
1716
+ _, (line, lpar), args, _cmdarg, body = val
1701
1717
  lexer.lpar_beg = lpar
1702
1718
 
1703
1719
  lexer.cmdarg.pop
1704
1720
 
1705
1721
  call = s(:lambda).line line
1706
1722
  result = new_iter call, args, body
1707
- result.line = line
1723
+ result.line line
1708
1724
  self.env.unextend # TODO: dynapush & dynapop
1709
1725
  }
1710
1726
 
@@ -1739,23 +1755,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1739
1755
  ## if (nd_type($1) == NODE_YIELD) {
1740
1756
  ## compile_error(PARSER_ARG "block given to yield");
1741
1757
 
1742
- syntax_error "Both block arg and actual block given." if
1743
- val[0].block_pass?
1758
+ cmd, blk = val
1744
1759
 
1745
- val = invert_block_call val if inverted? val
1760
+ syntax_error "Both block arg and actual block given." if
1761
+ cmd.block_pass?
1746
1762
 
1747
- cmd, blk = val
1763
+ if inverted? val then
1764
+ val = invert_block_call val
1765
+ cmd, blk = val
1766
+ end
1748
1767
 
1749
1768
  result = blk
1750
1769
  result.insert 1, cmd
1751
1770
  }
1752
1771
  | block_call call_op2 operation2 opt_paren_args
1753
1772
  {
1754
- result = new_call val[0], val[2].to_sym, val[3]
1773
+ lhs, _, (id, _line), args = val
1774
+
1775
+ result = new_call lhs, id.to_sym, args
1755
1776
  }
1756
1777
  | block_call call_op2 operation2 opt_paren_args brace_block
1757
1778
  {
1758
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1759
1780
 
1760
1781
  call = new_call iter1, name.to_sym, args
1761
1782
  iter2.insert 1, call
@@ -1764,7 +1785,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1764
1785
  }
1765
1786
  | block_call call_op2 operation2 command_args do_block
1766
1787
  {
1767
- iter1, _, name, args, iter2 = val
1788
+ iter1, _, (name, _line), args, iter2 = val
1768
1789
 
1769
1790
  call = new_call iter1, name.to_sym, args
1770
1791
  iter2.insert 1, call
@@ -1772,28 +1793,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1772
1793
  result = iter2
1773
1794
  }
1774
1795
 
1775
- method_call: fcall
1776
- {
1777
- result = self.lexer.lineno
1778
- }
1779
- paren_args
1796
+ method_call: fcall paren_args
1780
1797
  {
1781
- call, lineno, args = val
1798
+ call, args = val
1782
1799
 
1783
1800
  result = call.concat args.sexp_body if args
1784
- result.line lineno
1785
1801
  }
1786
1802
  | primary_value call_op operation2 opt_paren_args
1787
1803
  {
1788
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1804
+ recv, call_op, (op, _line), args = val
1805
+
1806
+ result = new_call recv, op.to_sym, args, call_op
1789
1807
  }
1790
1808
  | primary_value tCOLON2 operation2 paren_args
1791
1809
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1810
+ recv, _, (op, _line), args = val
1811
+
1812
+ result = new_call recv, op.to_sym, args
1793
1813
  }
1794
1814
  | primary_value tCOLON2 operation3
1795
1815
  {
1796
- result = new_call val[0], val[2].to_sym
1816
+ lhs, _, (id, _line) = val
1817
+
1818
+ result = new_call lhs, id.to_sym
1797
1819
  }
1798
1820
  | primary_value call_op paren_args
1799
1821
  {
@@ -1826,7 +1848,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1848
  _, line, body, _ = val
1827
1849
 
1828
1850
  result = body
1829
- result.line = line
1851
+ result.line line
1830
1852
 
1831
1853
  self.env.unextend
1832
1854
  }
@@ -1840,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1862
  _, line, body, _ = val
1841
1863
 
1842
1864
  result = body
1843
- result.line = line
1865
+ result.line line
1844
1866
 
1845
1867
  self.env.unextend
1846
1868
  }
@@ -1869,14 +1891,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1869
1891
  self.env.unextend
1870
1892
  }
1871
1893
 
1894
+ case_args: arg_value
1895
+ {
1896
+ arg, = val
1897
+
1898
+ result = s(:array, arg).line arg.line
1899
+ }
1900
+ | tSTAR arg_value
1901
+ {
1902
+ _, arg = val
1903
+
1904
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1905
+ }
1906
+ | case_args tCOMMA arg_value
1907
+ {
1908
+ args, _, id = val
1909
+
1910
+ result = self.list_append args, id
1911
+ }
1912
+ | case_args tCOMMA tSTAR arg_value
1913
+ {
1914
+ args, _, _, id = val
1915
+
1916
+ result = self.list_append args, s(:splat, id).line(id.line)
1917
+ }
1918
+
1872
1919
  case_body: k_when
1873
1920
  {
1874
1921
  result = self.lexer.lineno
1875
1922
  }
1876
- args then compstmt cases
1923
+ case_args then compstmt cases
1877
1924
  {
1878
1925
  result = new_when(val[2], val[4])
1879
- result.line = val[1]
1926
+ result.line val[1]
1880
1927
  result << val[5] if val[5]
1881
1928
  }
1882
1929
 
@@ -1922,17 +1969,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1922
1969
 
1923
1970
  literal: numeric
1924
1971
  {
1925
- line = lexer.lineno
1926
- result = s(:lit, val[0])
1927
- result.line = line
1972
+ (lit, line), = val
1973
+ result = s(:lit, lit).line line
1928
1974
  }
1929
1975
  | symbol
1930
- {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1934
- }
1935
- | dsym
1936
1976
 
1937
1977
  strings: string
1938
1978
  {
@@ -1943,7 +1983,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1943
1983
 
1944
1984
  string: tCHAR
1945
1985
  {
1946
- debug20 23, val, result
1986
+ debug 37
1947
1987
  }
1948
1988
  | string1
1949
1989
  | string string1
@@ -1953,11 +1993,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
1993
 
1954
1994
  string1: tSTRING_BEG string_contents tSTRING_END
1955
1995
  {
1956
- _, str, (_, func) = val
1996
+ (_, line), str, (_, func) = val
1957
1997
 
1958
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1998
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1959
1999
 
1960
- result = str
2000
+ result = str.line line
1961
2001
  }
1962
2002
  | tSTRING
1963
2003
  {
@@ -1977,11 +2017,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2017
 
1978
2018
  words: tWORDS_BEG tSPACE tSTRING_END
1979
2019
  {
1980
- result = s(:array).line lexer.lineno
2020
+ (_, line), _, _ = val
2021
+
2022
+ result = s(:array).line line
1981
2023
  }
1982
2024
  | tWORDS_BEG word_list tSTRING_END
1983
2025
  {
1984
- result = val[1]
2026
+ (_, line), list, _ = val
2027
+
2028
+ result = list.line line
1985
2029
  }
1986
2030
 
1987
2031
  word_list: none
@@ -2001,18 +2045,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2001
2045
 
2002
2046
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2003
2047
  {
2004
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2005
2051
  }
2006
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2052
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2007
2053
  {
2008
- _, line, list, _, = val
2009
- list.line = line
2054
+ (_, line), list, _, = val
2055
+ list.line line
2010
2056
  result = list
2011
2057
  }
2012
2058
 
2013
2059
  symbol_list: none
2014
2060
  {
2015
- result = new_symbol_list.line lexer.lineno
2061
+ result = new_symbol_list
2016
2062
  }
2017
2063
  | symbol_list word tSPACE
2018
2064
  {
@@ -2022,20 +2068,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2022
2068
 
2023
2069
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2024
2070
  {
2025
- result = s(:array).line lexer.lineno
2071
+ (_, line), _, _ = val
2072
+
2073
+ result = s(:array).line line
2026
2074
  }
2027
2075
  | tQWORDS_BEG qword_list tSTRING_END
2028
2076
  {
2029
- result = val[1]
2077
+ (_, line), list, _ = val
2078
+
2079
+ result = list.line line
2030
2080
  }
2031
2081
 
2032
2082
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2033
2083
  {
2034
- result = s(:array).line lexer.lineno # FIX
2084
+ (_, line), _, _ = val
2085
+
2086
+ result = s(:array).line line
2035
2087
  }
2036
2088
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2037
2089
  {
2038
- result = val[1]
2090
+ (_, line), list, _ = val
2091
+
2092
+ result = list.line line
2039
2093
  }
2040
2094
 
2041
2095
  qword_list: none
@@ -2058,7 +2112,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2112
 
2059
2113
  string_contents: none
2060
2114
  {
2061
- result = s(:str, "").line lexer.lineno
2115
+ line = prev_value_to_lineno _values.last
2116
+ result = s(:str, +"").line line
2062
2117
  }
2063
2118
  | string_contents string_content
2064
2119
  {
@@ -2133,8 +2188,8 @@ regexp_contents: none
2133
2188
  lexer.brace_nest = brace_nest
2134
2189
  lexer.string_nest = string_nest
2135
2190
 
2136
- lexer.cmdarg.pop
2137
2191
  lexer.cond.pop
2192
+ lexer.cmdarg.pop
2138
2193
 
2139
2194
  lexer.lex_state = oldlex_state
2140
2195
 
@@ -2149,29 +2204,42 @@ regexp_contents: none
2149
2204
  when nil then
2150
2205
  result = s(:evstr).line line
2151
2206
  else
2152
- debug20 25
2207
+ debug 38
2153
2208
  raise "unknown string body: #{stmt.inspect}"
2154
2209
  end
2155
2210
  }
2156
2211
 
2157
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2212
+ string_dvar: tGVAR
2213
+ {
2214
+ result = wrap :gvar, val[0]
2215
+ }
2216
+ | tIVAR
2217
+ {
2218
+ result = wrap :ivar, val[0]
2219
+ }
2220
+ | tCVAR
2221
+ {
2222
+ result = wrap :cvar, val[0]
2223
+ }
2160
2224
  | backref
2161
2225
 
2162
- symbol: tSYMBEG sym
2226
+ symbol: ssym
2227
+ | dsym
2228
+
2229
+ ssym: tSYMBEG sym
2163
2230
  {
2164
2231
  lexer.lex_state = EXPR_END
2165
- result = val[1].to_sym
2232
+ result = wrap :lit, val[1]
2166
2233
  }
2167
2234
  | tSYMBOL
2168
2235
  {
2169
- result = val[0].to_sym
2236
+ lexer.lex_state = EXPR_END
2237
+ result = wrap :lit, val[0]
2170
2238
  }
2171
2239
 
2172
2240
  sym: fname | tIVAR | tGVAR | tCVAR
2173
2241
 
2174
- dsym: tSYMBEG xstring_contents tSTRING_END
2242
+ dsym: tSYMBEG string_contents tSTRING_END
2175
2243
  {
2176
2244
  _, result, _ = val
2177
2245
 
@@ -2187,14 +2255,15 @@ regexp_contents: none
2187
2255
  when :evstr then
2188
2256
  result = s(:dsym, "", result).line result.line
2189
2257
  else
2190
- debug20 26, val, result
2258
+ debug 39
2191
2259
  end
2192
2260
  }
2193
2261
 
2194
2262
  numeric: simple_numeric
2195
- | tUMINUS_NUM simple_numeric
2263
+ | tUMINUS_NUM simple_numeric =tLOWEST
2196
2264
  {
2197
- result = -val[1] # TODO: pt_testcase
2265
+ _, (num, line) = val
2266
+ result = [-num, line]
2198
2267
  }
2199
2268
 
2200
2269
  simple_numeric: tINTEGER
@@ -2227,8 +2296,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2227
2296
 
2228
2297
  var_ref: user_variable
2229
2298
  {
2230
- var = val[0]
2299
+ raise "NO: #{val.inspect}" if Sexp === val.first
2300
+ (var, line), = val
2231
2301
  result = Sexp === var ? var : self.gettable(var)
2302
+ result.line line
2232
2303
  }
2233
2304
  | keyword_variable
2234
2305
  {
@@ -2243,11 +2314,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2314
  | keyword_variable
2244
2315
  {
2245
2316
  result = self.assignable val[0]
2246
- debug20 29, val, result
2317
+ debug 40
2247
2318
  }
2248
2319
 
2249
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2320
+ backref: tNTH_REF
2321
+ {
2322
+ (ref, line), = val
2323
+ result = s(:nth_ref, ref).line line
2324
+ }
2325
+ | tBACK_REF
2326
+ {
2327
+ (ref, line), = val
2328
+ result = s(:back_ref, ref).line line
2329
+ }
2251
2330
 
2252
2331
  superclass: tLT
2253
2332
  {
@@ -2265,9 +2344,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2344
 
2266
2345
  f_arglist: tLPAREN2 f_args rparen
2267
2346
  {
2268
- result = val[1]
2269
- self.lexer.lex_state = EXPR_BEG
2270
- self.lexer.command_start = true
2347
+ result = end_args val
2271
2348
  }
2272
2349
  | {
2273
2350
  result = self.in_kwarg
@@ -2276,12 +2353,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2276
2353
  }
2277
2354
  f_args term
2278
2355
  {
2279
- kwarg, args, _ = val
2280
-
2281
- self.in_kwarg = kwarg
2282
- result = args
2283
- lexer.lex_state = EXPR_BEG
2284
- lexer.command_start = true
2356
+ result = end_args val
2285
2357
  }
2286
2358
 
2287
2359
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2366,8 +2438,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2438
  |
2367
2439
  {
2368
2440
  result = args val
2441
+ # result.line lexer.lineno
2369
2442
  }
2370
2443
 
2444
+
2371
2445
  f_bad_arg: tCONSTANT
2372
2446
  {
2373
2447
  yyerror "formal argument cannot be a constant"
@@ -2388,10 +2462,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2388
2462
  f_norm_arg: f_bad_arg
2389
2463
  | tIDENTIFIER
2390
2464
  {
2391
- identifier = val[0].to_sym
2465
+ (id, line), = val
2466
+ identifier = id.to_sym
2392
2467
  self.env[identifier] = :lvar
2393
2468
 
2394
- result = identifier
2469
+ result = [identifier, line]
2395
2470
  }
2396
2471
 
2397
2472
  f_arg_asgn: f_norm_arg
@@ -2399,22 +2474,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2399
2474
  f_arg_item: f_arg_asgn
2400
2475
  | tLPAREN f_margs rparen
2401
2476
  {
2402
- result = val[1]
2477
+ _, margs, _ = val
2478
+
2479
+ result = margs
2403
2480
  }
2404
2481
 
2405
2482
  f_arg: f_arg_item
2406
2483
  {
2407
- arg, = val
2408
-
2409
- case arg
2410
- when Symbol then
2411
- result = s(:args, arg).line lexer.lineno
2412
- when Sexp then
2413
- result = arg
2414
- else
2415
- debug20 32
2416
- raise "Unknown f_arg type: #{val.inspect}"
2417
- end
2484
+ result = new_arg val
2418
2485
  }
2419
2486
  | f_arg tCOMMA f_arg_item
2420
2487
  {
@@ -2426,7 +2493,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2426
2493
  result = s(:args, list).line list.line
2427
2494
  end
2428
2495
 
2429
- result << item
2496
+ result << (Sexp === item ? item : item.first)
2430
2497
  }
2431
2498
 
2432
2499
  f_label: tLABEL
@@ -2487,26 +2554,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2487
2554
  kwrest_mark: tPOW
2488
2555
  | tDSTAR
2489
2556
 
2557
+
2490
2558
  f_kwrest: kwrest_mark tIDENTIFIER
2491
2559
  {
2492
- name = val[1].to_sym
2493
- self.assignable name
2494
- result = :"**#{name}"
2560
+ _, (id, line) = val
2561
+
2562
+ name = id.to_sym
2563
+ self.assignable [name, line]
2564
+ result = [:"**#{name}", line]
2495
2565
  }
2496
2566
  | kwrest_mark
2497
2567
  {
2498
- result = :"**"
2568
+ id = :"**"
2569
+ self.env[id] = :lvar # TODO: needed?!?
2570
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2499
2571
  }
2500
2572
 
2501
2573
  f_opt: f_arg_asgn tEQL arg_value
2502
2574
  {
2503
- result = self.assignable val[0], val[2]
2575
+ lhs, _, rhs = val
2576
+ result = self.assignable lhs, rhs
2504
2577
  # TODO: detect duplicate names
2505
2578
  }
2506
2579
 
2507
2580
  f_block_opt: f_arg_asgn tEQL primary_value
2508
2581
  {
2509
- result = self.assignable val[0], val[2]
2582
+ lhs, _, rhs = val
2583
+ result = self.assignable lhs, rhs
2510
2584
  }
2511
2585
 
2512
2586
  f_block_optarg: f_block_opt
@@ -2536,30 +2610,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2536
2610
  f_rest_arg: restarg_mark tIDENTIFIER
2537
2611
  {
2538
2612
  # TODO: differs from parse.y - needs tests
2539
- name = val[1].to_sym
2540
- self.assignable name
2541
- result = :"*#{name}"
2613
+ _, (id, line) = val
2614
+ name = id.to_sym
2615
+ self.assignable [name, line]
2616
+ result = [:"*#{name}", line]
2542
2617
  }
2543
2618
  | restarg_mark
2544
2619
  {
2545
2620
  name = :"*"
2546
2621
  self.env[name] = :lvar
2547
- result = name
2622
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2548
2623
  }
2549
2624
 
2550
2625
  blkarg_mark: tAMPER2 | tAMPER
2551
2626
 
2552
2627
  f_block_arg: blkarg_mark tIDENTIFIER
2553
2628
  {
2554
- identifier = val[1].to_sym
2629
+ _, (id, line) = val
2630
+ identifier = id.to_sym
2555
2631
 
2556
2632
  self.env[identifier] = :lvar
2557
- result = "&#{identifier}".to_sym
2633
+ result = ["&#{identifier}".to_sym, line]
2558
2634
  }
2559
2635
 
2560
2636
  opt_f_block_arg: tCOMMA f_block_arg
2561
2637
  {
2562
- result = val[1]
2638
+ _, arg = val
2639
+ result = arg
2563
2640
  }
2564
2641
  |
2565
2642
  {
@@ -2601,16 +2678,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2601
2678
  }
2602
2679
  | tLABEL arg_value
2603
2680
  {
2604
- (label, line), arg = val
2681
+ label, arg = val
2605
2682
 
2606
- lit = s(:lit, label.to_sym).line line
2607
- result = s(:array, lit, arg).line line
2683
+ lit = wrap :lit, label
2684
+ result = s(:array, lit, arg).line lit.line
2608
2685
  }
2609
2686
  | tSTRING_BEG string_contents tLABEL_END arg_value
2610
2687
  {
2611
- _, sym, _, value = val
2688
+ (_, line), sym, _, value = val
2689
+
2612
2690
  sym.sexp_type = :dsym
2613
- result = s(:array, sym, value).line sym.line
2691
+
2692
+ result = s(:array, sym, value).line line
2614
2693
  }
2615
2694
  | tDSTAR arg_value
2616
2695
  {