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