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/ruby27_parser.y CHANGED
@@ -18,10 +18,11 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
25
+ tBDOT2 tBDOT3
25
26
 
26
27
  preclow
27
28
  nonassoc tLOWEST
@@ -33,7 +34,7 @@ preclow
33
34
  right tEQL tOP_ASGN
34
35
  left kRESCUE_MOD
35
36
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
38
  left tOROP
38
39
  left tANDOP
39
40
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +57,9 @@ rule
56
57
  top_compstmt
57
58
  {
58
59
  result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
59
63
  }
60
64
 
61
65
  top_compstmt: top_stmts opt_terms
@@ -76,7 +80,7 @@ rule
76
80
  | klBEGIN
77
81
  {
78
82
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
83
+ debug 11
80
84
  yyerror "BEGIN in method"
81
85
  end
82
86
  self.env.extend
@@ -101,6 +105,8 @@ rule
101
105
  bodystmt: compstmt opt_rescue k_else
102
106
  {
103
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
104
110
  yyerror "else without rescue is useless" unless res
105
111
  }
106
112
  compstmt
@@ -131,7 +137,7 @@ rule
131
137
  | error stmt
132
138
  {
133
139
  result = val[1]
134
- debug20 2, val, result
140
+ debug 12
135
141
  }
136
142
 
137
143
  stmt_or_begin: stmt
@@ -139,6 +145,10 @@ rule
139
145
  {
140
146
  yyerror "BEGIN is permitted only at toplevel"
141
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
142
152
 
143
153
  stmt: kALIAS fitem
144
154
  {
@@ -151,12 +161,12 @@ rule
151
161
  }
152
162
  | kALIAS tGVAR tGVAR
153
163
  {
154
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
155
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
166
  }
157
167
  | kALIAS tGVAR tBACK_REF
158
168
  {
159
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
160
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
171
  }
162
172
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +209,7 @@ rule
199
209
  (_, line), _, stmt, _ = val
200
210
 
201
211
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
212
+ debug 13
203
213
  yyerror "END in method; use at_exit"
204
214
  end
205
215
 
@@ -215,6 +225,15 @@ rule
215
225
  lhs, _, rhs = val
216
226
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
217
227
  }
228
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
229
+ {
230
+ # unwraps s(:to_ary, rhs)
231
+ lhs, _, (_, rhs), _, resbody = val
232
+
233
+ resbody = new_resbody s(:array).line(resbody.line), resbody
234
+
235
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
236
+ }
218
237
  | mlhs tEQL mrhs_arg
219
238
  {
220
239
  result = new_masgn val[0], val[2]
@@ -239,32 +258,31 @@ rule
239
258
  }
240
259
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
260
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
261
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
262
+
263
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
264
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
265
+ result.line prim.line
248
266
  }
249
267
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
268
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
269
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
270
+
271
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
272
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
273
+ result.line prim.line
256
274
  }
257
275
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
276
  {
259
- lhs1, _, lhs2, op, rhs = val
277
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
278
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
279
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
280
  }
263
281
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
282
  {
265
- lhs1, _, lhs2, op, rhs = val
283
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
284
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
285
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
286
  }
269
287
  | backref tOP_ASGN command_rhs
270
288
  {
@@ -311,6 +329,28 @@ rule
311
329
  # REFACTOR: call_uni_op -- see parse26.y
312
330
  }
313
331
  | arg
332
+ kIN
333
+ {
334
+ # TODO? value_expr($1);
335
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
336
+ self.lexer.command_start = false
337
+ result = self.in_kwarg
338
+ self.in_kwarg = true
339
+ self.env.extend
340
+ }
341
+ p_expr
342
+ {
343
+ self.env.unextend
344
+
345
+ expr, _, old_kwarg, pat = val
346
+
347
+ expr = value_expr expr
348
+
349
+ self.in_kwarg = old_kwarg
350
+ pat_in = new_in pat, nil, nil, expr.line
351
+ result = new_case expr, pat_in, expr.line
352
+ }
353
+ | arg =tLBRACE_ARG
314
354
 
315
355
  expr_value: expr
316
356
  {
@@ -335,7 +375,7 @@ rule
335
375
  block_command: block_call
336
376
  | block_call call_op2 operation2 command_args
337
377
  {
338
- blk, _, msg, args = val
378
+ blk, _, (msg, _line), args = val
339
379
  result = new_call(blk, msg.to_sym, args).line blk.line
340
380
  }
341
381
 
@@ -349,15 +389,15 @@ rule
349
389
  _, line, body, _ = val
350
390
 
351
391
  result = body
352
- result.line = line
392
+ result.line line
353
393
 
354
394
  # self.env.unextend
355
395
  }
356
396
 
357
397
  fcall: operation
358
398
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
399
+ (msg, line), = val
400
+ result = new_call(nil, msg.to_sym).line line
361
401
  }
362
402
 
363
403
  command: fcall command_args =tLOWEST
@@ -380,12 +420,14 @@ rule
380
420
  }
381
421
  | primary_value call_op operation2 command_args =tLOWEST
382
422
  {
383
- lhs, callop, op, args = val
423
+ lhs, callop, (op, _), args = val
424
+
384
425
  result = new_call lhs, op.to_sym, args, callop
426
+ result.line lhs.line
385
427
  }
386
428
  | primary_value call_op operation2 command_args cmd_brace_block
387
429
  {
388
- recv, _, msg, args, block = val
430
+ recv, _, (msg, _line), args, block = val
389
431
  call = new_call recv, msg.to_sym, args, val[1]
390
432
 
391
433
  block_dup_check call, block
@@ -395,11 +437,14 @@ rule
395
437
  }
396
438
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
439
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
440
+ lhs, _, (id, line), args = val
441
+
442
+ result = new_call lhs, id.to_sym, args
443
+ result.line line
399
444
  }
400
445
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
446
  {
402
- recv, _, msg, args, block = val
447
+ recv, _, (msg, _line), args, block = val
403
448
  call = new_call recv, msg.to_sym, args
404
449
 
405
450
  block_dup_check call, block
@@ -557,25 +602,29 @@ rule
557
602
  }
558
603
  | primary_value call_op tIDENTIFIER
559
604
  {
560
- result = new_attrasgn val[0], val[2], val[1]
605
+ lhs, call_op, (id, _line) = val
606
+
607
+ result = new_attrasgn lhs, id, call_op
561
608
  }
562
609
  | primary_value tCOLON2 tIDENTIFIER
563
610
  {
564
- recv, _, id = val
611
+ recv, _, (id, _line) = val
565
612
  result = new_attrasgn recv, id
566
613
  }
567
614
  | primary_value call_op tCONSTANT
568
615
  {
569
- result = new_attrasgn val[0], val[2], val[1]
616
+ lhs, call_op, (id, _line) = val
617
+
618
+ result = new_attrasgn lhs, id, call_op
570
619
  }
571
620
  | primary_value tCOLON2 tCONSTANT
572
621
  {
573
622
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
623
+ debug 14
575
624
  yyerror "dynamic constant assignment"
576
625
  end
577
626
 
578
- expr, _, id = val
627
+ expr, _, (id, _line) = val
579
628
  l = expr.line
580
629
 
581
630
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +632,65 @@ rule
583
632
  | tCOLON3 tCONSTANT
584
633
  {
585
634
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
635
+ debug 15
587
636
  yyerror "dynamic constant assignment"
588
637
  end
589
638
 
590
- _, id = val
591
- l = lexer.lineno
639
+ _, (id, l) = val
592
640
 
593
641
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
642
  }
595
643
  | backref
596
644
  {
597
- self.backref_assign_error val[0]
645
+ ref, = val
646
+
647
+ self.backref_assign_error ref
598
648
  }
599
649
 
600
650
  lhs: user_variable
601
651
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
652
+ var, = val
653
+
654
+ result = self.assignable var
605
655
  }
606
656
  | keyword_variable
607
657
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
658
+ var, = val
659
+
660
+ result = self.assignable var
661
+
662
+ debug 16
612
663
  }
613
664
  | primary_value tLBRACK2 opt_call_args rbracket
614
665
  {
615
666
  lhs, _, args, _ = val
667
+
616
668
  result = self.aryset lhs, args
617
669
  }
618
670
  | primary_value call_op tIDENTIFIER # REFACTOR
619
671
  {
620
- lhs, op, id = val
672
+ lhs, op, (id, _line) = val
673
+
621
674
  result = new_attrasgn lhs, id, op
622
675
  }
623
676
  | primary_value tCOLON2 tIDENTIFIER
624
677
  {
625
- lhs, _, id = val
678
+ lhs, _, (id, _line) = val
679
+
626
680
  result = new_attrasgn lhs, id
627
681
  }
628
682
  | primary_value call_op tCONSTANT # REFACTOR?
629
683
  {
630
- result = new_attrasgn val[0], val[2], val[1]
684
+ lhs, call_op, (id, _line) = val
685
+
686
+ result = new_attrasgn lhs, id, call_op
631
687
  }
632
688
  | primary_value tCOLON2 tCONSTANT
633
689
  {
634
- expr, _, id = val
690
+ expr, _, (id, _line) = val
635
691
 
636
692
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
693
+ debug 17
638
694
  yyerror "dynamic constant assignment"
639
695
  end
640
696
 
@@ -643,14 +699,13 @@ rule
643
699
  }
644
700
  | tCOLON3 tCONSTANT
645
701
  {
646
- _, id = val
702
+ _, (id, l) = val
647
703
 
648
704
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
705
+ debug 18
650
706
  yyerror "dynamic constant assignment"
651
707
  end
652
708
 
653
- l = lexer.lineno
654
709
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
710
  }
656
711
  | backref
@@ -666,16 +721,16 @@ rule
666
721
 
667
722
  cpath: tCOLON3 cname
668
723
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
724
+ result = wrap :colon3, val[1]
671
725
  }
672
726
  | cname
673
727
  {
674
- result = val[0].to_sym
728
+ (id, line), = val
729
+ result = [id.to_sym, line] # TODO: sexp?
675
730
  }
676
731
  | primary_value tCOLON2 cname
677
732
  {
678
- pval, _, name = val
733
+ pval, _, (name, _line) = val
679
734
 
680
735
  result = s(:colon2, pval, name.to_sym)
681
736
  result.line pval.line
@@ -685,24 +740,15 @@ rule
685
740
  | op
686
741
  {
687
742
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
743
  }
690
744
 
691
745
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
-
698
- fsym: fname | symbol
699
746
 
700
- fitem: fsym
747
+ fitem: fname
701
748
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
749
+ result = wrap :lit, val[0]
704
750
  }
705
- | dsym
751
+ | symbol
706
752
 
707
753
  undef_list: fitem
708
754
  {
@@ -723,8 +769,6 @@ rule
723
769
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
770
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
771
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
772
 
729
773
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
774
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,26 +802,22 @@ rule
758
802
  }
759
803
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
804
  {
761
- lhs, _, id, op, rhs = val
805
+ lhs, _, (id, _line), (op, _), rhs = val
762
806
 
763
807
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
808
  }
765
809
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
810
  {
767
- lhs1, _, lhs2, op, rhs = val
811
+ lhs1, _, (lhs2, _line), op, rhs = val
768
812
 
769
813
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
814
  result = new_const_op_asgn [lhs, op, rhs]
771
815
  }
772
- | tCOLON3 tCONSTANT
773
- {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
816
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
777
817
  {
778
- _, lhs, line, op, rhs = val
818
+ _, lhs, op, rhs = val
779
819
 
780
- lhs = s(:colon3, lhs.to_sym).line line
820
+ lhs = wrap :colon3, lhs
781
821
  result = new_const_op_asgn [lhs, op, rhs]
782
822
  }
783
823
  | backref tOP_ASGN arg_rhs
@@ -789,7 +829,7 @@ rule
789
829
  | arg tDOT2 arg
790
830
  {
791
831
  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
832
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
833
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
834
  else
795
835
  result = s(:dot2, v1, v2).line v1.line
@@ -798,7 +838,7 @@ rule
798
838
  | arg tDOT3 arg
799
839
  {
800
840
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
841
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
842
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
843
  else
804
844
  result = s(:dot3, v1, v2).line v1.line
@@ -818,6 +858,22 @@ rule
818
858
 
819
859
  result = s(:dot3, v1, v2).line v1.line
820
860
  }
861
+
862
+ | tBDOT2 arg
863
+ {
864
+ _, v2, = val
865
+ v1 = nil
866
+
867
+ result = s(:dot2, v1, v2).line v2.line
868
+ }
869
+ | tBDOT3 arg
870
+ {
871
+ _, v2 = val
872
+ v1 = nil
873
+
874
+ result = s(:dot3, v1, v2).line v2.line
875
+ }
876
+
821
877
  | arg tPLUS arg
822
878
  {
823
879
  result = new_call val[0], :+, argl(val[2])
@@ -844,8 +900,9 @@ rule
844
900
  }
845
901
  | tUMINUS_NUM simple_numeric tPOW arg
846
902
  {
847
- lit = s(:lit, val[1]).line lexer.lineno
848
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
903
+ _, (num, line), _, arg = val
904
+ lit = s(:lit, num).line line
905
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
906
 
850
907
  }
851
908
  | tUPLUS arg
@@ -944,12 +1001,12 @@ rule
944
1001
 
945
1002
  rel_expr: arg relop arg =tGT
946
1003
  {
947
- lhs, op, rhs = val
1004
+ lhs, (op, _), rhs = val
948
1005
  result = new_call lhs, op.to_sym, argl(rhs)
949
1006
  }
950
1007
  | rel_expr relop arg =tGT
951
1008
  {
952
- lhs, op, rhs = val
1009
+ lhs, (op, _), rhs = val
953
1010
  warn "comparison '%s' after comparison", op
954
1011
  result = new_call lhs, op.to_sym, argl(rhs)
955
1012
  }
@@ -989,6 +1046,24 @@ rule
989
1046
  _, args, _ = val
990
1047
  result = args
991
1048
  }
1049
+ | tLPAREN2 args tCOMMA args_forward rparen
1050
+ {
1051
+ yyerror "Unexpected ..." unless
1052
+ self.lexer.is_local_id(:"*") &&
1053
+ self.lexer.is_local_id(:"**") &&
1054
+ self.lexer.is_local_id(:"&")
1055
+
1056
+ result = call_args val
1057
+ }
1058
+ | tLPAREN2 args_forward rparen
1059
+ {
1060
+ yyerror "Unexpected ..." unless
1061
+ self.lexer.is_local_id(:"*") &&
1062
+ self.lexer.is_local_id(:"**") &&
1063
+ self.lexer.is_local_id(:"&")
1064
+
1065
+ result = call_args val
1066
+ }
992
1067
 
993
1068
  opt_paren_args: none
994
1069
  | paren_args
@@ -1140,8 +1215,9 @@ rule
1140
1215
  | backref
1141
1216
  | tFID
1142
1217
  {
1143
- msg, = val
1218
+ (msg, line), = val
1144
1219
  result = new_call nil, msg.to_sym
1220
+ result.line line
1145
1221
  }
1146
1222
  | k_begin
1147
1223
  {
@@ -1183,15 +1259,13 @@ rule
1183
1259
  }
1184
1260
  | primary_value tCOLON2 tCONSTANT
1185
1261
  {
1186
- expr, _, id = val
1262
+ expr, _, (id, _line) = val
1187
1263
 
1188
1264
  result = s(:colon2, expr, id.to_sym).line expr.line
1189
1265
  }
1190
1266
  | tCOLON3 tCONSTANT
1191
1267
  {
1192
- _, id = val
1193
-
1194
- result = s(:colon3, id.to_sym).line lexer.lineno
1268
+ result = wrap :colon3, val[1]
1195
1269
  }
1196
1270
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1197
1271
  {
@@ -1215,15 +1289,21 @@ rule
1215
1289
  }
1216
1290
  | kYIELD tLPAREN2 call_args rparen
1217
1291
  {
1218
- result = new_yield val[2]
1292
+ (_, line), _, args, _ = val
1293
+
1294
+ result = new_yield(args).line line
1219
1295
  }
1220
1296
  | kYIELD tLPAREN2 rparen
1221
1297
  {
1222
- result = new_yield
1298
+ (_, line), _, _ = val
1299
+
1300
+ result = new_yield.line line
1223
1301
  }
1224
1302
  | kYIELD
1225
1303
  {
1226
- result = new_yield
1304
+ (_, line), = val
1305
+
1306
+ result = new_yield.line line
1227
1307
  }
1228
1308
  | kDEFINED opt_nl tLPAREN2 expr rparen
1229
1309
  {
@@ -1238,7 +1318,7 @@ rule
1238
1318
  }
1239
1319
  | kNOT tLPAREN2 rparen
1240
1320
  {
1241
- debug20 14, val, result
1321
+ debug 20
1242
1322
  }
1243
1323
  | fcall brace_block
1244
1324
  {
@@ -1256,9 +1336,10 @@ rule
1256
1336
  iter.insert 1, call # FIX
1257
1337
  result = iter
1258
1338
  }
1259
- | tLAMBDA lambda
1339
+ | lambda
1260
1340
  {
1261
- result = val[1] # TODO: fix lineno
1341
+ expr, = val
1342
+ result = expr
1262
1343
  }
1263
1344
  | k_if expr_value then compstmt if_tail k_end
1264
1345
  {
@@ -1290,6 +1371,12 @@ rule
1290
1371
  (_, line), _, body, _ = val
1291
1372
  result = new_case nil, body, line
1292
1373
  }
1374
+ | k_case expr_value opt_terms p_case_body k_end
1375
+ {
1376
+ (_, line), expr, _, body, _ = val
1377
+
1378
+ result = new_case expr, body, line
1379
+ }
1293
1380
  | k_for for_var kIN expr_value_do compstmt k_end
1294
1381
  {
1295
1382
  _, var, _, iter, body, _ = val
@@ -1301,7 +1388,6 @@ rule
1301
1388
  }
1302
1389
  cpath superclass
1303
1390
  {
1304
- self.comments.push self.lexer.comments
1305
1391
  if (self.in_def || self.in_single > 0) then
1306
1392
  yyerror "class definition in method body"
1307
1393
  end
@@ -1311,7 +1397,7 @@ rule
1311
1397
  {
1312
1398
  result = new_class val
1313
1399
  self.env.unextend
1314
- self.lexer.comments # we don't care about comments in the body
1400
+ self.lexer.ignore_body_comments
1315
1401
  }
1316
1402
  | k_class tLSHFT
1317
1403
  {
@@ -1332,7 +1418,7 @@ rule
1332
1418
  {
1333
1419
  result = new_sclass val
1334
1420
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1421
+ self.lexer.ignore_body_comments
1336
1422
  }
1337
1423
  | k_module
1338
1424
  {
@@ -1340,7 +1426,6 @@ rule
1340
1426
  }
1341
1427
  cpath
1342
1428
  {
1343
- self.comments.push self.lexer.comments
1344
1429
  yyerror "module definition in method body" if
1345
1430
  self.in_def or self.in_single > 0
1346
1431
 
@@ -1350,7 +1435,7 @@ rule
1350
1435
  {
1351
1436
  result = new_module val
1352
1437
  self.env.unextend
1353
- self.lexer.comments # we don't care about comments in the body
1438
+ self.lexer.ignore_body_comments
1354
1439
  }
1355
1440
  | k_def fname
1356
1441
  {
@@ -1360,21 +1445,17 @@ rule
1360
1445
  self.env.extend
1361
1446
  lexer.cmdarg.push false
1362
1447
  lexer.cond.push false
1363
-
1364
- self.comments.push self.lexer.comments
1365
1448
  }
1366
- f_arglist bodystmt { result = lexer.lineno } k_end
1449
+ f_arglist bodystmt k_end
1367
1450
  {
1368
- in_def = val[2]
1369
-
1370
- result = new_defn val
1451
+ result, in_def = new_defn val
1371
1452
 
1372
1453
  lexer.cond.pop # group = local_pop
1373
1454
  lexer.cmdarg.pop
1374
1455
  self.env.unextend
1375
1456
  self.in_def = in_def
1376
1457
 
1377
- self.lexer.comments # we don't care about comments in the body
1458
+ self.lexer.ignore_body_comments
1378
1459
  }
1379
1460
  | k_def singleton dot_or_colon
1380
1461
  {
@@ -1382,7 +1463,7 @@ rule
1382
1463
  }
1383
1464
  fname
1384
1465
  {
1385
- result = [self.in_def, lexer.lineno]
1466
+ result = self.in_def
1386
1467
 
1387
1468
  self.in_single += 1 # TODO: remove?
1388
1469
 
@@ -1392,13 +1473,18 @@ rule
1392
1473
  lexer.cond.push false
1393
1474
 
1394
1475
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
- self.comments.push self.lexer.comments
1396
1476
  }
1397
1477
  f_arglist bodystmt k_end
1398
1478
  {
1399
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1400
1479
 
1401
- result = new_defs val
1480
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1481
+ # =>
1482
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1483
+
1484
+ val.delete_at 3
1485
+ val.delete_at 2
1486
+
1487
+ result, in_def = new_defs val
1402
1488
 
1403
1489
  lexer.cond.pop # group = local_pop
1404
1490
  lexer.cmdarg.pop
@@ -1409,7 +1495,7 @@ rule
1409
1495
 
1410
1496
  # TODO: restore cur_arg ? what's cur_arg?
1411
1497
 
1412
- self.lexer.comments # we don't care about comments in the body
1498
+ self.lexer.ignore_body_comments
1413
1499
  }
1414
1500
  | kBREAK
1415
1501
  {
@@ -1446,8 +1532,17 @@ rule
1446
1532
  k_case: kCASE
1447
1533
  k_for: kFOR
1448
1534
  k_class: kCLASS
1535
+ {
1536
+ self.comments.push self.lexer.comments
1537
+ }
1449
1538
  k_module: kMODULE
1539
+ {
1540
+ self.comments.push self.lexer.comments
1541
+ }
1450
1542
  k_def: kDEF
1543
+ {
1544
+ self.comments.push self.lexer.comments
1545
+ }
1451
1546
  k_do: kDO
1452
1547
  k_do_block: kDO_BLOCK
1453
1548
  k_rescue: kRESCUE
@@ -1508,51 +1603,42 @@ rule
1508
1603
 
1509
1604
  result = block_var args
1510
1605
  }
1511
- | f_marg_list tCOMMA tSTAR f_norm_arg
1606
+ | f_marg_list tCOMMA f_rest_marg
1512
1607
  {
1513
- args, _, _, splat = val
1608
+ args, _, rest = val
1514
1609
 
1515
- result = block_var args, "*#{splat}".to_sym
1610
+ result = block_var args, rest
1516
1611
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1612
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1518
1613
  {
1519
- args, _, _, splat, _, args2 = val
1614
+ lhs, _, splat, _, rhs = val
1520
1615
 
1521
- result = block_var args, "*#{splat}".to_sym, args2
1616
+ result = block_var lhs, splat, rhs
1522
1617
  }
1523
- | f_marg_list tCOMMA tSTAR
1618
+ | f_rest_marg
1524
1619
  {
1525
- args, _, _ = val
1620
+ rest, = val
1526
1621
 
1527
- result = block_var args, :*
1622
+ result = block_var rest
1528
1623
  }
1529
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1624
+ | f_rest_marg tCOMMA f_marg_list
1530
1625
  {
1531
- args, _, _, _, args2 = val
1626
+ splat, _, rest = val
1532
1627
 
1533
- result = block_var args, :*, args2
1628
+ result = block_var splat, rest
1534
1629
  }
1535
- | tSTAR f_norm_arg
1536
- {
1537
- _, splat = val
1538
1630
 
1539
- result = block_var :"*#{splat}"
1540
- }
1541
- | tSTAR f_norm_arg tCOMMA f_marg_list
1631
+ f_rest_marg: tSTAR f_norm_arg
1542
1632
  {
1543
- _, splat, _, args = val
1633
+ _, (id, line) = val
1544
1634
 
1545
- result = block_var :"*#{splat}", args
1635
+ result = args ["*#{id}".to_sym]
1636
+ result.line line
1546
1637
  }
1547
1638
  | tSTAR
1548
1639
  {
1549
- result = block_var :*
1550
- }
1551
- | tSTAR tCOMMA f_marg_list
1552
- {
1553
- _, _, args = val
1554
-
1555
- result = block_var :*, args
1640
+ result = args [:*]
1641
+ result.line lexer.lineno # FIX: tSTAR -> line
1556
1642
  }
1557
1643
 
1558
1644
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1567,10 +1653,14 @@ rule
1567
1653
  {
1568
1654
  result = call_args val
1569
1655
  }
1656
+ | f_no_kwarg opt_f_block_arg
1657
+ {
1658
+ result = args val
1659
+ }
1570
1660
  | f_block_arg
1571
1661
  {
1572
- line = lexer.lineno
1573
- result = call_args val # TODO: push line down
1662
+ (id, line), = val
1663
+ result = call_args [id]
1574
1664
  result.line line
1575
1665
  }
1576
1666
 
@@ -1679,13 +1769,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1769
 
1680
1770
  bvar: tIDENTIFIER
1681
1771
  {
1682
- id, = val
1683
- line = lexer.lineno
1684
- result = s(:shadow, id.to_sym).line line
1772
+ result = wrap :shadow, val[0]
1685
1773
  }
1686
1774
  | f_bad_arg
1687
1775
 
1688
- lambda: {
1776
+ lambda: tLAMBDA
1777
+ {
1689
1778
  self.env.extend :dynamic
1690
1779
  result = [lexer.lineno, lexer.lpar_beg]
1691
1780
  lexer.paren_nest += 1
@@ -1697,14 +1786,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1697
1786
  }
1698
1787
  lambda_body
1699
1788
  {
1700
- (line, lpar), args, _cmdarg, body = val
1789
+ _, (line, lpar), args, _cmdarg, body = val
1701
1790
  lexer.lpar_beg = lpar
1702
1791
 
1703
1792
  lexer.cmdarg.pop
1704
1793
 
1705
1794
  call = s(:lambda).line line
1706
1795
  result = new_iter call, args, body
1707
- result.line = line
1796
+ result.line line
1708
1797
  self.env.unextend # TODO: dynapush & dynapop
1709
1798
  }
1710
1799
 
@@ -1739,23 +1828,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1739
1828
  ## if (nd_type($1) == NODE_YIELD) {
1740
1829
  ## compile_error(PARSER_ARG "block given to yield");
1741
1830
 
1742
- syntax_error "Both block arg and actual block given." if
1743
- val[0].block_pass?
1831
+ cmd, blk = val
1744
1832
 
1745
- val = invert_block_call val if inverted? val
1833
+ syntax_error "Both block arg and actual block given." if
1834
+ cmd.block_pass?
1746
1835
 
1747
- cmd, blk = val
1836
+ if inverted? val then
1837
+ val = invert_block_call val
1838
+ cmd, blk = val
1839
+ end
1748
1840
 
1749
1841
  result = blk
1750
1842
  result.insert 1, cmd
1751
1843
  }
1752
1844
  | block_call call_op2 operation2 opt_paren_args
1753
1845
  {
1754
- result = new_call val[0], val[2].to_sym, val[3]
1846
+ lhs, _, (id, _line), args = val
1847
+
1848
+ result = new_call lhs, id.to_sym, args
1755
1849
  }
1756
1850
  | block_call call_op2 operation2 opt_paren_args brace_block
1757
1851
  {
1758
- iter1, _, name, args, iter2 = val
1852
+ iter1, _, (name, _line), args, iter2 = val
1759
1853
 
1760
1854
  call = new_call iter1, name.to_sym, args
1761
1855
  iter2.insert 1, call
@@ -1764,7 +1858,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1764
1858
  }
1765
1859
  | block_call call_op2 operation2 command_args do_block
1766
1860
  {
1767
- iter1, _, name, args, iter2 = val
1861
+ iter1, _, (name, _line), args, iter2 = val
1768
1862
 
1769
1863
  call = new_call iter1, name.to_sym, args
1770
1864
  iter2.insert 1, call
@@ -1772,28 +1866,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1772
1866
  result = iter2
1773
1867
  }
1774
1868
 
1775
- method_call: fcall
1869
+ method_call: fcall paren_args
1776
1870
  {
1777
- result = self.lexer.lineno
1778
- }
1779
- paren_args
1780
- {
1781
- call, lineno, args = val
1871
+ call, args = val
1782
1872
 
1783
1873
  result = call.concat args.sexp_body if args
1784
- result.line lineno
1785
1874
  }
1786
1875
  | primary_value call_op operation2 opt_paren_args
1787
1876
  {
1788
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1877
+ recv, call_op, (op, _line), args = val
1878
+
1879
+ result = new_call recv, op.to_sym, args, call_op
1789
1880
  }
1790
1881
  | primary_value tCOLON2 operation2 paren_args
1791
1882
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1883
+ recv, _, (op, _line), args = val
1884
+
1885
+ result = new_call recv, op.to_sym, args
1793
1886
  }
1794
1887
  | primary_value tCOLON2 operation3
1795
1888
  {
1796
- result = new_call val[0], val[2].to_sym
1889
+ lhs, _, (id, _line) = val
1890
+
1891
+ result = new_call lhs, id.to_sym
1797
1892
  }
1798
1893
  | primary_value call_op paren_args
1799
1894
  {
@@ -1826,7 +1921,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1921
  _, line, body, _ = val
1827
1922
 
1828
1923
  result = body
1829
- result.line = line
1924
+ result.line line
1830
1925
 
1831
1926
  self.env.unextend
1832
1927
  }
@@ -1840,7 +1935,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1935
  _, line, body, _ = val
1841
1936
 
1842
1937
  result = body
1843
- result.line = line
1938
+ result.line line
1844
1939
 
1845
1940
  self.env.unextend
1846
1941
  }
@@ -1869,18 +1964,549 @@ opt_block_args_tail: tCOMMA block_args_tail
1869
1964
  self.env.unextend
1870
1965
  }
1871
1966
 
1967
+ case_args: arg_value
1968
+ {
1969
+ arg, = val
1970
+
1971
+ result = s(:array, arg).line arg.line
1972
+ }
1973
+ | tSTAR arg_value
1974
+ {
1975
+ _, arg = val
1976
+
1977
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1978
+ }
1979
+ | case_args tCOMMA arg_value
1980
+ {
1981
+ args, _, id = val
1982
+
1983
+ result = self.list_append args, id
1984
+ }
1985
+ | case_args tCOMMA tSTAR arg_value
1986
+ {
1987
+ args, _, _, id = val
1988
+
1989
+ result = self.list_append args, s(:splat, id).line(id.line)
1990
+ }
1991
+
1872
1992
  case_body: k_when
1873
1993
  {
1874
1994
  result = self.lexer.lineno
1875
1995
  }
1876
- args then compstmt cases
1996
+ case_args then compstmt cases
1877
1997
  {
1878
1998
  result = new_when(val[2], val[4])
1879
- result.line = val[1]
1999
+ result.line val[1]
1880
2000
  result << val[5] if val[5]
1881
2001
  }
1882
2002
 
1883
2003
  cases: opt_else | case_body
2004
+ ######################################################################
2005
+
2006
+ p_case_body: kIN
2007
+ {
2008
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2009
+ self.lexer.command_start = false
2010
+ result = self.in_kwarg
2011
+ self.in_kwarg = true
2012
+ push_pvtbl
2013
+ push_pktbl
2014
+ }
2015
+ p_top_expr then
2016
+ {
2017
+ pop_pktbl
2018
+ pop_pvtbl
2019
+ old_kwargs = _values[-3]
2020
+ self.in_kwarg = old_kwargs
2021
+ }
2022
+ compstmt
2023
+ p_cases
2024
+ {
2025
+ (_, line), _, pat, _, _, body, cases = val
2026
+
2027
+ result = new_in pat, body, cases, line
2028
+ }
2029
+
2030
+ p_cases: opt_else
2031
+ | p_case_body
2032
+
2033
+ p_top_expr: p_top_expr_body
2034
+ | p_top_expr_body kIF_MOD expr_value
2035
+ {
2036
+ body, _, cond = val
2037
+ body = remove_begin body
2038
+
2039
+ result = s(:if, cond, body, nil).line body.line
2040
+ }
2041
+ | p_top_expr_body kUNLESS_MOD expr_value
2042
+ {
2043
+ body, _, cond = val
2044
+ body = remove_begin body
2045
+
2046
+ result = s(:if, cond, nil, body).line body.line
2047
+ }
2048
+
2049
+ p_top_expr_body: p_expr
2050
+ | p_expr tCOMMA
2051
+ {
2052
+ expr, _ = val
2053
+
2054
+ tail = new_array_pattern_tail nil, true, nil, nil
2055
+ result = new_array_pattern nil, expr, tail, expr.line
2056
+ }
2057
+ | p_expr tCOMMA p_args
2058
+ {
2059
+ expr, _, args = val
2060
+
2061
+ result = new_array_pattern nil, expr, args, expr.line
2062
+ }
2063
+ | p_args_tail
2064
+ {
2065
+ args, = val
2066
+ result = new_array_pattern nil, nil, args, args.line
2067
+ }
2068
+ | p_kwargs
2069
+ {
2070
+ kwargs, = val
2071
+ result = new_hash_pattern nil, kwargs, kwargs.line
2072
+ }
2073
+
2074
+ p_expr: p_as
2075
+
2076
+ p_as: p_expr tASSOC p_variable
2077
+ {
2078
+ # NODE *n = NEW_LIST($1, &@$);
2079
+ # n = list_append(p, n, $3);
2080
+ # $$ = new_hash(p, n, &@$);
2081
+
2082
+ expr, _, var = val
2083
+
2084
+ id = var.last
2085
+
2086
+ self.env[id] = :lvar # HACK: need to extend env
2087
+ lhs = s(:lasgn, id).line var.line
2088
+
2089
+ result = new_assign lhs, expr
2090
+ }
2091
+ | p_alt
2092
+
2093
+ p_alt: p_alt tPIPE p_expr_basic
2094
+ {
2095
+ lhs, _, rhs = val
2096
+
2097
+ result = s(:or, lhs, rhs).line lhs.line
2098
+ }
2099
+ | p_expr_basic
2100
+
2101
+ p_lparen: tLPAREN2 { push_pktbl }
2102
+ p_lbracket: tLBRACK2 { push_pktbl }
2103
+
2104
+ p_expr_basic: p_value
2105
+ | p_const p_lparen p_args tRPAREN
2106
+ {
2107
+ lhs, _, args, _ = val
2108
+
2109
+ pop_pktbl
2110
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2111
+ }
2112
+ | p_const p_lparen p_kwargs tRPAREN
2113
+ {
2114
+ lhs, _, kwargs, _ = val
2115
+
2116
+ pop_pktbl
2117
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2118
+ }
2119
+ | p_const tLPAREN2 tRPAREN
2120
+ {
2121
+ const, _, _ = val
2122
+
2123
+ tail = new_array_pattern_tail nil, nil, nil, nil
2124
+ result = new_array_pattern const, nil, tail, const.line
2125
+ }
2126
+ | p_const p_lbracket p_args rbracket
2127
+ {
2128
+ const, _, pre_arg, _ = val
2129
+
2130
+ pop_pktbl
2131
+ result = new_array_pattern const, nil, pre_arg, const.line
2132
+ }
2133
+ | p_const p_lbracket p_kwargs rbracket
2134
+ {
2135
+ const, _, kwargs, _ = val
2136
+
2137
+ result = new_hash_pattern const, kwargs, const.line
2138
+ }
2139
+ | p_const tLBRACK2 rbracket
2140
+ {
2141
+ const, _, _ = val
2142
+
2143
+ tail = new_array_pattern_tail nil, nil, nil, nil
2144
+ result = new_array_pattern const, nil, tail, const.line
2145
+ }
2146
+ | tLBRACK { push_pktbl } p_args rbracket
2147
+ {
2148
+ _, _, pat, _ = val
2149
+
2150
+ pop_pktbl
2151
+ result = new_array_pattern nil, nil, pat, pat.line
2152
+ }
2153
+ | tLBRACK rbracket
2154
+ {
2155
+ (_, line), _ = val
2156
+
2157
+ result = s(:array_pat).line line
2158
+ }
2159
+ | tLBRACE
2160
+ {
2161
+ push_pktbl
2162
+ result = self.in_kwarg
2163
+ self.in_kwarg = false
2164
+ }
2165
+ p_kwargs rbrace
2166
+ {
2167
+ _, in_kwarg, kwargs, _ = val
2168
+
2169
+ pop_pktbl
2170
+ self.in_kwarg = in_kwarg
2171
+
2172
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2173
+ }
2174
+ | tLBRACE rbrace
2175
+ {
2176
+ (_, line), _ = val
2177
+
2178
+ tail = new_hash_pattern_tail nil, nil, line
2179
+ result = new_hash_pattern nil, tail, line
2180
+ }
2181
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2182
+ {
2183
+ _, _, expr, _ = val
2184
+
2185
+ pop_pktbl
2186
+ result = expr
2187
+ }
2188
+
2189
+ p_args: p_expr
2190
+ {
2191
+ expr, = val
2192
+
2193
+ ary = s(:array_TAIL, expr).line expr.line
2194
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2195
+ }
2196
+ | p_args_head
2197
+ {
2198
+ head, = val
2199
+
2200
+ result = new_array_pattern_tail head, true, nil, nil
2201
+ }
2202
+ | p_args_head p_arg
2203
+ {
2204
+ head, tail = val
2205
+
2206
+ both = array_pat_concat head, tail
2207
+
2208
+ result = new_array_pattern_tail both, nil, nil, nil
2209
+ result.line head.line
2210
+ }
2211
+ | p_args_head tSTAR tIDENTIFIER
2212
+ {
2213
+ head, _, (id, _line) = val
2214
+
2215
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2216
+ result.line head.line
2217
+ }
2218
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2219
+ {
2220
+ head, _, (id, _line), _, post = val
2221
+
2222
+ result = new_array_pattern_tail head, true, id.to_sym, post
2223
+ result.line head.line
2224
+ }
2225
+ | p_args_head tSTAR
2226
+ {
2227
+ expr, _ = val
2228
+
2229
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2230
+ }
2231
+ | p_args_head tSTAR tCOMMA p_args_post
2232
+ {
2233
+ head, _, _, post = val
2234
+
2235
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2236
+ }
2237
+ | p_args_tail
2238
+
2239
+ p_args_head: p_arg tCOMMA
2240
+ {
2241
+ arg, _ = val
2242
+ result = arg
2243
+ }
2244
+ | p_args_head p_arg tCOMMA
2245
+ {
2246
+ head, tail, _ = val
2247
+
2248
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2249
+ result.line head.line
2250
+ }
2251
+
2252
+ p_args_tail: tSTAR tIDENTIFIER
2253
+ {
2254
+ _, (id, line) = val
2255
+
2256
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2257
+ result.line line
2258
+ }
2259
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2260
+ {
2261
+ _, (id, line), _, rhs = val
2262
+
2263
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2264
+ result.line line
2265
+ }
2266
+ | tSTAR
2267
+ {
2268
+ (_, line), = val
2269
+
2270
+ result = new_array_pattern_tail nil, true, nil, nil
2271
+ result.line line
2272
+ }
2273
+ | tSTAR tCOMMA p_args_post
2274
+ {
2275
+ (_, line), _, args = val
2276
+
2277
+ result = new_array_pattern_tail nil, true, nil, args
2278
+ result.line line
2279
+ }
2280
+
2281
+ p_args_post: p_arg
2282
+ | p_args_post tCOMMA p_arg
2283
+ {
2284
+ lhs, _, rhs = val
2285
+
2286
+ result = array_pat_concat lhs, rhs
2287
+ }
2288
+
2289
+ p_arg: p_expr
2290
+ {
2291
+ expr, = val
2292
+ expr = s(:array_TAIL, expr).line expr.line unless
2293
+ expr.sexp_type == :array_TAIL
2294
+ result = expr
2295
+ }
2296
+
2297
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2298
+ {
2299
+ kw_arg, _, rest = val
2300
+ # TODO? new_unique_key_hash(p, $1, &@$)
2301
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2302
+ }
2303
+ | p_kwarg
2304
+ {
2305
+ kwarg, = val
2306
+ # TODO? new_unique_key_hash(p, $1, &@$)
2307
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2308
+ }
2309
+ | p_kwarg tCOMMA
2310
+ {
2311
+ kwarg, _ = val
2312
+ # TODO? new_unique_key_hash(p, $1, &@$)
2313
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2314
+ }
2315
+ | p_kwrest
2316
+ {
2317
+ rest, = val
2318
+
2319
+ result = new_hash_pattern_tail nil, rest, rest.line
2320
+ }
2321
+ | p_kwarg tCOMMA p_kwnorest
2322
+ {
2323
+ kwarg, _, norest = val
2324
+
2325
+ # TODO? new_unique_key_hash(p, $1, &@$)
2326
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2327
+ }
2328
+ | p_kwnorest
2329
+ {
2330
+ norest, = val
2331
+
2332
+ result = new_hash_pattern_tail nil, norest, norest.line
2333
+ }
2334
+
2335
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2336
+ | p_kwarg tCOMMA p_kw
2337
+ {
2338
+ kwarg, _, kw = val
2339
+ kwarg.concat kw.sexp_body
2340
+ result = kwarg
2341
+ }
2342
+
2343
+ p_kw: p_kw_label p_expr
2344
+ {
2345
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2346
+ lhs, rhs = val
2347
+
2348
+ result = s(:PAIR, lhs, rhs).line lhs.line
2349
+ }
2350
+ | p_kw_label
2351
+ {
2352
+ lhs, = val
2353
+
2354
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2355
+
2356
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2357
+ # yyerror1(&@1, "key must be valid as local variables");
2358
+ # }
2359
+
2360
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2361
+ # assignable(p, $1, 0, &@$));
2362
+
2363
+
2364
+ case lhs.sexp_type
2365
+ when :lit then
2366
+ assignable [lhs.value, lhs.line]
2367
+ else
2368
+ # TODO or done?
2369
+ debug 666
2370
+ end
2371
+
2372
+ # TODO PAIR -> LIST ?
2373
+ result = s(:PAIR, lhs, nil).line lhs.line
2374
+ }
2375
+
2376
+ p_kw_label: tLABEL
2377
+ {
2378
+ result = wrap :lit, val[0]
2379
+ }
2380
+
2381
+ p_kwrest: kwrest_mark tIDENTIFIER
2382
+ {
2383
+ _, (id, line) = val
2384
+
2385
+ name = id.to_sym
2386
+ self.assignable [name, line]
2387
+ result = s(:kwrest, :"**#{name}").line line
2388
+ }
2389
+ | kwrest_mark
2390
+ {
2391
+ (_, line), = val
2392
+
2393
+ result = s(:kwrest, :"**").line line
2394
+ }
2395
+
2396
+ p_kwnorest: kwrest_mark kNIL
2397
+ {
2398
+ (_, line), _ = val
2399
+
2400
+ # TODO: or s(:norest)? s(:**nil)?
2401
+ result = s(:kwrest, :"**nil").line line
2402
+ }
2403
+
2404
+ p_value: p_primitive
2405
+ | p_primitive tDOT2 p_primitive
2406
+ {
2407
+ lhs, _, rhs = val
2408
+
2409
+ lhs = value_expr lhs
2410
+ rhs = value_expr rhs
2411
+
2412
+ result = s(:dot2, lhs, rhs).line lhs.line
2413
+ }
2414
+ | p_primitive tDOT3 p_primitive
2415
+ {
2416
+ lhs, _, rhs = val
2417
+
2418
+ lhs = value_expr lhs
2419
+ rhs = value_expr rhs
2420
+
2421
+ result = s(:dot3, lhs, rhs).line lhs.line
2422
+ }
2423
+ | p_primitive tDOT2
2424
+ {
2425
+ v1, _ = val
2426
+
2427
+ result = s(:dot2, v1, nil).line v1.line
2428
+ }
2429
+ | p_primitive tDOT3
2430
+ {
2431
+ v1, _ = val
2432
+
2433
+ result = s(:dot3, v1, nil).line v1.line
2434
+ }
2435
+ | p_variable
2436
+ | p_var_ref
2437
+ | p_const
2438
+ | tBDOT2 p_primitive
2439
+ {
2440
+ _, v1 = val
2441
+
2442
+ result = s(:dot2, nil, v1).line v1.line
2443
+ }
2444
+ | tBDOT3 p_primitive
2445
+ {
2446
+ _, v1 = val
2447
+
2448
+ result = s(:dot3, nil, v1).line v1.line
2449
+ }
2450
+
2451
+ p_primitive: literal
2452
+ | strings
2453
+ | xstring
2454
+ | regexp
2455
+ | words
2456
+ {
2457
+ result = ary_to_pat val[0]
2458
+ }
2459
+ | qwords
2460
+ {
2461
+ result = ary_to_pat val[0]
2462
+ }
2463
+ | symbols
2464
+ {
2465
+ result = ary_to_pat val[0]
2466
+ }
2467
+ | qsymbols
2468
+ {
2469
+ result = ary_to_pat val[0]
2470
+ }
2471
+ | keyword_variable
2472
+ {
2473
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2474
+ var, = val
2475
+
2476
+ result = var
2477
+ }
2478
+ | lambda
2479
+
2480
+ p_variable: tIDENTIFIER
2481
+ {
2482
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2483
+ # TODO: assignable(p, $1, 0, &@$);
2484
+ result = wrap :lasgn, val[0]
2485
+ }
2486
+
2487
+ p_var_ref: tCARET tIDENTIFIER
2488
+ {
2489
+ # TODO: check id against env for lvar or dvar
2490
+ result = wrap :lvar, val[1]
2491
+ }
2492
+
2493
+ p_const: tCOLON3 cname
2494
+ {
2495
+ result = wrap :colon3, val[1]
2496
+ }
2497
+ | p_const tCOLON2 cname
2498
+ {
2499
+ lhs, _, (id, _line) = val
2500
+
2501
+ l = lhs.line
2502
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2503
+ }
2504
+ | tCONSTANT
2505
+ {
2506
+ # TODO $$ = gettable(p, $1, &@$);
2507
+ result = wrap :const, val[0]
2508
+ }
2509
+ ######################################################################
1884
2510
 
1885
2511
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1886
2512
  {
@@ -1922,17 +2548,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1922
2548
 
1923
2549
  literal: numeric
1924
2550
  {
1925
- line = lexer.lineno
1926
- result = s(:lit, val[0])
1927
- result.line = line
2551
+ (lit, line), = val
2552
+ result = s(:lit, lit).line line
1928
2553
  }
1929
2554
  | symbol
1930
- {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1934
- }
1935
- | dsym
1936
2555
 
1937
2556
  strings: string
1938
2557
  {
@@ -1943,7 +2562,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1943
2562
 
1944
2563
  string: tCHAR
1945
2564
  {
1946
- debug20 23, val, result
2565
+ debug 37
1947
2566
  }
1948
2567
  | string1
1949
2568
  | string string1
@@ -1953,11 +2572,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
2572
 
1954
2573
  string1: tSTRING_BEG string_contents tSTRING_END
1955
2574
  {
1956
- _, str, (_, func) = val
2575
+ (_, line), str, (_, func) = val
1957
2576
 
1958
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2577
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1959
2578
 
1960
- result = str
2579
+ result = str.line line
1961
2580
  }
1962
2581
  | tSTRING
1963
2582
  {
@@ -1977,11 +2596,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2596
 
1978
2597
  words: tWORDS_BEG tSPACE tSTRING_END
1979
2598
  {
1980
- result = s(:array).line lexer.lineno
2599
+ (_, line), _, _ = val
2600
+
2601
+ result = s(:array).line line
1981
2602
  }
1982
2603
  | tWORDS_BEG word_list tSTRING_END
1983
2604
  {
1984
- result = val[1]
2605
+ (_, line), list, _ = val
2606
+
2607
+ result = list.line line
1985
2608
  }
1986
2609
 
1987
2610
  word_list: none
@@ -2001,18 +2624,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2001
2624
 
2002
2625
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2003
2626
  {
2004
- result = s(:array).line lexer.lineno
2627
+ (_, line), _, _ = val
2628
+
2629
+ result = s(:array).line line
2005
2630
  }
2006
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2631
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2007
2632
  {
2008
- _, line, list, _, = val
2009
- list.line = line
2633
+ (_, line), list, _, = val
2634
+ list.line line
2010
2635
  result = list
2011
2636
  }
2012
2637
 
2013
2638
  symbol_list: none
2014
2639
  {
2015
- result = new_symbol_list.line lexer.lineno
2640
+ result = new_symbol_list
2016
2641
  }
2017
2642
  | symbol_list word tSPACE
2018
2643
  {
@@ -2022,20 +2647,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2022
2647
 
2023
2648
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2024
2649
  {
2025
- result = s(:array).line lexer.lineno
2650
+ (_, line), _, _ = val
2651
+
2652
+ result = s(:array).line line
2026
2653
  }
2027
2654
  | tQWORDS_BEG qword_list tSTRING_END
2028
2655
  {
2029
- result = val[1]
2656
+ (_, line), list, _ = val
2657
+
2658
+ result = list.line line
2030
2659
  }
2031
2660
 
2032
2661
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2033
2662
  {
2034
- result = s(:array).line lexer.lineno # FIX
2663
+ (_, line), _, _ = val
2664
+
2665
+ result = s(:array).line line
2035
2666
  }
2036
2667
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2037
2668
  {
2038
- result = val[1]
2669
+ (_, line), list, _ = val
2670
+
2671
+ result = list.line line
2039
2672
  }
2040
2673
 
2041
2674
  qword_list: none
@@ -2058,7 +2691,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2691
 
2059
2692
  string_contents: none
2060
2693
  {
2061
- result = s(:str, "").line lexer.lineno
2694
+ line = prev_value_to_lineno _values.last
2695
+ result = s(:str, +"").line line
2062
2696
  }
2063
2697
  | string_contents string_content
2064
2698
  {
@@ -2133,8 +2767,8 @@ regexp_contents: none
2133
2767
  lexer.brace_nest = brace_nest
2134
2768
  lexer.string_nest = string_nest
2135
2769
 
2136
- lexer.cmdarg.pop
2137
2770
  lexer.cond.pop
2771
+ lexer.cmdarg.pop
2138
2772
 
2139
2773
  lexer.lex_state = oldlex_state
2140
2774
 
@@ -2149,29 +2783,42 @@ regexp_contents: none
2149
2783
  when nil then
2150
2784
  result = s(:evstr).line line
2151
2785
  else
2152
- debug20 25
2786
+ debug 38
2153
2787
  raise "unknown string body: #{stmt.inspect}"
2154
2788
  end
2155
2789
  }
2156
2790
 
2157
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2791
+ string_dvar: tGVAR
2792
+ {
2793
+ result = wrap :gvar, val[0]
2794
+ }
2795
+ | tIVAR
2796
+ {
2797
+ result = wrap :ivar, val[0]
2798
+ }
2799
+ | tCVAR
2800
+ {
2801
+ result = wrap :cvar, val[0]
2802
+ }
2160
2803
  | backref
2161
2804
 
2162
- symbol: tSYMBEG sym
2805
+ symbol: ssym
2806
+ | dsym
2807
+
2808
+ ssym: tSYMBEG sym
2163
2809
  {
2164
2810
  lexer.lex_state = EXPR_END
2165
- result = val[1].to_sym
2811
+ result = wrap :lit, val[1]
2166
2812
  }
2167
2813
  | tSYMBOL
2168
2814
  {
2169
- result = val[0].to_sym
2815
+ lexer.lex_state = EXPR_END
2816
+ result = wrap :lit, val[0]
2170
2817
  }
2171
2818
 
2172
2819
  sym: fname | tIVAR | tGVAR | tCVAR
2173
2820
 
2174
- dsym: tSYMBEG xstring_contents tSTRING_END
2821
+ dsym: tSYMBEG string_contents tSTRING_END
2175
2822
  {
2176
2823
  _, result, _ = val
2177
2824
 
@@ -2187,14 +2834,15 @@ regexp_contents: none
2187
2834
  when :evstr then
2188
2835
  result = s(:dsym, "", result).line result.line
2189
2836
  else
2190
- debug20 26, val, result
2837
+ debug 39
2191
2838
  end
2192
2839
  }
2193
2840
 
2194
2841
  numeric: simple_numeric
2195
- | tUMINUS_NUM simple_numeric
2842
+ | tUMINUS_NUM simple_numeric =tLOWEST
2196
2843
  {
2197
- result = -val[1] # TODO: pt_testcase
2844
+ _, (num, line) = val
2845
+ result = [-num, line]
2198
2846
  }
2199
2847
 
2200
2848
  simple_numeric: tINTEGER
@@ -2227,8 +2875,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2227
2875
 
2228
2876
  var_ref: user_variable
2229
2877
  {
2230
- var = val[0]
2878
+ raise "NO: #{val.inspect}" if Sexp === val.first
2879
+ (var, line), = val
2231
2880
  result = Sexp === var ? var : self.gettable(var)
2881
+ result.line line
2232
2882
  }
2233
2883
  | keyword_variable
2234
2884
  {
@@ -2243,11 +2893,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2893
  | keyword_variable
2244
2894
  {
2245
2895
  result = self.assignable val[0]
2246
- debug20 29, val, result
2896
+ debug 40
2247
2897
  }
2248
2898
 
2249
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2899
+ backref: tNTH_REF
2900
+ {
2901
+ (ref, line), = val
2902
+ result = s(:nth_ref, ref).line line
2903
+ }
2904
+ | tBACK_REF
2905
+ {
2906
+ (ref, line), = val
2907
+ result = s(:back_ref, ref).line line
2908
+ }
2251
2909
 
2252
2910
  superclass: tLT
2253
2911
  {
@@ -2265,9 +2923,15 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2923
 
2266
2924
  f_arglist: tLPAREN2 f_args rparen
2267
2925
  {
2268
- result = val[1]
2269
- self.lexer.lex_state = EXPR_BEG
2270
- self.lexer.command_start = true
2926
+ result = end_args val
2927
+ }
2928
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
2929
+ {
2930
+ result = end_args val
2931
+ }
2932
+ | tLPAREN2 args_forward rparen
2933
+ {
2934
+ result = end_args val
2271
2935
  }
2272
2936
  | {
2273
2937
  result = self.in_kwarg
@@ -2276,12 +2940,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2276
2940
  }
2277
2941
  f_args term
2278
2942
  {
2279
- kwarg, args, _ = val
2280
-
2281
- self.in_kwarg = kwarg
2282
- result = args
2283
- lexer.lex_state = EXPR_BEG
2284
- lexer.command_start = true
2943
+ result = end_args val
2285
2944
  }
2286
2945
 
2287
2946
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2296,6 +2955,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2296
2955
  {
2297
2956
  result = args val
2298
2957
  }
2958
+ | f_no_kwarg opt_f_block_arg
2959
+ {
2960
+ result = args val
2961
+ }
2299
2962
  | f_block_arg
2300
2963
 
2301
2964
  opt_args_tail: tCOMMA args_tail
@@ -2366,6 +3029,12 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
3029
  |
2367
3030
  {
2368
3031
  result = args val
3032
+ # result.line lexer.lineno
3033
+ }
3034
+
3035
+ args_forward: tBDOT3
3036
+ {
3037
+ result = s(:forward_args).line lexer.lineno
2369
3038
  }
2370
3039
 
2371
3040
  f_bad_arg: tCONSTANT
@@ -2388,10 +3057,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2388
3057
  f_norm_arg: f_bad_arg
2389
3058
  | tIDENTIFIER
2390
3059
  {
2391
- identifier = val[0].to_sym
3060
+ (id, line), = val
3061
+ identifier = id.to_sym
2392
3062
  self.env[identifier] = :lvar
2393
3063
 
2394
- result = identifier
3064
+ result = [identifier, line]
2395
3065
  }
2396
3066
 
2397
3067
  f_arg_asgn: f_norm_arg
@@ -2399,22 +3069,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2399
3069
  f_arg_item: f_arg_asgn
2400
3070
  | tLPAREN f_margs rparen
2401
3071
  {
2402
- result = val[1]
3072
+ _, margs, _ = val
3073
+
3074
+ result = margs
2403
3075
  }
2404
3076
 
2405
3077
  f_arg: f_arg_item
2406
3078
  {
2407
- arg, = val
2408
-
2409
- case arg
2410
- when Symbol then
2411
- result = s(:args, arg).line lexer.lineno
2412
- when Sexp then
2413
- result = arg
2414
- else
2415
- debug20 32
2416
- raise "Unknown f_arg type: #{val.inspect}"
2417
- end
3079
+ result = new_arg val
2418
3080
  }
2419
3081
  | f_arg tCOMMA f_arg_item
2420
3082
  {
@@ -2426,7 +3088,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2426
3088
  result = s(:args, list).line list.line
2427
3089
  end
2428
3090
 
2429
- result << item
3091
+ result << (Sexp === item ? item : item.first)
2430
3092
  }
2431
3093
 
2432
3094
  f_label: tLABEL
@@ -2487,26 +3149,37 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2487
3149
  kwrest_mark: tPOW
2488
3150
  | tDSTAR
2489
3151
 
3152
+ f_no_kwarg: kwrest_mark kNIL
3153
+ {
3154
+ result = :"**nil"
3155
+ }
3156
+
2490
3157
  f_kwrest: kwrest_mark tIDENTIFIER
2491
3158
  {
2492
- name = val[1].to_sym
2493
- self.assignable name
2494
- result = :"**#{name}"
3159
+ _, (id, line) = val
3160
+
3161
+ name = id.to_sym
3162
+ self.assignable [name, line]
3163
+ result = [:"**#{name}", line]
2495
3164
  }
2496
3165
  | kwrest_mark
2497
3166
  {
2498
- result = :"**"
3167
+ id = :"**"
3168
+ self.env[id] = :lvar # TODO: needed?!?
3169
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2499
3170
  }
2500
3171
 
2501
3172
  f_opt: f_arg_asgn tEQL arg_value
2502
3173
  {
2503
- result = self.assignable val[0], val[2]
3174
+ lhs, _, rhs = val
3175
+ result = self.assignable lhs, rhs
2504
3176
  # TODO: detect duplicate names
2505
3177
  }
2506
3178
 
2507
3179
  f_block_opt: f_arg_asgn tEQL primary_value
2508
3180
  {
2509
- result = self.assignable val[0], val[2]
3181
+ lhs, _, rhs = val
3182
+ result = self.assignable lhs, rhs
2510
3183
  }
2511
3184
 
2512
3185
  f_block_optarg: f_block_opt
@@ -2536,30 +3209,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2536
3209
  f_rest_arg: restarg_mark tIDENTIFIER
2537
3210
  {
2538
3211
  # TODO: differs from parse.y - needs tests
2539
- name = val[1].to_sym
2540
- self.assignable name
2541
- result = :"*#{name}"
3212
+ _, (id, line) = val
3213
+ name = id.to_sym
3214
+ self.assignable [name, line]
3215
+ result = [:"*#{name}", line]
2542
3216
  }
2543
3217
  | restarg_mark
2544
3218
  {
2545
3219
  name = :"*"
2546
3220
  self.env[name] = :lvar
2547
- result = name
3221
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2548
3222
  }
2549
3223
 
2550
3224
  blkarg_mark: tAMPER2 | tAMPER
2551
3225
 
2552
3226
  f_block_arg: blkarg_mark tIDENTIFIER
2553
3227
  {
2554
- identifier = val[1].to_sym
3228
+ _, (id, line) = val
3229
+ identifier = id.to_sym
2555
3230
 
2556
3231
  self.env[identifier] = :lvar
2557
- result = "&#{identifier}".to_sym
3232
+ result = ["&#{identifier}".to_sym, line]
2558
3233
  }
2559
3234
 
2560
3235
  opt_f_block_arg: tCOMMA f_block_arg
2561
3236
  {
2562
- result = val[1]
3237
+ _, arg = val
3238
+ result = arg
2563
3239
  }
2564
3240
  |
2565
3241
  {
@@ -2601,16 +3277,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2601
3277
  }
2602
3278
  | tLABEL arg_value
2603
3279
  {
2604
- (label, line), arg = val
3280
+ label, arg = val
2605
3281
 
2606
- lit = s(:lit, label.to_sym).line line
2607
- result = s(:array, lit, arg).line line
3282
+ lit = wrap :lit, label
3283
+ result = s(:array, lit, arg).line lit.line
2608
3284
  }
2609
3285
  | tSTRING_BEG string_contents tLABEL_END arg_value
2610
3286
  {
2611
- _, sym, _, value = val
3287
+ (_, line), sym, _, value = val
3288
+
2612
3289
  sym.sexp_type = :dsym
2613
- result = s(:array, sym, value).line sym.line
3290
+
3291
+ result = s(:array, sym, value).line line
2614
3292
  }
2615
3293
  | tDSTAR arg_value
2616
3294
  {
@@ -2633,6 +3311,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2633
3311
  opt_nl: | tNL
2634
3312
  rparen: opt_nl tRPAREN
2635
3313
  rbracket: opt_nl tRBRACK
3314
+ rbrace: opt_nl tRCURLY
2636
3315
  trailer: | tNL | tCOMMA
2637
3316
 
2638
3317
  term: tSEMI { yyerrok }