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/ruby20_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
 
23
23
  preclow
24
24
  nonassoc tLOWEST
@@ -30,7 +30,7 @@ preclow
30
30
  right tEQL tOP_ASGN
31
31
  left kRESCUE_MOD
32
32
  right tEH tCOLON
33
- nonassoc tDOT2 tDOT3
33
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
34
34
  left tOROP
35
35
  left tANDOP
36
36
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -53,6 +53,9 @@ rule
53
53
  top_compstmt
54
54
  {
55
55
  result = new_compstmt val
56
+
57
+ lexer.cond.pop # local_pop
58
+ lexer.cmdarg.pop
56
59
  }
57
60
 
58
61
  top_compstmt: top_stmts opt_terms
@@ -73,7 +76,7 @@ rule
73
76
  | klBEGIN
74
77
  {
75
78
  if (self.in_def || self.in_single > 0) then
76
- debug20 1
79
+ debug 11
77
80
  yyerror "BEGIN in method"
78
81
  end
79
82
  self.env.extend
@@ -98,7 +101,9 @@ rule
98
101
  bodystmt: compstmt opt_rescue k_else
99
102
  {
100
103
  res = _values[-2]
101
- yyerror "else without rescue is useless" unless res
104
+ # TODO: move down to main match so I can just use val
105
+
106
+ warn "else without rescue is useless" unless res
102
107
  }
103
108
  compstmt
104
109
  opt_ensure
@@ -128,7 +133,7 @@ rule
128
133
  | error stmt
129
134
  {
130
135
  result = val[1]
131
- debug20 2, val, result
136
+ debug 12
132
137
  }
133
138
 
134
139
  stmt_or_begin: stmt
@@ -136,6 +141,10 @@ rule
136
141
  {
137
142
  yyerror "BEGIN is permitted only at toplevel"
138
143
  }
144
+ begin_block
145
+ {
146
+ result = val[2] # wtf?
147
+ }
139
148
 
140
149
  stmt: kALIAS fitem
141
150
  {
@@ -148,12 +157,12 @@ rule
148
157
  }
149
158
  | kALIAS tGVAR tGVAR
150
159
  {
151
- (_, line), lhs, rhs = val
160
+ (_, line), (lhs, _), (rhs, _) = val
152
161
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
153
162
  }
154
163
  | kALIAS tGVAR tBACK_REF
155
164
  {
156
- (_, line), lhs, rhs = val
165
+ (_, line), (lhs, _), (rhs, _) = val
157
166
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
158
167
  }
159
168
  | kALIAS tGVAR tNTH_REF
@@ -196,7 +205,7 @@ rule
196
205
  (_, line), _, stmt, _ = val
197
206
 
198
207
  if (self.in_def || self.in_single > 0) then
199
- debug20 3
208
+ debug 13
200
209
  yyerror "END in method; use at_exit"
201
210
  end
202
211
 
@@ -240,32 +249,31 @@ rule
240
249
  }
241
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
242
251
  {
243
- prim, _, id, opasgn, rhs = val
244
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
245
- if val[1] == '&.'
246
- result.sexp_type = :safe_op_asgn
247
- end
248
- 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
249
257
  }
250
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
251
259
  {
252
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
253
- if val[1] == '&.'
254
- result.sexp_type = :safe_op_asgn
255
- end
256
- 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
257
265
  }
258
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
259
267
  {
260
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
261
269
 
262
- 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
263
271
  }
264
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
265
273
  {
266
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
267
275
 
268
- 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
269
277
  }
270
278
  | backref tOP_ASGN command_rhs
271
279
  {
@@ -303,7 +311,7 @@ rule
303
311
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
304
312
  # REFACTOR: call_uni_op -- see parse26.y
305
313
  }
306
- | arg
314
+ | arg =tLBRACE_ARG
307
315
 
308
316
  expr_value: expr
309
317
  {
@@ -328,7 +336,7 @@ rule
328
336
  block_command: block_call
329
337
  | block_call call_op2 operation2 command_args
330
338
  {
331
- blk, _, msg, args = val
339
+ blk, _, (msg, _line), args = val
332
340
  result = new_call(blk, msg.to_sym, args).line blk.line
333
341
  }
334
342
 
@@ -342,15 +350,15 @@ rule
342
350
  _, line, body, _ = val
343
351
 
344
352
  result = body
345
- result.line = line
353
+ result.line line
346
354
 
347
355
  # self.env.unextend
348
356
  }
349
357
 
350
358
  fcall: operation
351
359
  {
352
- msg, = val
353
- result = new_call(nil, msg.to_sym).line lexer.lineno
360
+ (msg, line), = val
361
+ result = new_call(nil, msg.to_sym).line line
354
362
  }
355
363
 
356
364
  command: fcall command_args =tLOWEST
@@ -373,12 +381,14 @@ rule
373
381
  }
374
382
  | primary_value call_op operation2 command_args =tLOWEST
375
383
  {
376
- lhs, callop, op, args = val
384
+ lhs, callop, (op, _), args = val
385
+
377
386
  result = new_call lhs, op.to_sym, args, callop
387
+ result.line lhs.line
378
388
  }
379
389
  | primary_value call_op operation2 command_args cmd_brace_block
380
390
  {
381
- recv, _, msg, args, block = val
391
+ recv, _, (msg, _line), args, block = val
382
392
  call = new_call recv, msg.to_sym, args, val[1]
383
393
 
384
394
  block_dup_check call, block
@@ -388,11 +398,14 @@ rule
388
398
  }
389
399
  | primary_value tCOLON2 operation2 command_args =tLOWEST
390
400
  {
391
- result = new_call val[0], val[2].to_sym, val[3]
401
+ lhs, _, (id, line), args = val
402
+
403
+ result = new_call lhs, id.to_sym, args
404
+ result.line line
392
405
  }
393
406
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
394
407
  {
395
- recv, _, msg, args, block = val
408
+ recv, _, (msg, _line), args, block = val
396
409
  call = new_call recv, msg.to_sym, args
397
410
 
398
411
  block_dup_check call, block
@@ -550,25 +563,29 @@ rule
550
563
  }
551
564
  | primary_value call_op tIDENTIFIER
552
565
  {
553
- result = new_attrasgn val[0], val[2], val[1]
566
+ lhs, call_op, (id, _line) = val
567
+
568
+ result = new_attrasgn lhs, id, call_op
554
569
  }
555
570
  | primary_value tCOLON2 tIDENTIFIER
556
571
  {
557
- recv, _, id = val
572
+ recv, _, (id, _line) = val
558
573
  result = new_attrasgn recv, id
559
574
  }
560
575
  | primary_value call_op tCONSTANT
561
576
  {
562
- result = new_attrasgn val[0], val[2], val[1]
577
+ lhs, call_op, (id, _line) = val
578
+
579
+ result = new_attrasgn lhs, id, call_op
563
580
  }
564
581
  | primary_value tCOLON2 tCONSTANT
565
582
  {
566
583
  if (self.in_def || self.in_single > 0) then
567
- debug20 7
584
+ debug 14
568
585
  yyerror "dynamic constant assignment"
569
586
  end
570
587
 
571
- expr, _, id = val
588
+ expr, _, (id, _line) = val
572
589
  l = expr.line
573
590
 
574
591
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -576,58 +593,65 @@ rule
576
593
  | tCOLON3 tCONSTANT
577
594
  {
578
595
  if (self.in_def || self.in_single > 0) then
579
- debug20 8
596
+ debug 15
580
597
  yyerror "dynamic constant assignment"
581
598
  end
582
599
 
583
- _, id = val
584
- l = lexer.lineno
600
+ _, (id, l) = val
585
601
 
586
602
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
587
603
  }
588
604
  | backref
589
605
  {
590
- self.backref_assign_error val[0]
606
+ ref, = val
607
+
608
+ self.backref_assign_error ref
591
609
  }
592
610
 
593
611
  lhs: user_variable
594
612
  {
595
- line = lexer.lineno
596
- result = self.assignable val[0]
597
- result.line = line
613
+ var, = val
614
+
615
+ result = self.assignable var
598
616
  }
599
617
  | keyword_variable
600
618
  {
601
- line = lexer.lineno
602
- result = self.assignable val[0]
603
- result.line = line
604
- debug20 9, val, result
619
+ var, = val
620
+
621
+ result = self.assignable var
622
+
623
+ debug 16
605
624
  }
606
625
  | primary_value tLBRACK2 opt_call_args rbracket
607
626
  {
608
627
  lhs, _, args, _ = val
628
+
609
629
  result = self.aryset lhs, args
610
630
  }
611
631
  | primary_value call_op tIDENTIFIER # REFACTOR
612
632
  {
613
- lhs, op, id = val
633
+ lhs, op, (id, _line) = val
634
+
614
635
  result = new_attrasgn lhs, id, op
615
636
  }
616
637
  | primary_value tCOLON2 tIDENTIFIER
617
638
  {
618
- lhs, _, id = val
639
+ lhs, _, (id, _line) = val
640
+
619
641
  result = new_attrasgn lhs, id
620
642
  }
621
643
  | primary_value call_op tCONSTANT # REFACTOR?
622
644
  {
623
- result = new_attrasgn val[0], val[2], val[1]
645
+ lhs, call_op, (id, _line) = val
646
+
647
+ result = new_attrasgn lhs, id, call_op
624
648
  }
625
649
  | primary_value tCOLON2 tCONSTANT
626
650
  {
627
- expr, _, id = val
651
+ expr, _, (id, _line) = val
628
652
 
629
653
  if (self.in_def || self.in_single > 0) then
630
- debug20 10
654
+ debug 17
631
655
  yyerror "dynamic constant assignment"
632
656
  end
633
657
 
@@ -636,14 +660,13 @@ rule
636
660
  }
637
661
  | tCOLON3 tCONSTANT
638
662
  {
639
- _, id = val
663
+ _, (id, l) = val
640
664
 
641
665
  if (self.in_def || self.in_single > 0) then
642
- debug20 11
666
+ debug 18
643
667
  yyerror "dynamic constant assignment"
644
668
  end
645
669
 
646
- l = lexer.lineno
647
670
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
648
671
  }
649
672
  | backref
@@ -659,16 +682,16 @@ rule
659
682
 
660
683
  cpath: tCOLON3 cname
661
684
  {
662
- _, name = val
663
- result = s(:colon3, name.to_sym).line lexer.lineno
685
+ result = wrap :colon3, val[1]
664
686
  }
665
687
  | cname
666
688
  {
667
- result = val[0].to_sym
689
+ (id, line), = val
690
+ result = [id.to_sym, line] # TODO: sexp?
668
691
  }
669
692
  | primary_value tCOLON2 cname
670
693
  {
671
- pval, _, name = val
694
+ pval, _, (name, _line) = val
672
695
 
673
696
  result = s(:colon2, pval, name.to_sym)
674
697
  result.line pval.line
@@ -678,24 +701,15 @@ rule
678
701
  | op
679
702
  {
680
703
  lexer.lex_state = EXPR_END
681
- result = val[0]
682
704
  }
683
705
 
684
706
  | reswords
685
- {
686
- (sym, _line), = val
687
- lexer.lex_state = EXPR_END
688
- result = sym
689
- }
690
-
691
- fsym: fname | symbol
692
707
 
693
- fitem: fsym
708
+ fitem: fname
694
709
  {
695
- id, = val
696
- result = s(:lit, id.to_sym).line lexer.lineno
710
+ result = wrap :lit, val[0]
697
711
  }
698
- | dsym
712
+ | symbol
699
713
 
700
714
  undef_list: fitem
701
715
  {
@@ -716,8 +730,6 @@ rule
716
730
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
717
731
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
718
732
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
719
- # TODO: tUBANG dead?
720
- | tUBANG
721
733
 
722
734
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
723
735
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -751,26 +763,22 @@ rule
751
763
  }
752
764
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
753
765
  {
754
- lhs, _, id, op, rhs = val
766
+ lhs, _, (id, _line), (op, _), rhs = val
755
767
 
756
768
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
757
769
  }
758
770
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
759
771
  {
760
- lhs1, _, lhs2, op, rhs = val
772
+ lhs1, _, (lhs2, _line), op, rhs = val
761
773
 
762
774
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
763
775
  result = new_const_op_asgn [lhs, op, rhs]
764
776
  }
765
- | tCOLON3 tCONSTANT
777
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
766
778
  {
767
- result = self.lexer.lineno
768
- }
769
- tOP_ASGN arg_rhs
770
- {
771
- _, lhs, line, op, rhs = val
779
+ _, lhs, op, rhs = val
772
780
 
773
- lhs = s(:colon3, lhs.to_sym).line line
781
+ lhs = wrap :colon3, lhs
774
782
  result = new_const_op_asgn [lhs, op, rhs]
775
783
  }
776
784
  | backref tOP_ASGN arg_rhs
@@ -782,7 +790,7 @@ rule
782
790
  | arg tDOT2 arg
783
791
  {
784
792
  v1, v2 = val[0], val[2]
785
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
793
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
786
794
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
787
795
  else
788
796
  result = s(:dot2, v1, v2).line v1.line
@@ -791,12 +799,14 @@ rule
791
799
  | arg tDOT3 arg
792
800
  {
793
801
  v1, v2 = val[0], val[2]
794
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
802
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
795
803
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
796
804
  else
797
805
  result = s(:dot3, v1, v2).line v1.line
798
806
  end
799
807
  }
808
+
809
+
800
810
  | arg tPLUS arg
801
811
  {
802
812
  result = new_call val[0], :+, argl(val[2])
@@ -823,16 +833,18 @@ rule
823
833
  }
824
834
  | tUMINUS_NUM tINTEGER tPOW arg
825
835
  {
826
- lit = s(:lit, val[1]).line lexer.lineno
827
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
836
+ _, (num, line), _, arg = val
837
+ lit = s(:lit, num).line line
838
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
828
839
  }
829
840
  | tUMINUS_NUM tFLOAT tPOW arg
830
841
  {
831
- lit = s(:lit, val[1]).line lexer.lineno
832
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
842
+ _, (num, line), _, arg = val
843
+ lit = s(:lit, num).line line
844
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
833
845
 
834
846
  ## TODO: why is this 2.0 only?
835
- debug20 12, val, result
847
+ debug 19
836
848
  }
837
849
  | tUPLUS arg
838
850
  {
@@ -930,12 +942,12 @@ rule
930
942
 
931
943
  rel_expr: arg relop arg =tGT
932
944
  {
933
- lhs, op, rhs = val
945
+ lhs, (op, _), rhs = val
934
946
  result = new_call lhs, op.to_sym, argl(rhs)
935
947
  }
936
948
  | rel_expr relop arg =tGT
937
949
  {
938
- lhs, op, rhs = val
950
+ lhs, (op, _), rhs = val
939
951
  warn "comparison '%s' after comparison", op
940
952
  result = new_call lhs, op.to_sym, argl(rhs)
941
953
  }
@@ -1117,8 +1129,9 @@ rule
1117
1129
  | backref
1118
1130
  | tFID
1119
1131
  {
1120
- msg, = val
1132
+ (msg, line), = val
1121
1133
  result = new_call nil, msg.to_sym
1134
+ result.line line
1122
1135
  }
1123
1136
  | k_begin
1124
1137
  {
@@ -1160,15 +1173,13 @@ rule
1160
1173
  }
1161
1174
  | primary_value tCOLON2 tCONSTANT
1162
1175
  {
1163
- expr, _, id = val
1176
+ expr, _, (id, _line) = val
1164
1177
 
1165
1178
  result = s(:colon2, expr, id.to_sym).line expr.line
1166
1179
  }
1167
1180
  | tCOLON3 tCONSTANT
1168
1181
  {
1169
- _, id = val
1170
-
1171
- result = s(:colon3, id.to_sym).line lexer.lineno
1182
+ result = wrap :colon3, val[1]
1172
1183
  }
1173
1184
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1174
1185
  {
@@ -1192,15 +1203,21 @@ rule
1192
1203
  }
1193
1204
  | kYIELD tLPAREN2 call_args rparen
1194
1205
  {
1195
- result = new_yield val[2]
1206
+ (_, line), _, args, _ = val
1207
+
1208
+ result = new_yield(args).line line
1196
1209
  }
1197
1210
  | kYIELD tLPAREN2 rparen
1198
1211
  {
1199
- result = new_yield
1212
+ (_, line), _, _ = val
1213
+
1214
+ result = new_yield.line line
1200
1215
  }
1201
1216
  | kYIELD
1202
1217
  {
1203
- result = new_yield
1218
+ (_, line), = val
1219
+
1220
+ result = new_yield.line line
1204
1221
  }
1205
1222
  | kDEFINED opt_nl tLPAREN2 expr rparen
1206
1223
  {
@@ -1215,7 +1232,7 @@ rule
1215
1232
  }
1216
1233
  | kNOT tLPAREN2 rparen
1217
1234
  {
1218
- debug20 14, val, result
1235
+ debug 20
1219
1236
  }
1220
1237
  | fcall brace_block
1221
1238
  {
@@ -1233,9 +1250,10 @@ rule
1233
1250
  iter.insert 1, call # FIX
1234
1251
  result = iter
1235
1252
  }
1236
- | tLAMBDA lambda
1253
+ | lambda
1237
1254
  {
1238
- result = val[1] # TODO: fix lineno
1255
+ expr, = val
1256
+ result = expr
1239
1257
  }
1240
1258
  | k_if expr_value then compstmt if_tail k_end
1241
1259
  {
@@ -1278,7 +1296,6 @@ rule
1278
1296
  }
1279
1297
  cpath superclass
1280
1298
  {
1281
- self.comments.push self.lexer.comments
1282
1299
  if (self.in_def || self.in_single > 0) then
1283
1300
  yyerror "class definition in method body"
1284
1301
  end
@@ -1288,7 +1305,7 @@ rule
1288
1305
  {
1289
1306
  result = new_class val
1290
1307
  self.env.unextend
1291
- self.lexer.comments # we don't care about comments in the body
1308
+ self.lexer.ignore_body_comments
1292
1309
  }
1293
1310
  | k_class tLSHFT
1294
1311
  {
@@ -1309,7 +1326,7 @@ rule
1309
1326
  {
1310
1327
  result = new_sclass val
1311
1328
  self.env.unextend
1312
- self.lexer.comments # we don't care about comments in the body
1329
+ self.lexer.ignore_body_comments
1313
1330
  }
1314
1331
  | k_module
1315
1332
  {
@@ -1317,7 +1334,6 @@ rule
1317
1334
  }
1318
1335
  cpath
1319
1336
  {
1320
- self.comments.push self.lexer.comments
1321
1337
  yyerror "module definition in method body" if
1322
1338
  self.in_def or self.in_single > 0
1323
1339
 
@@ -1327,7 +1343,7 @@ rule
1327
1343
  {
1328
1344
  result = new_module val
1329
1345
  self.env.unextend
1330
- self.lexer.comments # we don't care about comments in the body
1346
+ self.lexer.ignore_body_comments
1331
1347
  }
1332
1348
  | k_def fname
1333
1349
  {
@@ -1337,21 +1353,17 @@ rule
1337
1353
  self.env.extend
1338
1354
  lexer.cmdarg.push false
1339
1355
  lexer.cond.push false
1340
-
1341
- self.comments.push self.lexer.comments
1342
1356
  }
1343
- f_arglist bodystmt { result = lexer.lineno } k_end
1357
+ f_arglist bodystmt k_end
1344
1358
  {
1345
- in_def = val[2]
1346
-
1347
- result = new_defn val
1359
+ result, in_def = new_defn val
1348
1360
 
1349
1361
  lexer.cond.pop # group = local_pop
1350
1362
  lexer.cmdarg.pop
1351
1363
  self.env.unextend
1352
1364
  self.in_def = in_def
1353
1365
 
1354
- self.lexer.comments # we don't care about comments in the body
1366
+ self.lexer.ignore_body_comments
1355
1367
  }
1356
1368
  | k_def singleton dot_or_colon
1357
1369
  {
@@ -1359,7 +1371,7 @@ rule
1359
1371
  }
1360
1372
  fname
1361
1373
  {
1362
- result = [self.in_def, lexer.lineno]
1374
+ result = self.in_def
1363
1375
 
1364
1376
  self.in_single += 1 # TODO: remove?
1365
1377
 
@@ -1369,13 +1381,18 @@ rule
1369
1381
  lexer.cond.push false
1370
1382
 
1371
1383
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1372
- self.comments.push self.lexer.comments
1373
1384
  }
1374
1385
  f_arglist bodystmt k_end
1375
1386
  {
1376
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1377
1387
 
1378
- 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
1379
1396
 
1380
1397
  lexer.cond.pop # group = local_pop
1381
1398
  lexer.cmdarg.pop
@@ -1386,7 +1403,7 @@ rule
1386
1403
 
1387
1404
  # TODO: restore cur_arg ? what's cur_arg?
1388
1405
 
1389
- self.lexer.comments # we don't care about comments in the body
1406
+ self.lexer.ignore_body_comments
1390
1407
  }
1391
1408
  | kBREAK
1392
1409
  {
@@ -1423,8 +1440,17 @@ rule
1423
1440
  k_case: kCASE
1424
1441
  k_for: kFOR
1425
1442
  k_class: kCLASS
1443
+ {
1444
+ self.comments.push self.lexer.comments
1445
+ }
1426
1446
  k_module: kMODULE
1447
+ {
1448
+ self.comments.push self.lexer.comments
1449
+ }
1427
1450
  k_def: kDEF
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1428
1454
  k_do: kDO
1429
1455
  k_do_block: kDO_BLOCK
1430
1456
  k_rescue: kRESCUE
@@ -1485,51 +1511,42 @@ rule
1485
1511
 
1486
1512
  result = block_var args
1487
1513
  }
1488
- | f_marg_list tCOMMA tSTAR f_norm_arg
1514
+ | f_marg_list tCOMMA f_rest_marg
1489
1515
  {
1490
- args, _, _, splat = val
1516
+ args, _, rest = val
1491
1517
 
1492
- result = block_var args, "*#{splat}".to_sym
1518
+ result = block_var args, rest
1493
1519
  }
1494
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1520
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1495
1521
  {
1496
- args, _, _, splat, _, args2 = val
1522
+ lhs, _, splat, _, rhs = val
1497
1523
 
1498
- result = block_var args, "*#{splat}".to_sym, args2
1524
+ result = block_var lhs, splat, rhs
1499
1525
  }
1500
- | f_marg_list tCOMMA tSTAR
1526
+ | f_rest_marg
1501
1527
  {
1502
- args, _, _ = val
1528
+ rest, = val
1503
1529
 
1504
- result = block_var args, :*
1530
+ result = block_var rest
1505
1531
  }
1506
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1532
+ | f_rest_marg tCOMMA f_marg_list
1507
1533
  {
1508
- args, _, _, _, args2 = val
1534
+ splat, _, rest = val
1509
1535
 
1510
- result = block_var args, :*, args2
1536
+ result = block_var splat, rest
1511
1537
  }
1512
- | tSTAR f_norm_arg
1513
- {
1514
- _, splat = val
1515
1538
 
1516
- result = block_var :"*#{splat}"
1517
- }
1518
- | tSTAR f_norm_arg tCOMMA f_marg_list
1539
+ f_rest_marg: tSTAR f_norm_arg
1519
1540
  {
1520
- _, splat, _, args = val
1541
+ _, (id, line) = val
1521
1542
 
1522
- result = block_var :"*#{splat}", args
1543
+ result = args ["*#{id}".to_sym]
1544
+ result.line line
1523
1545
  }
1524
1546
  | tSTAR
1525
1547
  {
1526
- result = block_var :*
1527
- }
1528
- | tSTAR tCOMMA f_marg_list
1529
- {
1530
- _, _, args = val
1531
-
1532
- result = block_var :*, args
1548
+ result = args [:*]
1549
+ result.line lexer.lineno # FIX: tSTAR -> line
1533
1550
  }
1534
1551
 
1535
1552
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1546,8 +1563,8 @@ rule
1546
1563
  }
1547
1564
  | f_block_arg
1548
1565
  {
1549
- line = lexer.lineno
1550
- result = call_args val # TODO: push line down
1566
+ (id, line), = val
1567
+ result = call_args [id]
1551
1568
  result.line line
1552
1569
  }
1553
1570
 
@@ -1656,13 +1673,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1656
1673
 
1657
1674
  bvar: tIDENTIFIER
1658
1675
  {
1659
- id, = val
1660
- line = lexer.lineno
1661
- result = s(:shadow, id.to_sym).line line
1676
+ result = wrap :shadow, val[0]
1662
1677
  }
1663
1678
  | f_bad_arg
1664
1679
 
1665
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1666
1682
  self.env.extend :dynamic
1667
1683
  result = [lexer.lineno, lexer.lpar_beg]
1668
1684
  lexer.paren_nest += 1
@@ -1674,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1674
1690
  }
1675
1691
  lambda_body
1676
1692
  {
1677
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1678
1694
  lexer.lpar_beg = lpar
1679
1695
 
1680
1696
  lexer.cmdarg.pop
1681
1697
 
1682
1698
  call = s(:lambda).line line
1683
1699
  result = new_iter call, args, body
1684
- result.line = line
1700
+ result.line line
1685
1701
  self.env.unextend # TODO: dynapush & dynapop
1686
1702
  }
1687
1703
 
@@ -1716,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1716
1732
  ## if (nd_type($1) == NODE_YIELD) {
1717
1733
  ## compile_error(PARSER_ARG "block given to yield");
1718
1734
 
1719
- syntax_error "Both block arg and actual block given." if
1720
- val[0].block_pass?
1735
+ cmd, blk = val
1721
1736
 
1722
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1723
1739
 
1724
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1725
1744
 
1726
1745
  result = blk
1727
1746
  result.insert 1, cmd
1728
1747
  }
1729
1748
  | block_call call_op2 operation2 opt_paren_args
1730
1749
  {
1731
- 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
1732
1753
  }
1733
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1734
1755
  {
1735
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1736
1757
 
1737
1758
  call = new_call iter1, name.to_sym, args
1738
1759
  iter2.insert 1, call
@@ -1741,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1741
1762
  }
1742
1763
  | block_call call_op2 operation2 command_args do_block
1743
1764
  {
1744
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1745
1766
 
1746
1767
  call = new_call iter1, name.to_sym, args
1747
1768
  iter2.insert 1, call
@@ -1749,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1749
1770
  result = iter2
1750
1771
  }
1751
1772
 
1752
- method_call: fcall
1773
+ method_call: fcall paren_args
1753
1774
  {
1754
- result = self.lexer.lineno
1755
- }
1756
- paren_args
1757
- {
1758
- call, lineno, args = val
1775
+ call, args = val
1759
1776
 
1760
1777
  result = call.concat args.sexp_body if args
1761
- result.line lineno
1762
1778
  }
1763
1779
  | primary_value call_op operation2 opt_paren_args
1764
1780
  {
1765
- 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
1766
1784
  }
1767
1785
  | primary_value tCOLON2 operation2 paren_args
1768
1786
  {
1769
- 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
1770
1790
  }
1771
1791
  | primary_value tCOLON2 operation3
1772
1792
  {
1773
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1774
1796
  }
1775
1797
  | primary_value call_op paren_args
1776
1798
  {
@@ -1803,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1803
1825
  _, line, body, _ = val
1804
1826
 
1805
1827
  result = body
1806
- result.line = line
1828
+ result.line line
1807
1829
 
1808
1830
  self.env.unextend
1809
1831
  }
@@ -1817,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1817
1839
  _, line, body, _ = val
1818
1840
 
1819
1841
  result = body
1820
- result.line = line
1842
+ result.line line
1821
1843
 
1822
1844
  self.env.unextend
1823
1845
  }
@@ -1846,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1846
1868
  self.env.unextend
1847
1869
  }
1848
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
+
1849
1896
  case_body: k_when
1850
1897
  {
1851
1898
  result = self.lexer.lineno
1852
1899
  }
1853
- args then compstmt cases
1900
+ case_args then compstmt cases
1854
1901
  {
1855
1902
  result = new_when(val[2], val[4])
1856
- result.line = val[1]
1903
+ result.line val[1]
1857
1904
  result << val[5] if val[5]
1858
1905
  }
1859
1906
 
@@ -1899,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1899
1946
 
1900
1947
  literal: numeric
1901
1948
  {
1902
- line = lexer.lineno
1903
- result = s(:lit, val[0])
1904
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1905
1951
  }
1906
1952
  | symbol
1907
- {
1908
- line = lexer.lineno
1909
- result = s(:lit, val[0])
1910
- result.line = line
1911
- }
1912
- | dsym
1913
1953
 
1914
1954
  strings: string
1915
1955
  {
@@ -1920,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1920
1960
 
1921
1961
  string: tCHAR
1922
1962
  {
1923
- debug20 23, val, result
1963
+ debug 37
1924
1964
  }
1925
1965
  | string1
1926
1966
  | string string1
@@ -1930,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1930
1970
 
1931
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1932
1972
  {
1933
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1934
1974
 
1935
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1936
1976
 
1937
- result = str
1977
+ result = str.line line
1938
1978
  }
1939
1979
  | tSTRING
1940
1980
  {
@@ -1954,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1954
1994
 
1955
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1956
1996
  {
1957
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1958
2000
  }
1959
2001
  | tWORDS_BEG word_list tSTRING_END
1960
2002
  {
1961
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1962
2006
  }
1963
2007
 
1964
2008
  word_list: none
@@ -1978,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1978
2022
 
1979
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1980
2024
  {
1981
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1982
2028
  }
1983
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1984
2030
  {
1985
- _, line, list, _, = val
1986
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1987
2033
  result = list
1988
2034
  }
1989
2035
 
1990
2036
  symbol_list: none
1991
2037
  {
1992
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1993
2039
  }
1994
2040
  | symbol_list word tSPACE
1995
2041
  {
@@ -1999,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1999
2045
 
2000
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2001
2047
  {
2002
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2003
2051
  }
2004
2052
  | tQWORDS_BEG qword_list tSTRING_END
2005
2053
  {
2006
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2007
2057
  }
2008
2058
 
2009
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2010
2060
  {
2011
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2012
2064
  }
2013
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2014
2066
  {
2015
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2016
2070
  }
2017
2071
 
2018
2072
  qword_list: none
@@ -2035,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2035
2089
 
2036
2090
  string_contents: none
2037
2091
  {
2038
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2039
2094
  }
2040
2095
  | string_contents string_content
2041
2096
  {
@@ -2110,8 +2165,8 @@ regexp_contents: none
2110
2165
  lexer.brace_nest = brace_nest
2111
2166
  lexer.string_nest = string_nest
2112
2167
 
2113
- lexer.cmdarg.pop
2114
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2115
2170
 
2116
2171
  lexer.lex_state = oldlex_state
2117
2172
 
@@ -2126,29 +2181,42 @@ regexp_contents: none
2126
2181
  when nil then
2127
2182
  result = s(:evstr).line line
2128
2183
  else
2129
- debug20 25
2184
+ debug 38
2130
2185
  raise "unknown string body: #{stmt.inspect}"
2131
2186
  end
2132
2187
  }
2133
2188
 
2134
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2135
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2136
- | 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
+ }
2137
2201
  | backref
2138
2202
 
2139
- symbol: tSYMBEG sym
2203
+ symbol: ssym
2204
+ | dsym
2205
+
2206
+ ssym: tSYMBEG sym
2140
2207
  {
2141
2208
  lexer.lex_state = EXPR_END
2142
- result = val[1].to_sym
2209
+ result = wrap :lit, val[1]
2143
2210
  }
2144
2211
  | tSYMBOL
2145
2212
  {
2146
- result = val[0].to_sym
2213
+ lexer.lex_state = EXPR_END
2214
+ result = wrap :lit, val[0]
2147
2215
  }
2148
2216
 
2149
2217
  sym: fname | tIVAR | tGVAR | tCVAR
2150
2218
 
2151
- dsym: tSYMBEG xstring_contents tSTRING_END
2219
+ dsym: tSYMBEG string_contents tSTRING_END
2152
2220
  {
2153
2221
  _, result, _ = val
2154
2222
 
@@ -2164,7 +2232,7 @@ regexp_contents: none
2164
2232
  when :evstr then
2165
2233
  result = s(:dsym, "", result).line result.line
2166
2234
  else
2167
- debug20 26, val, result
2235
+ debug 39
2168
2236
  end
2169
2237
  }
2170
2238
 
@@ -2172,11 +2240,13 @@ regexp_contents: none
2172
2240
  | tFLOAT
2173
2241
  | tUMINUS_NUM tINTEGER =tLOWEST
2174
2242
  {
2175
- result = -val[1] # TODO: pt_testcase
2243
+ _, (num, line) = val
2244
+ result = [-num, line]
2176
2245
  }
2177
2246
  | tUMINUS_NUM tFLOAT =tLOWEST
2178
2247
  {
2179
- result = -val[1] # TODO: pt_testcase
2248
+ _, (num, line) = val
2249
+ result = [-num, line]
2180
2250
  }
2181
2251
 
2182
2252
  user_variable: tIDENTIFIER
@@ -2204,8 +2274,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2204
2274
 
2205
2275
  var_ref: user_variable
2206
2276
  {
2207
- var = val[0]
2277
+ raise "NO: #{val.inspect}" if Sexp === val.first
2278
+ (var, line), = val
2208
2279
  result = Sexp === var ? var : self.gettable(var)
2280
+ result.line line
2209
2281
  }
2210
2282
  | keyword_variable
2211
2283
  {
@@ -2220,11 +2292,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2220
2292
  | keyword_variable
2221
2293
  {
2222
2294
  result = self.assignable val[0]
2223
- debug20 29, val, result
2295
+ debug 40
2224
2296
  }
2225
2297
 
2226
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2227
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2298
+ backref: tNTH_REF
2299
+ {
2300
+ (ref, line), = val
2301
+ result = s(:nth_ref, ref).line line
2302
+ }
2303
+ | tBACK_REF
2304
+ {
2305
+ (ref, line), = val
2306
+ result = s(:back_ref, ref).line line
2307
+ }
2228
2308
 
2229
2309
  superclass: tLT
2230
2310
  {
@@ -2242,9 +2322,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2242
2322
 
2243
2323
  f_arglist: tLPAREN2 f_args rparen
2244
2324
  {
2245
- result = val[1]
2246
- self.lexer.lex_state = EXPR_BEG
2247
- self.lexer.command_start = true
2325
+ result = end_args val
2248
2326
  }
2249
2327
  | {
2250
2328
  result = self.in_kwarg
@@ -2253,12 +2331,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2253
2331
  }
2254
2332
  f_args term
2255
2333
  {
2256
- kwarg, args, _ = val
2257
-
2258
- self.in_kwarg = kwarg
2259
- result = args
2260
- lexer.lex_state = EXPR_BEG
2261
- lexer.command_start = true
2334
+ result = end_args val
2262
2335
  }
2263
2336
 
2264
2337
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2343,8 +2416,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2343
2416
  |
2344
2417
  {
2345
2418
  result = args val
2419
+ # result.line lexer.lineno
2346
2420
  }
2347
2421
 
2422
+
2348
2423
  f_bad_arg: tCONSTANT
2349
2424
  {
2350
2425
  yyerror "formal argument cannot be a constant"
@@ -2365,31 +2440,24 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2365
2440
  f_norm_arg: f_bad_arg
2366
2441
  | tIDENTIFIER
2367
2442
  {
2368
- identifier = val[0].to_sym
2443
+ (id, line), = val
2444
+ identifier = id.to_sym
2369
2445
  self.env[identifier] = :lvar
2370
2446
 
2371
- result = identifier
2447
+ result = [identifier, line]
2372
2448
  }
2373
2449
 
2374
2450
  f_arg_item: f_norm_arg
2375
2451
  | tLPAREN f_margs rparen
2376
2452
  {
2377
- result = val[1]
2453
+ _, margs, _ = val
2454
+
2455
+ result = margs
2378
2456
  }
2379
2457
 
2380
2458
  f_arg: f_arg_item
2381
2459
  {
2382
- arg, = val
2383
-
2384
- case arg
2385
- when Symbol then
2386
- result = s(:args, arg).line lexer.lineno
2387
- when Sexp then
2388
- result = arg
2389
- else
2390
- debug20 32
2391
- raise "Unknown f_arg type: #{val.inspect}"
2392
- end
2460
+ result = new_arg val
2393
2461
  }
2394
2462
  | f_arg tCOMMA f_arg_item
2395
2463
  {
@@ -2401,7 +2469,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2401
2469
  result = s(:args, list).line list.line
2402
2470
  end
2403
2471
 
2404
- result << item
2472
+ result << (Sexp === item ? item : item.first)
2405
2473
  }
2406
2474
 
2407
2475
  f_kw: tLABEL arg_value
@@ -2442,26 +2510,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2442
2510
  kwrest_mark: tPOW
2443
2511
  | tDSTAR
2444
2512
 
2513
+
2445
2514
  f_kwrest: kwrest_mark tIDENTIFIER
2446
2515
  {
2447
- name = val[1].to_sym
2448
- self.assignable name
2449
- result = :"**#{name}"
2516
+ _, (id, line) = val
2517
+
2518
+ name = id.to_sym
2519
+ self.assignable [name, line]
2520
+ result = [:"**#{name}", line]
2450
2521
  }
2451
2522
  | kwrest_mark
2452
2523
  {
2453
- result = :"**"
2524
+ id = :"**"
2525
+ self.env[id] = :lvar # TODO: needed?!?
2526
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2454
2527
  }
2455
2528
 
2456
2529
  f_opt: tIDENTIFIER tEQL arg_value
2457
2530
  {
2458
- result = self.assignable val[0], val[2]
2531
+ lhs, _, rhs = val
2532
+ result = self.assignable lhs, rhs
2459
2533
  # TODO: detect duplicate names
2460
2534
  }
2461
2535
 
2462
2536
  f_block_opt: tIDENTIFIER tEQL primary_value
2463
2537
  {
2464
- result = self.assignable val[0], val[2]
2538
+ lhs, _, rhs = val
2539
+ result = self.assignable lhs, rhs
2465
2540
  }
2466
2541
 
2467
2542
  f_block_optarg: f_block_opt
@@ -2491,30 +2566,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2491
2566
  f_rest_arg: restarg_mark tIDENTIFIER
2492
2567
  {
2493
2568
  # TODO: differs from parse.y - needs tests
2494
- name = val[1].to_sym
2495
- self.assignable name
2496
- result = :"*#{name}"
2569
+ _, (id, line) = val
2570
+ name = id.to_sym
2571
+ self.assignable [name, line]
2572
+ result = [:"*#{name}", line]
2497
2573
  }
2498
2574
  | restarg_mark
2499
2575
  {
2500
2576
  name = :"*"
2501
2577
  self.env[name] = :lvar
2502
- result = name
2578
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2503
2579
  }
2504
2580
 
2505
2581
  blkarg_mark: tAMPER2 | tAMPER
2506
2582
 
2507
2583
  f_block_arg: blkarg_mark tIDENTIFIER
2508
2584
  {
2509
- identifier = val[1].to_sym
2585
+ _, (id, line) = val
2586
+ identifier = id.to_sym
2510
2587
 
2511
2588
  self.env[identifier] = :lvar
2512
- result = "&#{identifier}".to_sym
2589
+ result = ["&#{identifier}".to_sym, line]
2513
2590
  }
2514
2591
 
2515
2592
  opt_f_block_arg: tCOMMA f_block_arg
2516
2593
  {
2517
- result = val[1]
2594
+ _, arg = val
2595
+ result = arg
2518
2596
  }
2519
2597
  |
2520
2598
  {
@@ -2556,10 +2634,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2556
2634
  }
2557
2635
  | tLABEL arg_value
2558
2636
  {
2559
- (label, line), arg = val
2637
+ label, arg = val
2560
2638
 
2561
- lit = s(:lit, label.to_sym).line line
2562
- result = s(:array, lit, arg).line line
2639
+ lit = wrap :lit, label
2640
+ result = s(:array, lit, arg).line lit.line
2563
2641
  }
2564
2642
  | tDSTAR arg_value
2565
2643
  {