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