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/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
@@ -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
  {
@@ -302,7 +310,7 @@ rule
302
310
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
303
311
  # REFACTOR: call_uni_op -- see parse26.y
304
312
  }
305
- | arg
313
+ | arg =tLBRACE_ARG
306
314
 
307
315
  expr_value: expr
308
316
  {
@@ -327,7 +335,7 @@ rule
327
335
  block_command: block_call
328
336
  | block_call call_op2 operation2 command_args
329
337
  {
330
- blk, _, msg, args = val
338
+ blk, _, (msg, _line), args = val
331
339
  result = new_call(blk, msg.to_sym, args).line blk.line
332
340
  }
333
341
 
@@ -341,15 +349,15 @@ rule
341
349
  _, line, body, _ = val
342
350
 
343
351
  result = body
344
- result.line = line
352
+ result.line line
345
353
 
346
354
  # self.env.unextend
347
355
  }
348
356
 
349
357
  fcall: operation
350
358
  {
351
- msg, = val
352
- result = new_call(nil, msg.to_sym).line lexer.lineno
359
+ (msg, line), = val
360
+ result = new_call(nil, msg.to_sym).line line
353
361
  }
354
362
 
355
363
  command: fcall command_args =tLOWEST
@@ -372,12 +380,14 @@ rule
372
380
  }
373
381
  | primary_value call_op operation2 command_args =tLOWEST
374
382
  {
375
- lhs, callop, op, args = val
383
+ lhs, callop, (op, _), args = val
384
+
376
385
  result = new_call lhs, op.to_sym, args, callop
386
+ result.line lhs.line
377
387
  }
378
388
  | primary_value call_op operation2 command_args cmd_brace_block
379
389
  {
380
- recv, _, msg, args, block = val
390
+ recv, _, (msg, _line), args, block = val
381
391
  call = new_call recv, msg.to_sym, args, val[1]
382
392
 
383
393
  block_dup_check call, block
@@ -387,11 +397,14 @@ rule
387
397
  }
388
398
  | primary_value tCOLON2 operation2 command_args =tLOWEST
389
399
  {
390
- 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
391
404
  }
392
405
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
393
406
  {
394
- recv, _, msg, args, block = val
407
+ recv, _, (msg, _line), args, block = val
395
408
  call = new_call recv, msg.to_sym, args
396
409
 
397
410
  block_dup_check call, block
@@ -549,25 +562,29 @@ rule
549
562
  }
550
563
  | primary_value call_op tIDENTIFIER
551
564
  {
552
- 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
553
568
  }
554
569
  | primary_value tCOLON2 tIDENTIFIER
555
570
  {
556
- recv, _, id = val
571
+ recv, _, (id, _line) = val
557
572
  result = new_attrasgn recv, id
558
573
  }
559
574
  | primary_value call_op tCONSTANT
560
575
  {
561
- 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
562
579
  }
563
580
  | primary_value tCOLON2 tCONSTANT
564
581
  {
565
582
  if (self.in_def || self.in_single > 0) then
566
- debug20 7
583
+ debug 14
567
584
  yyerror "dynamic constant assignment"
568
585
  end
569
586
 
570
- expr, _, id = val
587
+ expr, _, (id, _line) = val
571
588
  l = expr.line
572
589
 
573
590
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -575,58 +592,65 @@ rule
575
592
  | tCOLON3 tCONSTANT
576
593
  {
577
594
  if (self.in_def || self.in_single > 0) then
578
- debug20 8
595
+ debug 15
579
596
  yyerror "dynamic constant assignment"
580
597
  end
581
598
 
582
- _, id = val
583
- l = lexer.lineno
599
+ _, (id, l) = val
584
600
 
585
601
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
586
602
  }
587
603
  | backref
588
604
  {
589
- self.backref_assign_error val[0]
605
+ ref, = val
606
+
607
+ self.backref_assign_error ref
590
608
  }
591
609
 
592
610
  lhs: user_variable
593
611
  {
594
- line = lexer.lineno
595
- result = self.assignable val[0]
596
- result.line = line
612
+ var, = val
613
+
614
+ result = self.assignable var
597
615
  }
598
616
  | keyword_variable
599
617
  {
600
- line = lexer.lineno
601
- result = self.assignable val[0]
602
- result.line = line
603
- debug20 9, val, result
618
+ var, = val
619
+
620
+ result = self.assignable var
621
+
622
+ debug 16
604
623
  }
605
624
  | primary_value tLBRACK2 opt_call_args rbracket
606
625
  {
607
626
  lhs, _, args, _ = val
627
+
608
628
  result = self.aryset lhs, args
609
629
  }
610
630
  | primary_value call_op tIDENTIFIER # REFACTOR
611
631
  {
612
- lhs, op, id = val
632
+ lhs, op, (id, _line) = val
633
+
613
634
  result = new_attrasgn lhs, id, op
614
635
  }
615
636
  | primary_value tCOLON2 tIDENTIFIER
616
637
  {
617
- lhs, _, id = val
638
+ lhs, _, (id, _line) = val
639
+
618
640
  result = new_attrasgn lhs, id
619
641
  }
620
642
  | primary_value call_op tCONSTANT # REFACTOR?
621
643
  {
622
- 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
623
647
  }
624
648
  | primary_value tCOLON2 tCONSTANT
625
649
  {
626
- expr, _, id = val
650
+ expr, _, (id, _line) = val
627
651
 
628
652
  if (self.in_def || self.in_single > 0) then
629
- debug20 10
653
+ debug 17
630
654
  yyerror "dynamic constant assignment"
631
655
  end
632
656
 
@@ -635,14 +659,13 @@ rule
635
659
  }
636
660
  | tCOLON3 tCONSTANT
637
661
  {
638
- _, id = val
662
+ _, (id, l) = val
639
663
 
640
664
  if (self.in_def || self.in_single > 0) then
641
- debug20 11
665
+ debug 18
642
666
  yyerror "dynamic constant assignment"
643
667
  end
644
668
 
645
- l = lexer.lineno
646
669
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
647
670
  }
648
671
  | backref
@@ -658,16 +681,16 @@ rule
658
681
 
659
682
  cpath: tCOLON3 cname
660
683
  {
661
- _, name = val
662
- result = s(:colon3, name.to_sym).line lexer.lineno
684
+ result = wrap :colon3, val[1]
663
685
  }
664
686
  | cname
665
687
  {
666
- result = val[0].to_sym
688
+ (id, line), = val
689
+ result = [id.to_sym, line] # TODO: sexp?
667
690
  }
668
691
  | primary_value tCOLON2 cname
669
692
  {
670
- pval, _, name = val
693
+ pval, _, (name, _line) = val
671
694
 
672
695
  result = s(:colon2, pval, name.to_sym)
673
696
  result.line pval.line
@@ -677,24 +700,15 @@ rule
677
700
  | op
678
701
  {
679
702
  lexer.lex_state = EXPR_END
680
- result = val[0]
681
703
  }
682
704
 
683
705
  | reswords
684
- {
685
- (sym, _line), = val
686
- lexer.lex_state = EXPR_END
687
- result = sym
688
- }
689
706
 
690
- fsym: fname | symbol
691
-
692
- fitem: fsym
707
+ fitem: fname
693
708
  {
694
- id, = val
695
- result = s(:lit, id.to_sym).line lexer.lineno
709
+ result = wrap :lit, val[0]
696
710
  }
697
- | dsym
711
+ | symbol
698
712
 
699
713
  undef_list: fitem
700
714
  {
@@ -715,8 +729,6 @@ rule
715
729
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
716
730
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
717
731
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
718
- # TODO: tUBANG dead?
719
- | tUBANG
720
732
 
721
733
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
722
734
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -750,26 +762,22 @@ rule
750
762
  }
751
763
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
752
764
  {
753
- lhs, _, id, op, rhs = val
765
+ lhs, _, (id, _line), (op, _), rhs = val
754
766
 
755
767
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
756
768
  }
757
769
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
758
770
  {
759
- lhs1, _, lhs2, op, rhs = val
771
+ lhs1, _, (lhs2, _line), op, rhs = val
760
772
 
761
773
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
762
774
  result = new_const_op_asgn [lhs, op, rhs]
763
775
  }
764
- | tCOLON3 tCONSTANT
776
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
765
777
  {
766
- result = self.lexer.lineno
767
- }
768
- tOP_ASGN arg_rhs
769
- {
770
- _, lhs, line, op, rhs = val
778
+ _, lhs, op, rhs = val
771
779
 
772
- lhs = s(:colon3, lhs.to_sym).line line
780
+ lhs = wrap :colon3, lhs
773
781
  result = new_const_op_asgn [lhs, op, rhs]
774
782
  }
775
783
  | backref tOP_ASGN arg_rhs
@@ -781,7 +789,7 @@ rule
781
789
  | arg tDOT2 arg
782
790
  {
783
791
  v1, v2 = val[0], val[2]
784
- 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
785
793
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
786
794
  else
787
795
  result = s(:dot2, v1, v2).line v1.line
@@ -790,12 +798,14 @@ rule
790
798
  | arg tDOT3 arg
791
799
  {
792
800
  v1, v2 = val[0], val[2]
793
- 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
794
802
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
795
803
  else
796
804
  result = s(:dot3, v1, v2).line v1.line
797
805
  end
798
806
  }
807
+
808
+
799
809
  | arg tPLUS arg
800
810
  {
801
811
  result = new_call val[0], :+, argl(val[2])
@@ -822,8 +832,9 @@ rule
822
832
  }
823
833
  | tUMINUS_NUM simple_numeric tPOW arg
824
834
  {
825
- lit = s(:lit, val[1]).line lexer.lineno
826
- 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)), :"-@")
827
838
 
828
839
  }
829
840
  | tUPLUS arg
@@ -922,12 +933,12 @@ rule
922
933
 
923
934
  rel_expr: arg relop arg =tGT
924
935
  {
925
- lhs, op, rhs = val
936
+ lhs, (op, _), rhs = val
926
937
  result = new_call lhs, op.to_sym, argl(rhs)
927
938
  }
928
939
  | rel_expr relop arg =tGT
929
940
  {
930
- lhs, op, rhs = val
941
+ lhs, (op, _), rhs = val
931
942
  warn "comparison '%s' after comparison", op
932
943
  result = new_call lhs, op.to_sym, argl(rhs)
933
944
  }
@@ -1118,8 +1129,9 @@ rule
1118
1129
  | backref
1119
1130
  | tFID
1120
1131
  {
1121
- msg, = val
1132
+ (msg, line), = val
1122
1133
  result = new_call nil, msg.to_sym
1134
+ result.line line
1123
1135
  }
1124
1136
  | k_begin
1125
1137
  {
@@ -1161,15 +1173,13 @@ rule
1161
1173
  }
1162
1174
  | primary_value tCOLON2 tCONSTANT
1163
1175
  {
1164
- expr, _, id = val
1176
+ expr, _, (id, _line) = val
1165
1177
 
1166
1178
  result = s(:colon2, expr, id.to_sym).line expr.line
1167
1179
  }
1168
1180
  | tCOLON3 tCONSTANT
1169
1181
  {
1170
- _, id = val
1171
-
1172
- result = s(:colon3, id.to_sym).line lexer.lineno
1182
+ result = wrap :colon3, val[1]
1173
1183
  }
1174
1184
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1175
1185
  {
@@ -1193,15 +1203,21 @@ rule
1193
1203
  }
1194
1204
  | kYIELD tLPAREN2 call_args rparen
1195
1205
  {
1196
- result = new_yield val[2]
1206
+ (_, line), _, args, _ = val
1207
+
1208
+ result = new_yield(args).line line
1197
1209
  }
1198
1210
  | kYIELD tLPAREN2 rparen
1199
1211
  {
1200
- result = new_yield
1212
+ (_, line), _, _ = val
1213
+
1214
+ result = new_yield.line line
1201
1215
  }
1202
1216
  | kYIELD
1203
1217
  {
1204
- result = new_yield
1218
+ (_, line), = val
1219
+
1220
+ result = new_yield.line line
1205
1221
  }
1206
1222
  | kDEFINED opt_nl tLPAREN2 expr rparen
1207
1223
  {
@@ -1216,7 +1232,7 @@ rule
1216
1232
  }
1217
1233
  | kNOT tLPAREN2 rparen
1218
1234
  {
1219
- debug20 14, val, result
1235
+ debug 20
1220
1236
  }
1221
1237
  | fcall brace_block
1222
1238
  {
@@ -1234,9 +1250,10 @@ rule
1234
1250
  iter.insert 1, call # FIX
1235
1251
  result = iter
1236
1252
  }
1237
- | tLAMBDA lambda
1253
+ | lambda
1238
1254
  {
1239
- result = val[1] # TODO: fix lineno
1255
+ expr, = val
1256
+ result = expr
1240
1257
  }
1241
1258
  | k_if expr_value then compstmt if_tail k_end
1242
1259
  {
@@ -1279,7 +1296,6 @@ rule
1279
1296
  }
1280
1297
  cpath superclass
1281
1298
  {
1282
- self.comments.push self.lexer.comments
1283
1299
  if (self.in_def || self.in_single > 0) then
1284
1300
  yyerror "class definition in method body"
1285
1301
  end
@@ -1289,7 +1305,7 @@ rule
1289
1305
  {
1290
1306
  result = new_class val
1291
1307
  self.env.unextend
1292
- self.lexer.comments # we don't care about comments in the body
1308
+ self.lexer.ignore_body_comments
1293
1309
  }
1294
1310
  | k_class tLSHFT
1295
1311
  {
@@ -1310,7 +1326,7 @@ rule
1310
1326
  {
1311
1327
  result = new_sclass val
1312
1328
  self.env.unextend
1313
- self.lexer.comments # we don't care about comments in the body
1329
+ self.lexer.ignore_body_comments
1314
1330
  }
1315
1331
  | k_module
1316
1332
  {
@@ -1318,7 +1334,6 @@ rule
1318
1334
  }
1319
1335
  cpath
1320
1336
  {
1321
- self.comments.push self.lexer.comments
1322
1337
  yyerror "module definition in method body" if
1323
1338
  self.in_def or self.in_single > 0
1324
1339
 
@@ -1328,7 +1343,7 @@ rule
1328
1343
  {
1329
1344
  result = new_module val
1330
1345
  self.env.unextend
1331
- self.lexer.comments # we don't care about comments in the body
1346
+ self.lexer.ignore_body_comments
1332
1347
  }
1333
1348
  | k_def fname
1334
1349
  {
@@ -1338,21 +1353,17 @@ rule
1338
1353
  self.env.extend
1339
1354
  lexer.cmdarg.push false
1340
1355
  lexer.cond.push false
1341
-
1342
- self.comments.push self.lexer.comments
1343
1356
  }
1344
- f_arglist bodystmt { result = lexer.lineno } k_end
1357
+ f_arglist bodystmt k_end
1345
1358
  {
1346
- in_def = val[2]
1347
-
1348
- result = new_defn val
1359
+ result, in_def = new_defn val
1349
1360
 
1350
1361
  lexer.cond.pop # group = local_pop
1351
1362
  lexer.cmdarg.pop
1352
1363
  self.env.unextend
1353
1364
  self.in_def = in_def
1354
1365
 
1355
- self.lexer.comments # we don't care about comments in the body
1366
+ self.lexer.ignore_body_comments
1356
1367
  }
1357
1368
  | k_def singleton dot_or_colon
1358
1369
  {
@@ -1360,7 +1371,7 @@ rule
1360
1371
  }
1361
1372
  fname
1362
1373
  {
1363
- result = [self.in_def, lexer.lineno]
1374
+ result = self.in_def
1364
1375
 
1365
1376
  self.in_single += 1 # TODO: remove?
1366
1377
 
@@ -1370,13 +1381,18 @@ rule
1370
1381
  lexer.cond.push false
1371
1382
 
1372
1383
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1373
- self.comments.push self.lexer.comments
1374
1384
  }
1375
1385
  f_arglist bodystmt k_end
1376
1386
  {
1377
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1378
1387
 
1379
- 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
1380
1396
 
1381
1397
  lexer.cond.pop # group = local_pop
1382
1398
  lexer.cmdarg.pop
@@ -1387,7 +1403,7 @@ rule
1387
1403
 
1388
1404
  # TODO: restore cur_arg ? what's cur_arg?
1389
1405
 
1390
- self.lexer.comments # we don't care about comments in the body
1406
+ self.lexer.ignore_body_comments
1391
1407
  }
1392
1408
  | kBREAK
1393
1409
  {
@@ -1424,8 +1440,17 @@ rule
1424
1440
  k_case: kCASE
1425
1441
  k_for: kFOR
1426
1442
  k_class: kCLASS
1443
+ {
1444
+ self.comments.push self.lexer.comments
1445
+ }
1427
1446
  k_module: kMODULE
1447
+ {
1448
+ self.comments.push self.lexer.comments
1449
+ }
1428
1450
  k_def: kDEF
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1429
1454
  k_do: kDO
1430
1455
  k_do_block: kDO_BLOCK
1431
1456
  k_rescue: kRESCUE
@@ -1486,51 +1511,42 @@ rule
1486
1511
 
1487
1512
  result = block_var args
1488
1513
  }
1489
- | f_marg_list tCOMMA tSTAR f_norm_arg
1514
+ | f_marg_list tCOMMA f_rest_marg
1490
1515
  {
1491
- args, _, _, splat = val
1516
+ args, _, rest = val
1492
1517
 
1493
- result = block_var args, "*#{splat}".to_sym
1518
+ result = block_var args, rest
1494
1519
  }
1495
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1520
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1496
1521
  {
1497
- args, _, _, splat, _, args2 = val
1522
+ lhs, _, splat, _, rhs = val
1498
1523
 
1499
- result = block_var args, "*#{splat}".to_sym, args2
1524
+ result = block_var lhs, splat, rhs
1500
1525
  }
1501
- | f_marg_list tCOMMA tSTAR
1526
+ | f_rest_marg
1502
1527
  {
1503
- args, _, _ = val
1528
+ rest, = val
1504
1529
 
1505
- result = block_var args, :*
1530
+ result = block_var rest
1506
1531
  }
1507
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1532
+ | f_rest_marg tCOMMA f_marg_list
1508
1533
  {
1509
- args, _, _, _, args2 = val
1534
+ splat, _, rest = val
1510
1535
 
1511
- result = block_var args, :*, args2
1536
+ result = block_var splat, rest
1512
1537
  }
1513
- | tSTAR f_norm_arg
1514
- {
1515
- _, splat = val
1516
1538
 
1517
- result = block_var :"*#{splat}"
1518
- }
1519
- | tSTAR f_norm_arg tCOMMA f_marg_list
1539
+ f_rest_marg: tSTAR f_norm_arg
1520
1540
  {
1521
- _, splat, _, args = val
1541
+ _, (id, line) = val
1522
1542
 
1523
- result = block_var :"*#{splat}", args
1543
+ result = args ["*#{id}".to_sym]
1544
+ result.line line
1524
1545
  }
1525
1546
  | tSTAR
1526
1547
  {
1527
- result = block_var :*
1528
- }
1529
- | tSTAR tCOMMA f_marg_list
1530
- {
1531
- _, _, args = val
1532
-
1533
- result = block_var :*, args
1548
+ result = args [:*]
1549
+ result.line lexer.lineno # FIX: tSTAR -> line
1534
1550
  }
1535
1551
 
1536
1552
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1547,8 +1563,8 @@ rule
1547
1563
  }
1548
1564
  | f_block_arg
1549
1565
  {
1550
- line = lexer.lineno
1551
- result = call_args val # TODO: push line down
1566
+ (id, line), = val
1567
+ result = call_args [id]
1552
1568
  result.line line
1553
1569
  }
1554
1570
 
@@ -1657,13 +1673,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1657
1673
 
1658
1674
  bvar: tIDENTIFIER
1659
1675
  {
1660
- id, = val
1661
- line = lexer.lineno
1662
- result = s(:shadow, id.to_sym).line line
1676
+ result = wrap :shadow, val[0]
1663
1677
  }
1664
1678
  | f_bad_arg
1665
1679
 
1666
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1667
1682
  self.env.extend :dynamic
1668
1683
  result = [lexer.lineno, lexer.lpar_beg]
1669
1684
  lexer.paren_nest += 1
@@ -1675,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1675
1690
  }
1676
1691
  lambda_body
1677
1692
  {
1678
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1679
1694
  lexer.lpar_beg = lpar
1680
1695
 
1681
1696
  lexer.cmdarg.pop
1682
1697
 
1683
1698
  call = s(:lambda).line line
1684
1699
  result = new_iter call, args, body
1685
- result.line = line
1700
+ result.line line
1686
1701
  self.env.unextend # TODO: dynapush & dynapop
1687
1702
  }
1688
1703
 
@@ -1717,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1732
  ## if (nd_type($1) == NODE_YIELD) {
1718
1733
  ## compile_error(PARSER_ARG "block given to yield");
1719
1734
 
1720
- syntax_error "Both block arg and actual block given." if
1721
- val[0].block_pass?
1735
+ cmd, blk = val
1722
1736
 
1723
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1724
1739
 
1725
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1726
1744
 
1727
1745
  result = blk
1728
1746
  result.insert 1, cmd
1729
1747
  }
1730
1748
  | block_call call_op2 operation2 opt_paren_args
1731
1749
  {
1732
- 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
1733
1753
  }
1734
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1735
1755
  {
1736
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1737
1757
 
1738
1758
  call = new_call iter1, name.to_sym, args
1739
1759
  iter2.insert 1, call
@@ -1742,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1742
1762
  }
1743
1763
  | block_call call_op2 operation2 command_args do_block
1744
1764
  {
1745
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1746
1766
 
1747
1767
  call = new_call iter1, name.to_sym, args
1748
1768
  iter2.insert 1, call
@@ -1750,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1770
  result = iter2
1751
1771
  }
1752
1772
 
1753
- method_call: fcall
1754
- {
1755
- result = self.lexer.lineno
1756
- }
1757
- paren_args
1773
+ method_call: fcall paren_args
1758
1774
  {
1759
- call, lineno, args = val
1775
+ call, args = val
1760
1776
 
1761
1777
  result = call.concat args.sexp_body if args
1762
- result.line lineno
1763
1778
  }
1764
1779
  | primary_value call_op operation2 opt_paren_args
1765
1780
  {
1766
- 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
1767
1784
  }
1768
1785
  | primary_value tCOLON2 operation2 paren_args
1769
1786
  {
1770
- 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
1771
1790
  }
1772
1791
  | primary_value tCOLON2 operation3
1773
1792
  {
1774
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1775
1796
  }
1776
1797
  | primary_value call_op paren_args
1777
1798
  {
@@ -1804,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1804
1825
  _, line, body, _ = val
1805
1826
 
1806
1827
  result = body
1807
- result.line = line
1828
+ result.line line
1808
1829
 
1809
1830
  self.env.unextend
1810
1831
  }
@@ -1818,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1818
1839
  _, line, body, _ = val
1819
1840
 
1820
1841
  result = body
1821
- result.line = line
1842
+ result.line line
1822
1843
 
1823
1844
  self.env.unextend
1824
1845
  }
@@ -1847,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1847
1868
  self.env.unextend
1848
1869
  }
1849
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
+
1850
1896
  case_body: k_when
1851
1897
  {
1852
1898
  result = self.lexer.lineno
1853
1899
  }
1854
- args then compstmt cases
1900
+ case_args then compstmt cases
1855
1901
  {
1856
1902
  result = new_when(val[2], val[4])
1857
- result.line = val[1]
1903
+ result.line val[1]
1858
1904
  result << val[5] if val[5]
1859
1905
  }
1860
1906
 
@@ -1900,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1900
1946
 
1901
1947
  literal: numeric
1902
1948
  {
1903
- line = lexer.lineno
1904
- result = s(:lit, val[0])
1905
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1906
1951
  }
1907
1952
  | symbol
1908
- {
1909
- line = lexer.lineno
1910
- result = s(:lit, val[0])
1911
- result.line = line
1912
- }
1913
- | dsym
1914
1953
 
1915
1954
  strings: string
1916
1955
  {
@@ -1921,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1921
1960
 
1922
1961
  string: tCHAR
1923
1962
  {
1924
- debug20 23, val, result
1963
+ debug 37
1925
1964
  }
1926
1965
  | string1
1927
1966
  | string string1
@@ -1931,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1931
1970
 
1932
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1933
1972
  {
1934
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1935
1974
 
1936
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1937
1976
 
1938
- result = str
1977
+ result = str.line line
1939
1978
  }
1940
1979
  | tSTRING
1941
1980
  {
@@ -1955,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1955
1994
 
1956
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1957
1996
  {
1958
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1959
2000
  }
1960
2001
  | tWORDS_BEG word_list tSTRING_END
1961
2002
  {
1962
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1963
2006
  }
1964
2007
 
1965
2008
  word_list: none
@@ -1979,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1979
2022
 
1980
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1981
2024
  {
1982
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1983
2028
  }
1984
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1985
2030
  {
1986
- _, line, list, _, = val
1987
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1988
2033
  result = list
1989
2034
  }
1990
2035
 
1991
2036
  symbol_list: none
1992
2037
  {
1993
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1994
2039
  }
1995
2040
  | symbol_list word tSPACE
1996
2041
  {
@@ -2000,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2000
2045
 
2001
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2002
2047
  {
2003
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2004
2051
  }
2005
2052
  | tQWORDS_BEG qword_list tSTRING_END
2006
2053
  {
2007
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2008
2057
  }
2009
2058
 
2010
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2011
2060
  {
2012
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2013
2064
  }
2014
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2015
2066
  {
2016
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2017
2070
  }
2018
2071
 
2019
2072
  qword_list: none
@@ -2036,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2036
2089
 
2037
2090
  string_contents: none
2038
2091
  {
2039
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2040
2094
  }
2041
2095
  | string_contents string_content
2042
2096
  {
@@ -2111,8 +2165,8 @@ regexp_contents: none
2111
2165
  lexer.brace_nest = brace_nest
2112
2166
  lexer.string_nest = string_nest
2113
2167
 
2114
- lexer.cmdarg.pop
2115
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2116
2170
 
2117
2171
  lexer.lex_state = oldlex_state
2118
2172
 
@@ -2127,29 +2181,42 @@ regexp_contents: none
2127
2181
  when nil then
2128
2182
  result = s(:evstr).line line
2129
2183
  else
2130
- debug20 25
2184
+ debug 38
2131
2185
  raise "unknown string body: #{stmt.inspect}"
2132
2186
  end
2133
2187
  }
2134
2188
 
2135
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2136
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2137
- | 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
+ }
2138
2201
  | backref
2139
2202
 
2140
- symbol: tSYMBEG sym
2203
+ symbol: ssym
2204
+ | dsym
2205
+
2206
+ ssym: tSYMBEG sym
2141
2207
  {
2142
2208
  lexer.lex_state = EXPR_END
2143
- result = val[1].to_sym
2209
+ result = wrap :lit, val[1]
2144
2210
  }
2145
2211
  | tSYMBOL
2146
2212
  {
2147
- result = val[0].to_sym
2213
+ lexer.lex_state = EXPR_END
2214
+ result = wrap :lit, val[0]
2148
2215
  }
2149
2216
 
2150
2217
  sym: fname | tIVAR | tGVAR | tCVAR
2151
2218
 
2152
- dsym: tSYMBEG xstring_contents tSTRING_END
2219
+ dsym: tSYMBEG string_contents tSTRING_END
2153
2220
  {
2154
2221
  _, result, _ = val
2155
2222
 
@@ -2165,14 +2232,15 @@ regexp_contents: none
2165
2232
  when :evstr then
2166
2233
  result = s(:dsym, "", result).line result.line
2167
2234
  else
2168
- debug20 26, val, result
2235
+ debug 39
2169
2236
  end
2170
2237
  }
2171
2238
 
2172
2239
  numeric: simple_numeric
2173
- | tUMINUS_NUM simple_numeric
2240
+ | tUMINUS_NUM simple_numeric =tLOWEST
2174
2241
  {
2175
- result = -val[1] # TODO: pt_testcase
2242
+ _, (num, line) = val
2243
+ result = [-num, line]
2176
2244
  }
2177
2245
 
2178
2246
  simple_numeric: tINTEGER
@@ -2205,8 +2273,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2205
2273
 
2206
2274
  var_ref: user_variable
2207
2275
  {
2208
- var = val[0]
2276
+ raise "NO: #{val.inspect}" if Sexp === val.first
2277
+ (var, line), = val
2209
2278
  result = Sexp === var ? var : self.gettable(var)
2279
+ result.line line
2210
2280
  }
2211
2281
  | keyword_variable
2212
2282
  {
@@ -2221,11 +2291,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2221
2291
  | keyword_variable
2222
2292
  {
2223
2293
  result = self.assignable val[0]
2224
- debug20 29, val, result
2294
+ debug 40
2225
2295
  }
2226
2296
 
2227
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2228
- | 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
+ }
2229
2307
 
2230
2308
  superclass: tLT
2231
2309
  {
@@ -2243,9 +2321,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2321
 
2244
2322
  f_arglist: tLPAREN2 f_args rparen
2245
2323
  {
2246
- result = val[1]
2247
- self.lexer.lex_state = EXPR_BEG
2248
- self.lexer.command_start = true
2324
+ result = end_args val
2249
2325
  }
2250
2326
  | {
2251
2327
  result = self.in_kwarg
@@ -2254,12 +2330,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2254
2330
  }
2255
2331
  f_args term
2256
2332
  {
2257
- kwarg, args, _ = val
2258
-
2259
- self.in_kwarg = kwarg
2260
- result = args
2261
- lexer.lex_state = EXPR_BEG
2262
- lexer.command_start = true
2333
+ result = end_args val
2263
2334
  }
2264
2335
 
2265
2336
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,8 +2415,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
2415
  |
2345
2416
  {
2346
2417
  result = args val
2418
+ # result.line lexer.lineno
2347
2419
  }
2348
2420
 
2421
+
2349
2422
  f_bad_arg: tCONSTANT
2350
2423
  {
2351
2424
  yyerror "formal argument cannot be a constant"
@@ -2366,10 +2439,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2439
  f_norm_arg: f_bad_arg
2367
2440
  | tIDENTIFIER
2368
2441
  {
2369
- identifier = val[0].to_sym
2442
+ (id, line), = val
2443
+ identifier = id.to_sym
2370
2444
  self.env[identifier] = :lvar
2371
2445
 
2372
- result = identifier
2446
+ result = [identifier, line]
2373
2447
  }
2374
2448
 
2375
2449
  f_arg_asgn: f_norm_arg
@@ -2377,22 +2451,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2377
2451
  f_arg_item: f_arg_asgn
2378
2452
  | tLPAREN f_margs rparen
2379
2453
  {
2380
- result = val[1]
2454
+ _, margs, _ = val
2455
+
2456
+ result = margs
2381
2457
  }
2382
2458
 
2383
2459
  f_arg: f_arg_item
2384
2460
  {
2385
- arg, = val
2386
-
2387
- case arg
2388
- when Symbol then
2389
- result = s(:args, arg).line lexer.lineno
2390
- when Sexp then
2391
- result = arg
2392
- else
2393
- debug20 32
2394
- raise "Unknown f_arg type: #{val.inspect}"
2395
- end
2461
+ result = new_arg val
2396
2462
  }
2397
2463
  | f_arg tCOMMA f_arg_item
2398
2464
  {
@@ -2404,7 +2470,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2404
2470
  result = s(:args, list).line list.line
2405
2471
  end
2406
2472
 
2407
- result << item
2473
+ result << (Sexp === item ? item : item.first)
2408
2474
  }
2409
2475
 
2410
2476
  f_label: tLABEL
@@ -2465,26 +2531,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2465
2531
  kwrest_mark: tPOW
2466
2532
  | tDSTAR
2467
2533
 
2534
+
2468
2535
  f_kwrest: kwrest_mark tIDENTIFIER
2469
2536
  {
2470
- name = val[1].to_sym
2471
- self.assignable name
2472
- result = :"**#{name}"
2537
+ _, (id, line) = val
2538
+
2539
+ name = id.to_sym
2540
+ self.assignable [name, line]
2541
+ result = [:"**#{name}", line]
2473
2542
  }
2474
2543
  | kwrest_mark
2475
2544
  {
2476
- result = :"**"
2545
+ id = :"**"
2546
+ self.env[id] = :lvar # TODO: needed?!?
2547
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2477
2548
  }
2478
2549
 
2479
2550
  f_opt: f_arg_asgn tEQL arg_value
2480
2551
  {
2481
- result = self.assignable val[0], val[2]
2552
+ lhs, _, rhs = val
2553
+ result = self.assignable lhs, rhs
2482
2554
  # TODO: detect duplicate names
2483
2555
  }
2484
2556
 
2485
2557
  f_block_opt: f_arg_asgn tEQL primary_value
2486
2558
  {
2487
- result = self.assignable val[0], val[2]
2559
+ lhs, _, rhs = val
2560
+ result = self.assignable lhs, rhs
2488
2561
  }
2489
2562
 
2490
2563
  f_block_optarg: f_block_opt
@@ -2514,30 +2587,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2514
2587
  f_rest_arg: restarg_mark tIDENTIFIER
2515
2588
  {
2516
2589
  # TODO: differs from parse.y - needs tests
2517
- name = val[1].to_sym
2518
- self.assignable name
2519
- result = :"*#{name}"
2590
+ _, (id, line) = val
2591
+ name = id.to_sym
2592
+ self.assignable [name, line]
2593
+ result = [:"*#{name}", line]
2520
2594
  }
2521
2595
  | restarg_mark
2522
2596
  {
2523
2597
  name = :"*"
2524
2598
  self.env[name] = :lvar
2525
- result = name
2599
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2526
2600
  }
2527
2601
 
2528
2602
  blkarg_mark: tAMPER2 | tAMPER
2529
2603
 
2530
2604
  f_block_arg: blkarg_mark tIDENTIFIER
2531
2605
  {
2532
- identifier = val[1].to_sym
2606
+ _, (id, line) = val
2607
+ identifier = id.to_sym
2533
2608
 
2534
2609
  self.env[identifier] = :lvar
2535
- result = "&#{identifier}".to_sym
2610
+ result = ["&#{identifier}".to_sym, line]
2536
2611
  }
2537
2612
 
2538
2613
  opt_f_block_arg: tCOMMA f_block_arg
2539
2614
  {
2540
- result = val[1]
2615
+ _, arg = val
2616
+ result = arg
2541
2617
  }
2542
2618
  |
2543
2619
  {
@@ -2579,16 +2655,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2579
2655
  }
2580
2656
  | tLABEL arg_value
2581
2657
  {
2582
- (label, line), arg = val
2658
+ label, arg = val
2583
2659
 
2584
- lit = s(:lit, label.to_sym).line line
2585
- result = s(:array, lit, arg).line line
2660
+ lit = wrap :lit, label
2661
+ result = s(:array, lit, arg).line lit.line
2586
2662
  }
2587
2663
  | tSTRING_BEG string_contents tLABEL_END arg_value
2588
2664
  {
2589
- _, sym, _, value = val
2665
+ (_, line), sym, _, value = val
2666
+
2590
2667
  sym.sexp_type = :dsym
2591
- result = s(:array, sym, value).line sym.line
2668
+
2669
+ result = s(:array, sym, value).line line
2592
2670
  }
2593
2671
  | tDSTAR arg_value
2594
2672
  {