ruby_parser 3.17.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. metadata.gz.sig +0 -0
data/lib/ruby26_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
@@ -80,7 +80,7 @@ rule
80
80
  | klBEGIN
81
81
  {
82
82
  if (self.in_def || self.in_single > 0) then
83
- debug20 1
83
+ debug 11
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -105,6 +105,8 @@ rule
105
105
  bodystmt: compstmt opt_rescue k_else
106
106
  {
107
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
108
110
  yyerror "else without rescue is useless" unless res
109
111
  }
110
112
  compstmt
@@ -135,7 +137,7 @@ rule
135
137
  | error stmt
136
138
  {
137
139
  result = val[1]
138
- debug20 2, val, result
140
+ debug 12
139
141
  }
140
142
 
141
143
  stmt_or_begin: stmt
@@ -143,6 +145,10 @@ rule
143
145
  {
144
146
  yyerror "BEGIN is permitted only at toplevel"
145
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
146
152
 
147
153
  stmt: kALIAS fitem
148
154
  {
@@ -155,12 +161,12 @@ rule
155
161
  }
156
162
  | kALIAS tGVAR tGVAR
157
163
  {
158
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
159
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
166
  }
161
167
  | kALIAS tGVAR tBACK_REF
162
168
  {
163
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
164
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
171
  }
166
172
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +209,7 @@ rule
203
209
  (_, line), _, stmt, _ = val
204
210
 
205
211
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
212
+ debug 13
207
213
  yyerror "END in method; use at_exit"
208
214
  end
209
215
 
@@ -243,32 +249,31 @@ rule
243
249
  }
244
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
251
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- 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
252
257
  }
253
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
259
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- 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
260
265
  }
261
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
267
  {
263
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
269
 
265
- 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
266
271
  }
267
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
273
  {
269
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
275
 
271
- 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
272
277
  }
273
278
  | backref tOP_ASGN command_rhs
274
279
  {
@@ -314,7 +319,7 @@ rule
314
319
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
320
  # REFACTOR: call_uni_op -- see parse26.y
316
321
  }
317
- | arg
322
+ | arg =tLBRACE_ARG
318
323
 
319
324
  expr_value: expr
320
325
  {
@@ -339,7 +344,7 @@ rule
339
344
  block_command: block_call
340
345
  | block_call call_op2 operation2 command_args
341
346
  {
342
- blk, _, msg, args = val
347
+ blk, _, (msg, _line), args = val
343
348
  result = new_call(blk, msg.to_sym, args).line blk.line
344
349
  }
345
350
 
@@ -353,15 +358,15 @@ rule
353
358
  _, line, body, _ = val
354
359
 
355
360
  result = body
356
- result.line = line
361
+ result.line line
357
362
 
358
363
  # self.env.unextend
359
364
  }
360
365
 
361
366
  fcall: operation
362
367
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
368
+ (msg, line), = val
369
+ result = new_call(nil, msg.to_sym).line line
365
370
  }
366
371
 
367
372
  command: fcall command_args =tLOWEST
@@ -384,12 +389,14 @@ rule
384
389
  }
385
390
  | primary_value call_op operation2 command_args =tLOWEST
386
391
  {
387
- lhs, callop, op, args = val
392
+ lhs, callop, (op, _), args = val
393
+
388
394
  result = new_call lhs, op.to_sym, args, callop
395
+ result.line lhs.line
389
396
  }
390
397
  | primary_value call_op operation2 command_args cmd_brace_block
391
398
  {
392
- recv, _, msg, args, block = val
399
+ recv, _, (msg, _line), args, block = val
393
400
  call = new_call recv, msg.to_sym, args, val[1]
394
401
 
395
402
  block_dup_check call, block
@@ -399,11 +406,14 @@ rule
399
406
  }
400
407
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
408
  {
402
- 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
403
413
  }
404
414
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
415
  {
406
- recv, _, msg, args, block = val
416
+ recv, _, (msg, _line), args, block = val
407
417
  call = new_call recv, msg.to_sym, args
408
418
 
409
419
  block_dup_check call, block
@@ -561,25 +571,29 @@ rule
561
571
  }
562
572
  | primary_value call_op tIDENTIFIER
563
573
  {
564
- 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
565
577
  }
566
578
  | primary_value tCOLON2 tIDENTIFIER
567
579
  {
568
- recv, _, id = val
580
+ recv, _, (id, _line) = val
569
581
  result = new_attrasgn recv, id
570
582
  }
571
583
  | primary_value call_op tCONSTANT
572
584
  {
573
- 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
574
588
  }
575
589
  | primary_value tCOLON2 tCONSTANT
576
590
  {
577
591
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
592
+ debug 14
579
593
  yyerror "dynamic constant assignment"
580
594
  end
581
595
 
582
- expr, _, id = val
596
+ expr, _, (id, _line) = val
583
597
  l = expr.line
584
598
 
585
599
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +601,65 @@ rule
587
601
  | tCOLON3 tCONSTANT
588
602
  {
589
603
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
604
+ debug 15
591
605
  yyerror "dynamic constant assignment"
592
606
  end
593
607
 
594
- _, id = val
595
- l = lexer.lineno
608
+ _, (id, l) = val
596
609
 
597
610
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
611
  }
599
612
  | backref
600
613
  {
601
- self.backref_assign_error val[0]
614
+ ref, = val
615
+
616
+ self.backref_assign_error ref
602
617
  }
603
618
 
604
619
  lhs: user_variable
605
620
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
621
+ var, = val
622
+
623
+ result = self.assignable var
609
624
  }
610
625
  | keyword_variable
611
626
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
627
+ var, = val
628
+
629
+ result = self.assignable var
630
+
631
+ debug 16
616
632
  }
617
633
  | primary_value tLBRACK2 opt_call_args rbracket
618
634
  {
619
635
  lhs, _, args, _ = val
636
+
620
637
  result = self.aryset lhs, args
621
638
  }
622
639
  | primary_value call_op tIDENTIFIER # REFACTOR
623
640
  {
624
- lhs, op, id = val
641
+ lhs, op, (id, _line) = val
642
+
625
643
  result = new_attrasgn lhs, id, op
626
644
  }
627
645
  | primary_value tCOLON2 tIDENTIFIER
628
646
  {
629
- lhs, _, id = val
647
+ lhs, _, (id, _line) = val
648
+
630
649
  result = new_attrasgn lhs, id
631
650
  }
632
651
  | primary_value call_op tCONSTANT # REFACTOR?
633
652
  {
634
- 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
635
656
  }
636
657
  | primary_value tCOLON2 tCONSTANT
637
658
  {
638
- expr, _, id = val
659
+ expr, _, (id, _line) = val
639
660
 
640
661
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
662
+ debug 17
642
663
  yyerror "dynamic constant assignment"
643
664
  end
644
665
 
@@ -647,14 +668,13 @@ rule
647
668
  }
648
669
  | tCOLON3 tCONSTANT
649
670
  {
650
- _, id = val
671
+ _, (id, l) = val
651
672
 
652
673
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
674
+ debug 18
654
675
  yyerror "dynamic constant assignment"
655
676
  end
656
677
 
657
- l = lexer.lineno
658
678
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
679
  }
660
680
  | backref
@@ -670,16 +690,16 @@ rule
670
690
 
671
691
  cpath: tCOLON3 cname
672
692
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
693
+ result = wrap :colon3, val[1]
675
694
  }
676
695
  | cname
677
696
  {
678
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
679
699
  }
680
700
  | primary_value tCOLON2 cname
681
701
  {
682
- pval, _, name = val
702
+ pval, _, (name, _line) = val
683
703
 
684
704
  result = s(:colon2, pval, name.to_sym)
685
705
  result.line pval.line
@@ -689,24 +709,15 @@ rule
689
709
  | op
690
710
  {
691
711
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
712
  }
694
713
 
695
714
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
715
 
704
- fitem: fsym
716
+ fitem: fname
705
717
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
718
+ result = wrap :lit, val[0]
708
719
  }
709
- | dsym
720
+ | symbol
710
721
 
711
722
  undef_list: fitem
712
723
  {
@@ -727,8 +738,6 @@ rule
727
738
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
739
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
740
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
741
 
733
742
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
743
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,26 +771,22 @@ rule
762
771
  }
763
772
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
773
  {
765
- lhs, _, id, op, rhs = val
774
+ lhs, _, (id, _line), (op, _), rhs = val
766
775
 
767
776
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
777
  }
769
778
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
779
  {
771
- lhs1, _, lhs2, op, rhs = val
780
+ lhs1, _, (lhs2, _line), op, rhs = val
772
781
 
773
782
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
783
  result = new_const_op_asgn [lhs, op, rhs]
775
784
  }
776
- | tCOLON3 tCONSTANT
777
- {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
785
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
781
786
  {
782
- _, lhs, line, op, rhs = val
787
+ _, lhs, op, rhs = val
783
788
 
784
- lhs = s(:colon3, lhs.to_sym).line line
789
+ lhs = wrap :colon3, lhs
785
790
  result = new_const_op_asgn [lhs, op, rhs]
786
791
  }
787
792
  | backref tOP_ASGN arg_rhs
@@ -793,7 +798,7 @@ rule
793
798
  | arg tDOT2 arg
794
799
  {
795
800
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
801
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
802
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
803
  else
799
804
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +807,7 @@ rule
802
807
  | arg tDOT3 arg
803
808
  {
804
809
  v1, v2 = val[0], val[2]
805
- 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
806
811
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
812
  else
808
813
  result = s(:dot3, v1, v2).line v1.line
@@ -850,8 +855,9 @@ rule
850
855
  }
851
856
  | tUMINUS_NUM simple_numeric tPOW arg
852
857
  {
853
- lit = s(:lit, val[1]).line lexer.lineno
854
- 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)), :"-@")
855
861
 
856
862
  }
857
863
  | tUPLUS arg
@@ -950,12 +956,12 @@ rule
950
956
 
951
957
  rel_expr: arg relop arg =tGT
952
958
  {
953
- lhs, op, rhs = val
959
+ lhs, (op, _), rhs = val
954
960
  result = new_call lhs, op.to_sym, argl(rhs)
955
961
  }
956
962
  | rel_expr relop arg =tGT
957
963
  {
958
- lhs, op, rhs = val
964
+ lhs, (op, _), rhs = val
959
965
  warn "comparison '%s' after comparison", op
960
966
  result = new_call lhs, op.to_sym, argl(rhs)
961
967
  }
@@ -1146,8 +1152,9 @@ rule
1146
1152
  | backref
1147
1153
  | tFID
1148
1154
  {
1149
- msg, = val
1155
+ (msg, line), = val
1150
1156
  result = new_call nil, msg.to_sym
1157
+ result.line line
1151
1158
  }
1152
1159
  | k_begin
1153
1160
  {
@@ -1189,15 +1196,13 @@ rule
1189
1196
  }
1190
1197
  | primary_value tCOLON2 tCONSTANT
1191
1198
  {
1192
- expr, _, id = val
1199
+ expr, _, (id, _line) = val
1193
1200
 
1194
1201
  result = s(:colon2, expr, id.to_sym).line expr.line
1195
1202
  }
1196
1203
  | tCOLON3 tCONSTANT
1197
1204
  {
1198
- _, id = val
1199
-
1200
- result = s(:colon3, id.to_sym).line lexer.lineno
1205
+ result = wrap :colon3, val[1]
1201
1206
  }
1202
1207
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1203
1208
  {
@@ -1221,15 +1226,21 @@ rule
1221
1226
  }
1222
1227
  | kYIELD tLPAREN2 call_args rparen
1223
1228
  {
1224
- result = new_yield val[2]
1229
+ (_, line), _, args, _ = val
1230
+
1231
+ result = new_yield(args).line line
1225
1232
  }
1226
1233
  | kYIELD tLPAREN2 rparen
1227
1234
  {
1228
- result = new_yield
1235
+ (_, line), _, _ = val
1236
+
1237
+ result = new_yield.line line
1229
1238
  }
1230
1239
  | kYIELD
1231
1240
  {
1232
- result = new_yield
1241
+ (_, line), = val
1242
+
1243
+ result = new_yield.line line
1233
1244
  }
1234
1245
  | kDEFINED opt_nl tLPAREN2 expr rparen
1235
1246
  {
@@ -1244,7 +1255,7 @@ rule
1244
1255
  }
1245
1256
  | kNOT tLPAREN2 rparen
1246
1257
  {
1247
- debug20 14, val, result
1258
+ debug 20
1248
1259
  }
1249
1260
  | fcall brace_block
1250
1261
  {
@@ -1262,9 +1273,10 @@ rule
1262
1273
  iter.insert 1, call # FIX
1263
1274
  result = iter
1264
1275
  }
1265
- | tLAMBDA lambda
1276
+ | lambda
1266
1277
  {
1267
- result = val[1] # TODO: fix lineno
1278
+ expr, = val
1279
+ result = expr
1268
1280
  }
1269
1281
  | k_if expr_value then compstmt if_tail k_end
1270
1282
  {
@@ -1307,7 +1319,6 @@ rule
1307
1319
  }
1308
1320
  cpath superclass
1309
1321
  {
1310
- self.comments.push self.lexer.comments
1311
1322
  if (self.in_def || self.in_single > 0) then
1312
1323
  yyerror "class definition in method body"
1313
1324
  end
@@ -1317,7 +1328,7 @@ rule
1317
1328
  {
1318
1329
  result = new_class val
1319
1330
  self.env.unextend
1320
- self.lexer.comments # we don't care about comments in the body
1331
+ self.lexer.ignore_body_comments
1321
1332
  }
1322
1333
  | k_class tLSHFT
1323
1334
  {
@@ -1338,7 +1349,7 @@ rule
1338
1349
  {
1339
1350
  result = new_sclass val
1340
1351
  self.env.unextend
1341
- self.lexer.comments # we don't care about comments in the body
1352
+ self.lexer.ignore_body_comments
1342
1353
  }
1343
1354
  | k_module
1344
1355
  {
@@ -1346,7 +1357,6 @@ rule
1346
1357
  }
1347
1358
  cpath
1348
1359
  {
1349
- self.comments.push self.lexer.comments
1350
1360
  yyerror "module definition in method body" if
1351
1361
  self.in_def or self.in_single > 0
1352
1362
 
@@ -1356,7 +1366,7 @@ rule
1356
1366
  {
1357
1367
  result = new_module val
1358
1368
  self.env.unextend
1359
- self.lexer.comments # we don't care about comments in the body
1369
+ self.lexer.ignore_body_comments
1360
1370
  }
1361
1371
  | k_def fname
1362
1372
  {
@@ -1366,21 +1376,17 @@ rule
1366
1376
  self.env.extend
1367
1377
  lexer.cmdarg.push false
1368
1378
  lexer.cond.push false
1369
-
1370
- self.comments.push self.lexer.comments
1371
1379
  }
1372
- f_arglist bodystmt { result = lexer.lineno } k_end
1380
+ f_arglist bodystmt k_end
1373
1381
  {
1374
- in_def = val[2]
1375
-
1376
- result = new_defn val
1382
+ result, in_def = new_defn val
1377
1383
 
1378
1384
  lexer.cond.pop # group = local_pop
1379
1385
  lexer.cmdarg.pop
1380
1386
  self.env.unextend
1381
1387
  self.in_def = in_def
1382
1388
 
1383
- self.lexer.comments # we don't care about comments in the body
1389
+ self.lexer.ignore_body_comments
1384
1390
  }
1385
1391
  | k_def singleton dot_or_colon
1386
1392
  {
@@ -1388,7 +1394,7 @@ rule
1388
1394
  }
1389
1395
  fname
1390
1396
  {
1391
- result = [self.in_def, lexer.lineno]
1397
+ result = self.in_def
1392
1398
 
1393
1399
  self.in_single += 1 # TODO: remove?
1394
1400
 
@@ -1398,13 +1404,18 @@ rule
1398
1404
  lexer.cond.push false
1399
1405
 
1400
1406
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1401
- self.comments.push self.lexer.comments
1402
1407
  }
1403
1408
  f_arglist bodystmt k_end
1404
1409
  {
1405
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1406
1410
 
1407
- 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
1408
1419
 
1409
1420
  lexer.cond.pop # group = local_pop
1410
1421
  lexer.cmdarg.pop
@@ -1415,7 +1426,7 @@ rule
1415
1426
 
1416
1427
  # TODO: restore cur_arg ? what's cur_arg?
1417
1428
 
1418
- self.lexer.comments # we don't care about comments in the body
1429
+ self.lexer.ignore_body_comments
1419
1430
  }
1420
1431
  | kBREAK
1421
1432
  {
@@ -1452,8 +1463,17 @@ rule
1452
1463
  k_case: kCASE
1453
1464
  k_for: kFOR
1454
1465
  k_class: kCLASS
1466
+ {
1467
+ self.comments.push self.lexer.comments
1468
+ }
1455
1469
  k_module: kMODULE
1470
+ {
1471
+ self.comments.push self.lexer.comments
1472
+ }
1456
1473
  k_def: kDEF
1474
+ {
1475
+ self.comments.push self.lexer.comments
1476
+ }
1457
1477
  k_do: kDO
1458
1478
  k_do_block: kDO_BLOCK
1459
1479
  k_rescue: kRESCUE
@@ -1514,51 +1534,42 @@ rule
1514
1534
 
1515
1535
  result = block_var args
1516
1536
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg
1537
+ | f_marg_list tCOMMA f_rest_marg
1518
1538
  {
1519
- args, _, _, splat = val
1539
+ args, _, rest = val
1520
1540
 
1521
- result = block_var args, "*#{splat}".to_sym
1541
+ result = block_var args, rest
1522
1542
  }
1523
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1543
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1524
1544
  {
1525
- args, _, _, splat, _, args2 = val
1545
+ lhs, _, splat, _, rhs = val
1526
1546
 
1527
- result = block_var args, "*#{splat}".to_sym, args2
1547
+ result = block_var lhs, splat, rhs
1528
1548
  }
1529
- | f_marg_list tCOMMA tSTAR
1549
+ | f_rest_marg
1530
1550
  {
1531
- args, _, _ = val
1551
+ rest, = val
1532
1552
 
1533
- result = block_var args, :*
1553
+ result = block_var rest
1534
1554
  }
1535
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1555
+ | f_rest_marg tCOMMA f_marg_list
1536
1556
  {
1537
- args, _, _, _, args2 = val
1557
+ splat, _, rest = val
1538
1558
 
1539
- result = block_var args, :*, args2
1559
+ result = block_var splat, rest
1540
1560
  }
1541
- | tSTAR f_norm_arg
1542
- {
1543
- _, splat = val
1544
1561
 
1545
- result = block_var :"*#{splat}"
1546
- }
1547
- | tSTAR f_norm_arg tCOMMA f_marg_list
1562
+ f_rest_marg: tSTAR f_norm_arg
1548
1563
  {
1549
- _, splat, _, args = val
1564
+ _, (id, line) = val
1550
1565
 
1551
- result = block_var :"*#{splat}", args
1566
+ result = args ["*#{id}".to_sym]
1567
+ result.line line
1552
1568
  }
1553
1569
  | tSTAR
1554
1570
  {
1555
- result = block_var :*
1556
- }
1557
- | tSTAR tCOMMA f_marg_list
1558
- {
1559
- _, _, args = val
1560
-
1561
- result = block_var :*, args
1571
+ result = args [:*]
1572
+ result.line lexer.lineno # FIX: tSTAR -> line
1562
1573
  }
1563
1574
 
1564
1575
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1575,8 +1586,8 @@ rule
1575
1586
  }
1576
1587
  | f_block_arg
1577
1588
  {
1578
- line = lexer.lineno
1579
- result = call_args val # TODO: push line down
1589
+ (id, line), = val
1590
+ result = call_args [id]
1580
1591
  result.line line
1581
1592
  }
1582
1593
 
@@ -1685,13 +1696,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1685
1696
 
1686
1697
  bvar: tIDENTIFIER
1687
1698
  {
1688
- id, = val
1689
- line = lexer.lineno
1690
- result = s(:shadow, id.to_sym).line line
1699
+ result = wrap :shadow, val[0]
1691
1700
  }
1692
1701
  | f_bad_arg
1693
1702
 
1694
- lambda: {
1703
+ lambda: tLAMBDA
1704
+ {
1695
1705
  self.env.extend :dynamic
1696
1706
  result = [lexer.lineno, lexer.lpar_beg]
1697
1707
  lexer.paren_nest += 1
@@ -1703,14 +1713,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1703
1713
  }
1704
1714
  lambda_body
1705
1715
  {
1706
- (line, lpar), args, _cmdarg, body = val
1716
+ _, (line, lpar), args, _cmdarg, body = val
1707
1717
  lexer.lpar_beg = lpar
1708
1718
 
1709
1719
  lexer.cmdarg.pop
1710
1720
 
1711
1721
  call = s(:lambda).line line
1712
1722
  result = new_iter call, args, body
1713
- result.line = line
1723
+ result.line line
1714
1724
  self.env.unextend # TODO: dynapush & dynapop
1715
1725
  }
1716
1726
 
@@ -1745,23 +1755,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1745
1755
  ## if (nd_type($1) == NODE_YIELD) {
1746
1756
  ## compile_error(PARSER_ARG "block given to yield");
1747
1757
 
1748
- syntax_error "Both block arg and actual block given." if
1749
- val[0].block_pass?
1758
+ cmd, blk = val
1750
1759
 
1751
- val = invert_block_call val if inverted? val
1760
+ syntax_error "Both block arg and actual block given." if
1761
+ cmd.block_pass?
1752
1762
 
1753
- cmd, blk = val
1763
+ if inverted? val then
1764
+ val = invert_block_call val
1765
+ cmd, blk = val
1766
+ end
1754
1767
 
1755
1768
  result = blk
1756
1769
  result.insert 1, cmd
1757
1770
  }
1758
1771
  | block_call call_op2 operation2 opt_paren_args
1759
1772
  {
1760
- 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
1761
1776
  }
1762
1777
  | block_call call_op2 operation2 opt_paren_args brace_block
1763
1778
  {
1764
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1765
1780
 
1766
1781
  call = new_call iter1, name.to_sym, args
1767
1782
  iter2.insert 1, call
@@ -1770,7 +1785,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1770
1785
  }
1771
1786
  | block_call call_op2 operation2 command_args do_block
1772
1787
  {
1773
- iter1, _, name, args, iter2 = val
1788
+ iter1, _, (name, _line), args, iter2 = val
1774
1789
 
1775
1790
  call = new_call iter1, name.to_sym, args
1776
1791
  iter2.insert 1, call
@@ -1778,28 +1793,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1778
1793
  result = iter2
1779
1794
  }
1780
1795
 
1781
- method_call: fcall
1796
+ method_call: fcall paren_args
1782
1797
  {
1783
- result = self.lexer.lineno
1784
- }
1785
- paren_args
1786
- {
1787
- call, lineno, args = val
1798
+ call, args = val
1788
1799
 
1789
1800
  result = call.concat args.sexp_body if args
1790
- result.line lineno
1791
1801
  }
1792
1802
  | primary_value call_op operation2 opt_paren_args
1793
1803
  {
1794
- 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
1795
1807
  }
1796
1808
  | primary_value tCOLON2 operation2 paren_args
1797
1809
  {
1798
- 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
1799
1813
  }
1800
1814
  | primary_value tCOLON2 operation3
1801
1815
  {
1802
- result = new_call val[0], val[2].to_sym
1816
+ lhs, _, (id, _line) = val
1817
+
1818
+ result = new_call lhs, id.to_sym
1803
1819
  }
1804
1820
  | primary_value call_op paren_args
1805
1821
  {
@@ -1832,7 +1848,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1832
1848
  _, line, body, _ = val
1833
1849
 
1834
1850
  result = body
1835
- result.line = line
1851
+ result.line line
1836
1852
 
1837
1853
  self.env.unextend
1838
1854
  }
@@ -1846,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1846
1862
  _, line, body, _ = val
1847
1863
 
1848
1864
  result = body
1849
- result.line = line
1865
+ result.line line
1850
1866
 
1851
1867
  self.env.unextend
1852
1868
  }
@@ -1875,14 +1891,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1875
1891
  self.env.unextend
1876
1892
  }
1877
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
+
1878
1919
  case_body: k_when
1879
1920
  {
1880
1921
  result = self.lexer.lineno
1881
1922
  }
1882
- args then compstmt cases
1923
+ case_args then compstmt cases
1883
1924
  {
1884
1925
  result = new_when(val[2], val[4])
1885
- result.line = val[1]
1926
+ result.line val[1]
1886
1927
  result << val[5] if val[5]
1887
1928
  }
1888
1929
 
@@ -1928,17 +1969,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1928
1969
 
1929
1970
  literal: numeric
1930
1971
  {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1972
+ (lit, line), = val
1973
+ result = s(:lit, lit).line line
1934
1974
  }
1935
1975
  | symbol
1936
- {
1937
- line = lexer.lineno
1938
- result = s(:lit, val[0])
1939
- result.line = line
1940
- }
1941
- | dsym
1942
1976
 
1943
1977
  strings: string
1944
1978
  {
@@ -1949,7 +1983,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1949
1983
 
1950
1984
  string: tCHAR
1951
1985
  {
1952
- debug20 23, val, result
1986
+ debug 37
1953
1987
  }
1954
1988
  | string1
1955
1989
  | string string1
@@ -1959,11 +1993,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1959
1993
 
1960
1994
  string1: tSTRING_BEG string_contents tSTRING_END
1961
1995
  {
1962
- _, str, (_, func) = val
1996
+ (_, line), str, (_, func) = val
1963
1997
 
1964
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1998
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1965
1999
 
1966
- result = str
2000
+ result = str.line line
1967
2001
  }
1968
2002
  | tSTRING
1969
2003
  {
@@ -1983,11 +2017,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1983
2017
 
1984
2018
  words: tWORDS_BEG tSPACE tSTRING_END
1985
2019
  {
1986
- result = s(:array).line lexer.lineno
2020
+ (_, line), _, _ = val
2021
+
2022
+ result = s(:array).line line
1987
2023
  }
1988
2024
  | tWORDS_BEG word_list tSTRING_END
1989
2025
  {
1990
- result = val[1]
2026
+ (_, line), list, _ = val
2027
+
2028
+ result = list.line line
1991
2029
  }
1992
2030
 
1993
2031
  word_list: none
@@ -2007,18 +2045,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2007
2045
 
2008
2046
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2009
2047
  {
2010
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2011
2051
  }
2012
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2052
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2013
2053
  {
2014
- _, line, list, _, = val
2015
- list.line = line
2054
+ (_, line), list, _, = val
2055
+ list.line line
2016
2056
  result = list
2017
2057
  }
2018
2058
 
2019
2059
  symbol_list: none
2020
2060
  {
2021
- result = new_symbol_list.line lexer.lineno
2061
+ result = new_symbol_list
2022
2062
  }
2023
2063
  | symbol_list word tSPACE
2024
2064
  {
@@ -2028,20 +2068,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2028
2068
 
2029
2069
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2030
2070
  {
2031
- result = s(:array).line lexer.lineno
2071
+ (_, line), _, _ = val
2072
+
2073
+ result = s(:array).line line
2032
2074
  }
2033
2075
  | tQWORDS_BEG qword_list tSTRING_END
2034
2076
  {
2035
- result = val[1]
2077
+ (_, line), list, _ = val
2078
+
2079
+ result = list.line line
2036
2080
  }
2037
2081
 
2038
2082
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2039
2083
  {
2040
- result = s(:array).line lexer.lineno # FIX
2084
+ (_, line), _, _ = val
2085
+
2086
+ result = s(:array).line line
2041
2087
  }
2042
2088
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2043
2089
  {
2044
- result = val[1]
2090
+ (_, line), list, _ = val
2091
+
2092
+ result = list.line line
2045
2093
  }
2046
2094
 
2047
2095
  qword_list: none
@@ -2064,7 +2112,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2064
2112
 
2065
2113
  string_contents: none
2066
2114
  {
2067
- result = s(:str, "").line lexer.lineno
2115
+ line = prev_value_to_lineno _values.last
2116
+ result = s(:str, +"").line line
2068
2117
  }
2069
2118
  | string_contents string_content
2070
2119
  {
@@ -2139,8 +2188,8 @@ regexp_contents: none
2139
2188
  lexer.brace_nest = brace_nest
2140
2189
  lexer.string_nest = string_nest
2141
2190
 
2142
- lexer.cmdarg.pop
2143
2191
  lexer.cond.pop
2192
+ lexer.cmdarg.pop
2144
2193
 
2145
2194
  lexer.lex_state = oldlex_state
2146
2195
 
@@ -2155,29 +2204,42 @@ regexp_contents: none
2155
2204
  when nil then
2156
2205
  result = s(:evstr).line line
2157
2206
  else
2158
- debug20 25
2207
+ debug 38
2159
2208
  raise "unknown string body: #{stmt.inspect}"
2160
2209
  end
2161
2210
  }
2162
2211
 
2163
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2164
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2165
- | 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
+ }
2166
2224
  | backref
2167
2225
 
2168
- symbol: tSYMBEG sym
2226
+ symbol: ssym
2227
+ | dsym
2228
+
2229
+ ssym: tSYMBEG sym
2169
2230
  {
2170
2231
  lexer.lex_state = EXPR_END
2171
- result = val[1].to_sym
2232
+ result = wrap :lit, val[1]
2172
2233
  }
2173
2234
  | tSYMBOL
2174
2235
  {
2175
- result = val[0].to_sym
2236
+ lexer.lex_state = EXPR_END
2237
+ result = wrap :lit, val[0]
2176
2238
  }
2177
2239
 
2178
2240
  sym: fname | tIVAR | tGVAR | tCVAR
2179
2241
 
2180
- dsym: tSYMBEG xstring_contents tSTRING_END
2242
+ dsym: tSYMBEG string_contents tSTRING_END
2181
2243
  {
2182
2244
  _, result, _ = val
2183
2245
 
@@ -2193,14 +2255,15 @@ regexp_contents: none
2193
2255
  when :evstr then
2194
2256
  result = s(:dsym, "", result).line result.line
2195
2257
  else
2196
- debug20 26, val, result
2258
+ debug 39
2197
2259
  end
2198
2260
  }
2199
2261
 
2200
2262
  numeric: simple_numeric
2201
- | tUMINUS_NUM simple_numeric
2263
+ | tUMINUS_NUM simple_numeric =tLOWEST
2202
2264
  {
2203
- result = -val[1] # TODO: pt_testcase
2265
+ _, (num, line) = val
2266
+ result = [-num, line]
2204
2267
  }
2205
2268
 
2206
2269
  simple_numeric: tINTEGER
@@ -2233,8 +2296,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2233
2296
 
2234
2297
  var_ref: user_variable
2235
2298
  {
2236
- var = val[0]
2299
+ raise "NO: #{val.inspect}" if Sexp === val.first
2300
+ (var, line), = val
2237
2301
  result = Sexp === var ? var : self.gettable(var)
2302
+ result.line line
2238
2303
  }
2239
2304
  | keyword_variable
2240
2305
  {
@@ -2249,11 +2314,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2249
2314
  | keyword_variable
2250
2315
  {
2251
2316
  result = self.assignable val[0]
2252
- debug20 29, val, result
2317
+ debug 40
2253
2318
  }
2254
2319
 
2255
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2256
- | 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
+ }
2257
2330
 
2258
2331
  superclass: tLT
2259
2332
  {
@@ -2271,9 +2344,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2271
2344
 
2272
2345
  f_arglist: tLPAREN2 f_args rparen
2273
2346
  {
2274
- result = val[1]
2275
- self.lexer.lex_state = EXPR_BEG
2276
- self.lexer.command_start = true
2347
+ result = end_args val
2277
2348
  }
2278
2349
  | {
2279
2350
  result = self.in_kwarg
@@ -2282,12 +2353,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2282
2353
  }
2283
2354
  f_args term
2284
2355
  {
2285
- kwarg, args, _ = val
2286
-
2287
- self.in_kwarg = kwarg
2288
- result = args
2289
- lexer.lex_state = EXPR_BEG
2290
- lexer.command_start = true
2356
+ result = end_args val
2291
2357
  }
2292
2358
 
2293
2359
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2372,6 +2438,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2372
2438
  |
2373
2439
  {
2374
2440
  result = args val
2441
+ # result.line lexer.lineno
2375
2442
  }
2376
2443
 
2377
2444
 
@@ -2395,10 +2462,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2395
2462
  f_norm_arg: f_bad_arg
2396
2463
  | tIDENTIFIER
2397
2464
  {
2398
- identifier = val[0].to_sym
2465
+ (id, line), = val
2466
+ identifier = id.to_sym
2399
2467
  self.env[identifier] = :lvar
2400
2468
 
2401
- result = identifier
2469
+ result = [identifier, line]
2402
2470
  }
2403
2471
 
2404
2472
  f_arg_asgn: f_norm_arg
@@ -2406,22 +2474,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2406
2474
  f_arg_item: f_arg_asgn
2407
2475
  | tLPAREN f_margs rparen
2408
2476
  {
2409
- result = val[1]
2477
+ _, margs, _ = val
2478
+
2479
+ result = margs
2410
2480
  }
2411
2481
 
2412
2482
  f_arg: f_arg_item
2413
2483
  {
2414
- arg, = val
2415
-
2416
- case arg
2417
- when Symbol then
2418
- result = s(:args, arg).line lexer.lineno
2419
- when Sexp then
2420
- result = arg
2421
- else
2422
- debug20 32
2423
- raise "Unknown f_arg type: #{val.inspect}"
2424
- end
2484
+ result = new_arg val
2425
2485
  }
2426
2486
  | f_arg tCOMMA f_arg_item
2427
2487
  {
@@ -2433,7 +2493,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2433
2493
  result = s(:args, list).line list.line
2434
2494
  end
2435
2495
 
2436
- result << item
2496
+ result << (Sexp === item ? item : item.first)
2437
2497
  }
2438
2498
 
2439
2499
  f_label: tLABEL
@@ -2494,27 +2554,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2494
2554
  kwrest_mark: tPOW
2495
2555
  | tDSTAR
2496
2556
 
2557
+
2497
2558
  f_kwrest: kwrest_mark tIDENTIFIER
2498
2559
  {
2499
- name = val[1].to_sym
2500
- self.assignable name
2501
- result = :"**#{name}"
2560
+ _, (id, line) = val
2561
+
2562
+ name = id.to_sym
2563
+ self.assignable [name, line]
2564
+ result = [:"**#{name}", line]
2502
2565
  }
2503
2566
  | kwrest_mark
2504
2567
  {
2505
- result = :"**"
2506
- self.env[result] = :lvar
2568
+ id = :"**"
2569
+ self.env[id] = :lvar # TODO: needed?!?
2570
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2507
2571
  }
2508
2572
 
2509
2573
  f_opt: f_arg_asgn tEQL arg_value
2510
2574
  {
2511
- result = self.assignable val[0], val[2]
2575
+ lhs, _, rhs = val
2576
+ result = self.assignable lhs, rhs
2512
2577
  # TODO: detect duplicate names
2513
2578
  }
2514
2579
 
2515
2580
  f_block_opt: f_arg_asgn tEQL primary_value
2516
2581
  {
2517
- result = self.assignable val[0], val[2]
2582
+ lhs, _, rhs = val
2583
+ result = self.assignable lhs, rhs
2518
2584
  }
2519
2585
 
2520
2586
  f_block_optarg: f_block_opt
@@ -2544,30 +2610,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
2610
  f_rest_arg: restarg_mark tIDENTIFIER
2545
2611
  {
2546
2612
  # TODO: differs from parse.y - needs tests
2547
- name = val[1].to_sym
2548
- self.assignable name
2549
- result = :"*#{name}"
2613
+ _, (id, line) = val
2614
+ name = id.to_sym
2615
+ self.assignable [name, line]
2616
+ result = [:"*#{name}", line]
2550
2617
  }
2551
2618
  | restarg_mark
2552
2619
  {
2553
2620
  name = :"*"
2554
2621
  self.env[name] = :lvar
2555
- result = name
2622
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2556
2623
  }
2557
2624
 
2558
2625
  blkarg_mark: tAMPER2 | tAMPER
2559
2626
 
2560
2627
  f_block_arg: blkarg_mark tIDENTIFIER
2561
2628
  {
2562
- identifier = val[1].to_sym
2629
+ _, (id, line) = val
2630
+ identifier = id.to_sym
2563
2631
 
2564
2632
  self.env[identifier] = :lvar
2565
- result = "&#{identifier}".to_sym
2633
+ result = ["&#{identifier}".to_sym, line]
2566
2634
  }
2567
2635
 
2568
2636
  opt_f_block_arg: tCOMMA f_block_arg
2569
2637
  {
2570
- result = val[1]
2638
+ _, arg = val
2639
+ result = arg
2571
2640
  }
2572
2641
  |
2573
2642
  {
@@ -2609,16 +2678,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2609
2678
  }
2610
2679
  | tLABEL arg_value
2611
2680
  {
2612
- (label, line), arg = val
2681
+ label, arg = val
2613
2682
 
2614
- lit = s(:lit, label.to_sym).line line
2615
- result = s(:array, lit, arg).line line
2683
+ lit = wrap :lit, label
2684
+ result = s(:array, lit, arg).line lit.line
2616
2685
  }
2617
2686
  | tSTRING_BEG string_contents tLABEL_END arg_value
2618
2687
  {
2619
- _, sym, _, value = val
2688
+ (_, line), sym, _, value = val
2689
+
2620
2690
  sym.sexp_type = :dsym
2621
- result = s(:array, sym, value).line sym.line
2691
+
2692
+ result = s(:array, sym, value).line line
2622
2693
  }
2623
2694
  | tDSTAR arg_value
2624
2695
  {