ruby_parser 3.17.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. metadata.gz.sig +0 -0
data/lib/ruby_parser.yy CHANGED
@@ -16,8 +16,6 @@ class Ruby25Parser
16
16
  class Ruby26Parser
17
17
  #elif V == 27
18
18
  class Ruby27Parser
19
- #elif V == 30
20
- class Ruby30Parser
21
19
  #else
22
20
  fail "version not specified or supported on code generation"
23
21
  #endif
@@ -38,7 +36,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
38
36
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
39
37
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
40
38
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
41
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
39
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
42
40
  #if V >= 21
43
41
  tRATIONAL tIMAGINARY
44
42
  #endif
@@ -108,7 +106,7 @@ rule
108
106
  | klBEGIN
109
107
  {
110
108
  if (self.in_def || self.in_single > 0) then
111
- debug20 1
109
+ debug 11
112
110
  yyerror "BEGIN in method"
113
111
  end
114
112
  self.env.extend
@@ -133,7 +131,13 @@ rule
133
131
  bodystmt: compstmt opt_rescue k_else
134
132
  {
135
133
  res = _values[-2]
134
+ # TODO: move down to main match so I can just use val
135
+
136
+ #if V >= 26
136
137
  yyerror "else without rescue is useless" unless res
138
+ #else
139
+ warn "else without rescue is useless" unless res
140
+ #endif
137
141
  }
138
142
  compstmt
139
143
  opt_ensure
@@ -163,7 +167,7 @@ rule
163
167
  | error stmt
164
168
  {
165
169
  result = val[1]
166
- debug20 2, val, result
170
+ debug 12
167
171
  }
168
172
 
169
173
  stmt_or_begin: stmt
@@ -171,6 +175,10 @@ rule
171
175
  {
172
176
  yyerror "BEGIN is permitted only at toplevel"
173
177
  }
178
+ begin_block
179
+ {
180
+ result = val[2] # wtf?
181
+ }
174
182
 
175
183
  stmt: kALIAS fitem
176
184
  {
@@ -183,12 +191,12 @@ rule
183
191
  }
184
192
  | kALIAS tGVAR tGVAR
185
193
  {
186
- (_, line), lhs, rhs = val
194
+ (_, line), (lhs, _), (rhs, _) = val
187
195
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
188
196
  }
189
197
  | kALIAS tGVAR tBACK_REF
190
198
  {
191
- (_, line), lhs, rhs = val
199
+ (_, line), (lhs, _), (rhs, _) = val
192
200
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
193
201
  }
194
202
  | kALIAS tGVAR tNTH_REF
@@ -231,7 +239,7 @@ rule
231
239
  (_, line), _, stmt, _ = val
232
240
 
233
241
  if (self.in_def || self.in_single > 0) then
234
- debug20 3
242
+ debug 13
235
243
  yyerror "END in method; use at_exit"
236
244
  end
237
245
 
@@ -252,6 +260,19 @@ rule
252
260
  {
253
261
  result = new_masgn val[0], val[2], :wrap
254
262
  }
263
+ #endif
264
+ #if V >= 27
265
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
266
+ {
267
+ # unwraps s(:to_ary, rhs)
268
+ lhs, _, (_, rhs), _, resbody = val
269
+
270
+ resbody = new_resbody s(:array).line(resbody.line), resbody
271
+
272
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
273
+ }
274
+ #endif
275
+ #if V == 20
255
276
  | mlhs tEQL mrhs
256
277
  #else
257
278
  | mlhs tEQL mrhs_arg
@@ -279,32 +300,31 @@ rule
279
300
  }
280
301
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
281
302
  {
282
- prim, _, id, opasgn, rhs = val
283
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
284
- if val[1] == '&.'
285
- result.sexp_type = :safe_op_asgn
286
- end
287
- result.line = val[0].line
303
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
304
+
305
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
306
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
307
+ result.line prim.line
288
308
  }
289
309
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
290
310
  {
291
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
292
- if val[1] == '&.'
293
- result.sexp_type = :safe_op_asgn
294
- end
295
- result.line = val[0].line
311
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
312
+
313
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
314
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
315
+ result.line prim.line
296
316
  }
297
317
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
298
318
  {
299
- lhs1, _, lhs2, op, rhs = val
319
+ lhs1, _, (lhs2, line), (id, _), rhs = val
300
320
 
301
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
321
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
302
322
  }
303
323
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
304
324
  {
305
- lhs1, _, lhs2, op, rhs = val
325
+ lhs1, _, (lhs2, line), (id, _), rhs = val
306
326
 
307
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
327
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
308
328
  }
309
329
  | backref tOP_ASGN command_rhs
310
330
  {
@@ -352,7 +372,31 @@ rule
352
372
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
353
373
  # REFACTOR: call_uni_op -- see parse26.y
354
374
  }
375
+ #if V >= 27
355
376
  | arg
377
+ kIN
378
+ {
379
+ # TODO? value_expr($1);
380
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
381
+ self.lexer.command_start = false
382
+ result = self.in_kwarg
383
+ self.in_kwarg = true
384
+ self.env.extend
385
+ }
386
+ p_expr
387
+ {
388
+ self.env.unextend
389
+
390
+ expr, _, old_kwarg, pat = val
391
+
392
+ expr = value_expr expr
393
+
394
+ self.in_kwarg = old_kwarg
395
+ pat_in = new_in pat, nil, nil, expr.line
396
+ result = new_case expr, pat_in, expr.line
397
+ }
398
+ #endif
399
+ | arg =tLBRACE_ARG
356
400
 
357
401
  expr_value: expr
358
402
  {
@@ -377,7 +421,7 @@ rule
377
421
  block_command: block_call
378
422
  | block_call call_op2 operation2 command_args
379
423
  {
380
- blk, _, msg, args = val
424
+ blk, _, (msg, _line), args = val
381
425
  result = new_call(blk, msg.to_sym, args).line blk.line
382
426
  }
383
427
 
@@ -391,15 +435,15 @@ rule
391
435
  _, line, body, _ = val
392
436
 
393
437
  result = body
394
- result.line = line
438
+ result.line line
395
439
 
396
440
  # self.env.unextend
397
441
  }
398
442
 
399
443
  fcall: operation
400
444
  {
401
- msg, = val
402
- result = new_call(nil, msg.to_sym).line lexer.lineno
445
+ (msg, line), = val
446
+ result = new_call(nil, msg.to_sym).line line
403
447
  }
404
448
 
405
449
  command: fcall command_args =tLOWEST
@@ -422,12 +466,14 @@ rule
422
466
  }
423
467
  | primary_value call_op operation2 command_args =tLOWEST
424
468
  {
425
- lhs, callop, op, args = val
469
+ lhs, callop, (op, _), args = val
470
+
426
471
  result = new_call lhs, op.to_sym, args, callop
472
+ result.line lhs.line
427
473
  }
428
474
  | primary_value call_op operation2 command_args cmd_brace_block
429
475
  {
430
- recv, _, msg, args, block = val
476
+ recv, _, (msg, _line), args, block = val
431
477
  call = new_call recv, msg.to_sym, args, val[1]
432
478
 
433
479
  block_dup_check call, block
@@ -437,11 +483,14 @@ rule
437
483
  }
438
484
  | primary_value tCOLON2 operation2 command_args =tLOWEST
439
485
  {
440
- result = new_call val[0], val[2].to_sym, val[3]
486
+ lhs, _, (id, line), args = val
487
+
488
+ result = new_call lhs, id.to_sym, args
489
+ result.line line
441
490
  }
442
491
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
443
492
  {
444
- recv, _, msg, args, block = val
493
+ recv, _, (msg, _line), args, block = val
445
494
  call = new_call recv, msg.to_sym, args
446
495
 
447
496
  block_dup_check call, block
@@ -599,25 +648,29 @@ rule
599
648
  }
600
649
  | primary_value call_op tIDENTIFIER
601
650
  {
602
- result = new_attrasgn val[0], val[2], val[1]
651
+ lhs, call_op, (id, _line) = val
652
+
653
+ result = new_attrasgn lhs, id, call_op
603
654
  }
604
655
  | primary_value tCOLON2 tIDENTIFIER
605
656
  {
606
- recv, _, id = val
657
+ recv, _, (id, _line) = val
607
658
  result = new_attrasgn recv, id
608
659
  }
609
660
  | primary_value call_op tCONSTANT
610
661
  {
611
- result = new_attrasgn val[0], val[2], val[1]
662
+ lhs, call_op, (id, _line) = val
663
+
664
+ result = new_attrasgn lhs, id, call_op
612
665
  }
613
666
  | primary_value tCOLON2 tCONSTANT
614
667
  {
615
668
  if (self.in_def || self.in_single > 0) then
616
- debug20 7
669
+ debug 14
617
670
  yyerror "dynamic constant assignment"
618
671
  end
619
672
 
620
- expr, _, id = val
673
+ expr, _, (id, _line) = val
621
674
  l = expr.line
622
675
 
623
676
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -625,58 +678,65 @@ rule
625
678
  | tCOLON3 tCONSTANT
626
679
  {
627
680
  if (self.in_def || self.in_single > 0) then
628
- debug20 8
681
+ debug 15
629
682
  yyerror "dynamic constant assignment"
630
683
  end
631
684
 
632
- _, id = val
633
- l = lexer.lineno
685
+ _, (id, l) = val
634
686
 
635
687
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
636
688
  }
637
689
  | backref
638
690
  {
639
- self.backref_assign_error val[0]
691
+ ref, = val
692
+
693
+ self.backref_assign_error ref
640
694
  }
641
695
 
642
696
  lhs: user_variable
643
697
  {
644
- line = lexer.lineno
645
- result = self.assignable val[0]
646
- result.line = line
698
+ var, = val
699
+
700
+ result = self.assignable var
647
701
  }
648
702
  | keyword_variable
649
703
  {
650
- line = lexer.lineno
651
- result = self.assignable val[0]
652
- result.line = line
653
- debug20 9, val, result
704
+ var, = val
705
+
706
+ result = self.assignable var
707
+
708
+ debug 16
654
709
  }
655
710
  | primary_value tLBRACK2 opt_call_args rbracket
656
711
  {
657
712
  lhs, _, args, _ = val
713
+
658
714
  result = self.aryset lhs, args
659
715
  }
660
716
  | primary_value call_op tIDENTIFIER # REFACTOR
661
717
  {
662
- lhs, op, id = val
718
+ lhs, op, (id, _line) = val
719
+
663
720
  result = new_attrasgn lhs, id, op
664
721
  }
665
722
  | primary_value tCOLON2 tIDENTIFIER
666
723
  {
667
- lhs, _, id = val
724
+ lhs, _, (id, _line) = val
725
+
668
726
  result = new_attrasgn lhs, id
669
727
  }
670
728
  | primary_value call_op tCONSTANT # REFACTOR?
671
729
  {
672
- result = new_attrasgn val[0], val[2], val[1]
730
+ lhs, call_op, (id, _line) = val
731
+
732
+ result = new_attrasgn lhs, id, call_op
673
733
  }
674
734
  | primary_value tCOLON2 tCONSTANT
675
735
  {
676
- expr, _, id = val
736
+ expr, _, (id, _line) = val
677
737
 
678
738
  if (self.in_def || self.in_single > 0) then
679
- debug20 10
739
+ debug 17
680
740
  yyerror "dynamic constant assignment"
681
741
  end
682
742
 
@@ -685,14 +745,13 @@ rule
685
745
  }
686
746
  | tCOLON3 tCONSTANT
687
747
  {
688
- _, id = val
748
+ _, (id, l) = val
689
749
 
690
750
  if (self.in_def || self.in_single > 0) then
691
- debug20 11
751
+ debug 18
692
752
  yyerror "dynamic constant assignment"
693
753
  end
694
754
 
695
- l = lexer.lineno
696
755
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
697
756
  }
698
757
  | backref
@@ -708,16 +767,16 @@ rule
708
767
 
709
768
  cpath: tCOLON3 cname
710
769
  {
711
- _, name = val
712
- result = s(:colon3, name.to_sym).line lexer.lineno
770
+ result = wrap :colon3, val[1]
713
771
  }
714
772
  | cname
715
773
  {
716
- result = val[0].to_sym
774
+ (id, line), = val
775
+ result = [id.to_sym, line] # TODO: sexp?
717
776
  }
718
777
  | primary_value tCOLON2 cname
719
778
  {
720
- pval, _, name = val
779
+ pval, _, (name, _line) = val
721
780
 
722
781
  result = s(:colon2, pval, name.to_sym)
723
782
  result.line pval.line
@@ -727,24 +786,15 @@ rule
727
786
  | op
728
787
  {
729
788
  lexer.lex_state = EXPR_END
730
- result = val[0]
731
789
  }
732
790
 
733
791
  | reswords
734
- {
735
- (sym, _line), = val
736
- lexer.lex_state = EXPR_END
737
- result = sym
738
- }
739
792
 
740
- fsym: fname | symbol
741
-
742
- fitem: fsym
793
+ fitem: fname
743
794
  {
744
- id, = val
745
- result = s(:lit, id.to_sym).line lexer.lineno
795
+ result = wrap :lit, val[0]
746
796
  }
747
- | dsym
797
+ | symbol
748
798
 
749
799
  undef_list: fitem
750
800
  {
@@ -765,10 +815,6 @@ rule
765
815
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
766
816
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
767
817
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
768
- #if V >= 20
769
- # TODO: tUBANG dead?
770
- | tUBANG
771
- #endif
772
818
 
773
819
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
774
820
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -802,26 +848,22 @@ rule
802
848
  }
803
849
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
804
850
  {
805
- lhs, _, id, op, rhs = val
851
+ lhs, _, (id, _line), (op, _), rhs = val
806
852
 
807
853
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
808
854
  }
809
855
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
810
856
  {
811
- lhs1, _, lhs2, op, rhs = val
857
+ lhs1, _, (lhs2, _line), op, rhs = val
812
858
 
813
859
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
814
860
  result = new_const_op_asgn [lhs, op, rhs]
815
861
  }
816
- | tCOLON3 tCONSTANT
817
- {
818
- result = self.lexer.lineno
819
- }
820
- tOP_ASGN arg_rhs
862
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
821
863
  {
822
- _, lhs, line, op, rhs = val
864
+ _, lhs, op, rhs = val
823
865
 
824
- lhs = s(:colon3, lhs.to_sym).line line
866
+ lhs = wrap :colon3, lhs
825
867
  result = new_const_op_asgn [lhs, op, rhs]
826
868
  }
827
869
  | backref tOP_ASGN arg_rhs
@@ -833,7 +875,7 @@ rule
833
875
  | arg tDOT2 arg
834
876
  {
835
877
  v1, v2 = val[0], val[2]
836
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
878
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
837
879
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
838
880
  else
839
881
  result = s(:dot2, v1, v2).line v1.line
@@ -842,7 +884,7 @@ rule
842
884
  | arg tDOT3 arg
843
885
  {
844
886
  v1, v2 = val[0], val[2]
845
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
887
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
846
888
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
847
889
  else
848
890
  result = s(:dot3, v1, v2).line v1.line
@@ -909,20 +951,22 @@ rule
909
951
  #if V == 20
910
952
  | tUMINUS_NUM tINTEGER tPOW arg
911
953
  {
912
- lit = s(:lit, val[1]).line lexer.lineno
913
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
954
+ _, (num, line), _, arg = val
955
+ lit = s(:lit, num).line line
956
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
914
957
  }
915
958
  | tUMINUS_NUM tFLOAT tPOW arg
916
959
  #else
917
960
  | tUMINUS_NUM simple_numeric tPOW arg
918
961
  #endif
919
962
  {
920
- lit = s(:lit, val[1]).line lexer.lineno
921
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
963
+ _, (num, line), _, arg = val
964
+ lit = s(:lit, num).line line
965
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
922
966
 
923
967
  #if V == 20
924
968
  ## TODO: why is this 2.0 only?
925
- debug20 12, val, result
969
+ debug 19
926
970
  #endif
927
971
  }
928
972
  | tUPLUS arg
@@ -1021,12 +1065,12 @@ rule
1021
1065
 
1022
1066
  rel_expr: arg relop arg =tGT
1023
1067
  {
1024
- lhs, op, rhs = val
1068
+ lhs, (op, _), rhs = val
1025
1069
  result = new_call lhs, op.to_sym, argl(rhs)
1026
1070
  }
1027
1071
  | rel_expr relop arg =tGT
1028
1072
  {
1029
- lhs, op, rhs = val
1073
+ lhs, (op, _), rhs = val
1030
1074
  warn "comparison '%s' after comparison", op
1031
1075
  result = new_call lhs, op.to_sym, argl(rhs)
1032
1076
  }
@@ -1239,8 +1283,9 @@ rule
1239
1283
  | backref
1240
1284
  | tFID
1241
1285
  {
1242
- msg, = val
1286
+ (msg, line), = val
1243
1287
  result = new_call nil, msg.to_sym
1288
+ result.line line
1244
1289
  }
1245
1290
  | k_begin
1246
1291
  {
@@ -1282,15 +1327,13 @@ rule
1282
1327
  }
1283
1328
  | primary_value tCOLON2 tCONSTANT
1284
1329
  {
1285
- expr, _, id = val
1330
+ expr, _, (id, _line) = val
1286
1331
 
1287
1332
  result = s(:colon2, expr, id.to_sym).line expr.line
1288
1333
  }
1289
1334
  | tCOLON3 tCONSTANT
1290
1335
  {
1291
- _, id = val
1292
-
1293
- result = s(:colon3, id.to_sym).line lexer.lineno
1336
+ result = wrap :colon3, val[1]
1294
1337
  }
1295
1338
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1296
1339
  {
@@ -1314,15 +1357,21 @@ rule
1314
1357
  }
1315
1358
  | kYIELD tLPAREN2 call_args rparen
1316
1359
  {
1317
- result = new_yield val[2]
1360
+ (_, line), _, args, _ = val
1361
+
1362
+ result = new_yield(args).line line
1318
1363
  }
1319
1364
  | kYIELD tLPAREN2 rparen
1320
1365
  {
1321
- result = new_yield
1366
+ (_, line), _, _ = val
1367
+
1368
+ result = new_yield.line line
1322
1369
  }
1323
1370
  | kYIELD
1324
1371
  {
1325
- result = new_yield
1372
+ (_, line), = val
1373
+
1374
+ result = new_yield.line line
1326
1375
  }
1327
1376
  | kDEFINED opt_nl tLPAREN2 expr rparen
1328
1377
  {
@@ -1337,7 +1386,7 @@ rule
1337
1386
  }
1338
1387
  | kNOT tLPAREN2 rparen
1339
1388
  {
1340
- debug20 14, val, result
1389
+ debug 20
1341
1390
  }
1342
1391
  | fcall brace_block
1343
1392
  {
@@ -1355,9 +1404,10 @@ rule
1355
1404
  iter.insert 1, call # FIX
1356
1405
  result = iter
1357
1406
  }
1358
- | tLAMBDA lambda
1407
+ | lambda
1359
1408
  {
1360
- result = val[1] # TODO: fix lineno
1409
+ expr, = val
1410
+ result = expr
1361
1411
  }
1362
1412
  | k_if expr_value then compstmt if_tail k_end
1363
1413
  {
@@ -1389,6 +1439,14 @@ rule
1389
1439
  (_, line), _, body, _ = val
1390
1440
  result = new_case nil, body, line
1391
1441
  }
1442
+ #if V >= 27
1443
+ | k_case expr_value opt_terms p_case_body k_end
1444
+ {
1445
+ (_, line), expr, _, body, _ = val
1446
+
1447
+ result = new_case expr, body, line
1448
+ }
1449
+ #endif
1392
1450
  | k_for for_var kIN expr_value_do compstmt k_end
1393
1451
  {
1394
1452
  _, var, _, iter, body, _ = val
@@ -1400,7 +1458,6 @@ rule
1400
1458
  }
1401
1459
  cpath superclass
1402
1460
  {
1403
- self.comments.push self.lexer.comments
1404
1461
  if (self.in_def || self.in_single > 0) then
1405
1462
  yyerror "class definition in method body"
1406
1463
  end
@@ -1410,7 +1467,7 @@ rule
1410
1467
  {
1411
1468
  result = new_class val
1412
1469
  self.env.unextend
1413
- self.lexer.comments # we don't care about comments in the body
1470
+ self.lexer.ignore_body_comments
1414
1471
  }
1415
1472
  | k_class tLSHFT
1416
1473
  {
@@ -1431,7 +1488,7 @@ rule
1431
1488
  {
1432
1489
  result = new_sclass val
1433
1490
  self.env.unextend
1434
- self.lexer.comments # we don't care about comments in the body
1491
+ self.lexer.ignore_body_comments
1435
1492
  }
1436
1493
  | k_module
1437
1494
  {
@@ -1439,7 +1496,6 @@ rule
1439
1496
  }
1440
1497
  cpath
1441
1498
  {
1442
- self.comments.push self.lexer.comments
1443
1499
  yyerror "module definition in method body" if
1444
1500
  self.in_def or self.in_single > 0
1445
1501
 
@@ -1449,7 +1505,7 @@ rule
1449
1505
  {
1450
1506
  result = new_module val
1451
1507
  self.env.unextend
1452
- self.lexer.comments # we don't care about comments in the body
1508
+ self.lexer.ignore_body_comments
1453
1509
  }
1454
1510
  | k_def fname
1455
1511
  {
@@ -1459,21 +1515,17 @@ rule
1459
1515
  self.env.extend
1460
1516
  lexer.cmdarg.push false
1461
1517
  lexer.cond.push false
1462
-
1463
- self.comments.push self.lexer.comments
1464
1518
  }
1465
- f_arglist bodystmt { result = lexer.lineno } k_end
1519
+ f_arglist bodystmt k_end
1466
1520
  {
1467
- in_def = val[2]
1468
-
1469
- result = new_defn val
1521
+ result, in_def = new_defn val
1470
1522
 
1471
1523
  lexer.cond.pop # group = local_pop
1472
1524
  lexer.cmdarg.pop
1473
1525
  self.env.unextend
1474
1526
  self.in_def = in_def
1475
1527
 
1476
- self.lexer.comments # we don't care about comments in the body
1528
+ self.lexer.ignore_body_comments
1477
1529
  }
1478
1530
  | k_def singleton dot_or_colon
1479
1531
  {
@@ -1481,7 +1533,7 @@ rule
1481
1533
  }
1482
1534
  fname
1483
1535
  {
1484
- result = [self.in_def, lexer.lineno]
1536
+ result = self.in_def
1485
1537
 
1486
1538
  self.in_single += 1 # TODO: remove?
1487
1539
 
@@ -1491,13 +1543,18 @@ rule
1491
1543
  lexer.cond.push false
1492
1544
 
1493
1545
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1494
- self.comments.push self.lexer.comments
1495
1546
  }
1496
1547
  f_arglist bodystmt k_end
1497
1548
  {
1498
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1499
1549
 
1500
- result = new_defs val
1550
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1551
+ # =>
1552
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1553
+
1554
+ val.delete_at 3
1555
+ val.delete_at 2
1556
+
1557
+ result, in_def = new_defs val
1501
1558
 
1502
1559
  lexer.cond.pop # group = local_pop
1503
1560
  lexer.cmdarg.pop
@@ -1508,7 +1565,7 @@ rule
1508
1565
 
1509
1566
  # TODO: restore cur_arg ? what's cur_arg?
1510
1567
 
1511
- self.lexer.comments # we don't care about comments in the body
1568
+ self.lexer.ignore_body_comments
1512
1569
  }
1513
1570
  | kBREAK
1514
1571
  {
@@ -1545,8 +1602,17 @@ rule
1545
1602
  k_case: kCASE
1546
1603
  k_for: kFOR
1547
1604
  k_class: kCLASS
1605
+ {
1606
+ self.comments.push self.lexer.comments
1607
+ }
1548
1608
  k_module: kMODULE
1609
+ {
1610
+ self.comments.push self.lexer.comments
1611
+ }
1549
1612
  k_def: kDEF
1613
+ {
1614
+ self.comments.push self.lexer.comments
1615
+ }
1550
1616
  k_do: kDO
1551
1617
  k_do_block: kDO_BLOCK
1552
1618
  k_rescue: kRESCUE
@@ -1607,51 +1673,42 @@ rule
1607
1673
 
1608
1674
  result = block_var args
1609
1675
  }
1610
- | f_marg_list tCOMMA tSTAR f_norm_arg
1676
+ | f_marg_list tCOMMA f_rest_marg
1611
1677
  {
1612
- args, _, _, splat = val
1678
+ args, _, rest = val
1613
1679
 
1614
- result = block_var args, "*#{splat}".to_sym
1680
+ result = block_var args, rest
1615
1681
  }
1616
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1682
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1617
1683
  {
1618
- args, _, _, splat, _, args2 = val
1684
+ lhs, _, splat, _, rhs = val
1619
1685
 
1620
- result = block_var args, "*#{splat}".to_sym, args2
1686
+ result = block_var lhs, splat, rhs
1621
1687
  }
1622
- | f_marg_list tCOMMA tSTAR
1688
+ | f_rest_marg
1623
1689
  {
1624
- args, _, _ = val
1690
+ rest, = val
1625
1691
 
1626
- result = block_var args, :*
1692
+ result = block_var rest
1627
1693
  }
1628
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1694
+ | f_rest_marg tCOMMA f_marg_list
1629
1695
  {
1630
- args, _, _, _, args2 = val
1696
+ splat, _, rest = val
1631
1697
 
1632
- result = block_var args, :*, args2
1698
+ result = block_var splat, rest
1633
1699
  }
1634
- | tSTAR f_norm_arg
1635
- {
1636
- _, splat = val
1637
1700
 
1638
- result = block_var :"*#{splat}"
1639
- }
1640
- | tSTAR f_norm_arg tCOMMA f_marg_list
1701
+ f_rest_marg: tSTAR f_norm_arg
1641
1702
  {
1642
- _, splat, _, args = val
1703
+ _, (id, line) = val
1643
1704
 
1644
- result = block_var :"*#{splat}", args
1705
+ result = args ["*#{id}".to_sym]
1706
+ result.line line
1645
1707
  }
1646
1708
  | tSTAR
1647
1709
  {
1648
- result = block_var :*
1649
- }
1650
- | tSTAR tCOMMA f_marg_list
1651
- {
1652
- _, _, args = val
1653
-
1654
- result = block_var :*, args
1710
+ result = args [:*]
1711
+ result.line lexer.lineno # FIX: tSTAR -> line
1655
1712
  }
1656
1713
 
1657
1714
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1666,10 +1723,16 @@ rule
1666
1723
  {
1667
1724
  result = call_args val
1668
1725
  }
1726
+ #if V >= 27
1727
+ | f_no_kwarg opt_f_block_arg
1728
+ {
1729
+ result = args val
1730
+ }
1731
+ #endif
1669
1732
  | f_block_arg
1670
1733
  {
1671
- line = lexer.lineno
1672
- result = call_args val # TODO: push line down
1734
+ (id, line), = val
1735
+ result = call_args [id]
1673
1736
  result.line line
1674
1737
  }
1675
1738
 
@@ -1778,13 +1841,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1778
1841
 
1779
1842
  bvar: tIDENTIFIER
1780
1843
  {
1781
- id, = val
1782
- line = lexer.lineno
1783
- result = s(:shadow, id.to_sym).line line
1844
+ result = wrap :shadow, val[0]
1784
1845
  }
1785
1846
  | f_bad_arg
1786
1847
 
1787
- lambda: {
1848
+ lambda: tLAMBDA
1849
+ {
1788
1850
  self.env.extend :dynamic
1789
1851
  result = [lexer.lineno, lexer.lpar_beg]
1790
1852
  lexer.paren_nest += 1
@@ -1796,14 +1858,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1796
1858
  }
1797
1859
  lambda_body
1798
1860
  {
1799
- (line, lpar), args, _cmdarg, body = val
1861
+ _, (line, lpar), args, _cmdarg, body = val
1800
1862
  lexer.lpar_beg = lpar
1801
1863
 
1802
1864
  lexer.cmdarg.pop
1803
1865
 
1804
1866
  call = s(:lambda).line line
1805
1867
  result = new_iter call, args, body
1806
- result.line = line
1868
+ result.line line
1807
1869
  self.env.unextend # TODO: dynapush & dynapop
1808
1870
  }
1809
1871
 
@@ -1838,23 +1900,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1838
1900
  ## if (nd_type($1) == NODE_YIELD) {
1839
1901
  ## compile_error(PARSER_ARG "block given to yield");
1840
1902
 
1841
- syntax_error "Both block arg and actual block given." if
1842
- val[0].block_pass?
1903
+ cmd, blk = val
1843
1904
 
1844
- val = invert_block_call val if inverted? val
1905
+ syntax_error "Both block arg and actual block given." if
1906
+ cmd.block_pass?
1845
1907
 
1846
- cmd, blk = val
1908
+ if inverted? val then
1909
+ val = invert_block_call val
1910
+ cmd, blk = val
1911
+ end
1847
1912
 
1848
1913
  result = blk
1849
1914
  result.insert 1, cmd
1850
1915
  }
1851
1916
  | block_call call_op2 operation2 opt_paren_args
1852
1917
  {
1853
- result = new_call val[0], val[2].to_sym, val[3]
1918
+ lhs, _, (id, _line), args = val
1919
+
1920
+ result = new_call lhs, id.to_sym, args
1854
1921
  }
1855
1922
  | block_call call_op2 operation2 opt_paren_args brace_block
1856
1923
  {
1857
- iter1, _, name, args, iter2 = val
1924
+ iter1, _, (name, _line), args, iter2 = val
1858
1925
 
1859
1926
  call = new_call iter1, name.to_sym, args
1860
1927
  iter2.insert 1, call
@@ -1863,7 +1930,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1863
1930
  }
1864
1931
  | block_call call_op2 operation2 command_args do_block
1865
1932
  {
1866
- iter1, _, name, args, iter2 = val
1933
+ iter1, _, (name, _line), args, iter2 = val
1867
1934
 
1868
1935
  call = new_call iter1, name.to_sym, args
1869
1936
  iter2.insert 1, call
@@ -1871,28 +1938,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1871
1938
  result = iter2
1872
1939
  }
1873
1940
 
1874
- method_call: fcall
1941
+ method_call: fcall paren_args
1875
1942
  {
1876
- result = self.lexer.lineno
1877
- }
1878
- paren_args
1879
- {
1880
- call, lineno, args = val
1943
+ call, args = val
1881
1944
 
1882
1945
  result = call.concat args.sexp_body if args
1883
- result.line lineno
1884
1946
  }
1885
1947
  | primary_value call_op operation2 opt_paren_args
1886
1948
  {
1887
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1949
+ recv, call_op, (op, _line), args = val
1950
+
1951
+ result = new_call recv, op.to_sym, args, call_op
1888
1952
  }
1889
1953
  | primary_value tCOLON2 operation2 paren_args
1890
1954
  {
1891
- result = new_call val[0], val[2].to_sym, val[3]
1955
+ recv, _, (op, _line), args = val
1956
+
1957
+ result = new_call recv, op.to_sym, args
1892
1958
  }
1893
1959
  | primary_value tCOLON2 operation3
1894
1960
  {
1895
- result = new_call val[0], val[2].to_sym
1961
+ lhs, _, (id, _line) = val
1962
+
1963
+ result = new_call lhs, id.to_sym
1896
1964
  }
1897
1965
  | primary_value call_op paren_args
1898
1966
  {
@@ -1925,7 +1993,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1925
1993
  _, line, body, _ = val
1926
1994
 
1927
1995
  result = body
1928
- result.line = line
1996
+ result.line line
1929
1997
 
1930
1998
  self.env.unextend
1931
1999
  }
@@ -1939,7 +2007,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1939
2007
  _, line, body, _ = val
1940
2008
 
1941
2009
  result = body
1942
- result.line = line
2010
+ result.line line
1943
2011
 
1944
2012
  self.env.unextend
1945
2013
  }
@@ -1972,18 +2040,539 @@ opt_block_args_tail: tCOMMA block_args_tail
1972
2040
  self.env.unextend
1973
2041
  }
1974
2042
 
2043
+ case_args: arg_value
2044
+ {
2045
+ arg, = val
2046
+
2047
+ result = s(:array, arg).line arg.line
2048
+ }
2049
+ | tSTAR arg_value
2050
+ {
2051
+ _, arg = val
2052
+
2053
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2054
+ }
2055
+ | case_args tCOMMA arg_value
2056
+ {
2057
+ args, _, id = val
2058
+
2059
+ result = self.list_append args, id
2060
+ }
2061
+ | case_args tCOMMA tSTAR arg_value
2062
+ {
2063
+ args, _, _, id = val
2064
+
2065
+ result = self.list_append args, s(:splat, id).line(id.line)
2066
+ }
2067
+
1975
2068
  case_body: k_when
1976
2069
  {
1977
2070
  result = self.lexer.lineno
1978
2071
  }
1979
- args then compstmt cases
2072
+ case_args then compstmt cases
1980
2073
  {
1981
2074
  result = new_when(val[2], val[4])
1982
- result.line = val[1]
2075
+ result.line val[1]
1983
2076
  result << val[5] if val[5]
1984
2077
  }
1985
2078
 
1986
2079
  cases: opt_else | case_body
2080
+ #if V >= 27
2081
+ ######################################################################
2082
+
2083
+ p_case_body: kIN
2084
+ {
2085
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2086
+ self.lexer.command_start = false
2087
+ result = self.in_kwarg
2088
+ self.in_kwarg = true
2089
+ push_pvtbl
2090
+ push_pktbl
2091
+ }
2092
+ p_top_expr then
2093
+ {
2094
+ pop_pktbl
2095
+ pop_pvtbl
2096
+ old_kwargs = _values[-3]
2097
+ self.in_kwarg = old_kwargs
2098
+ }
2099
+ compstmt
2100
+ p_cases
2101
+ {
2102
+ (_, line), _, pat, _, _, body, cases = val
2103
+
2104
+ result = new_in pat, body, cases, line
2105
+ }
2106
+
2107
+ p_cases: opt_else
2108
+ | p_case_body
2109
+
2110
+ p_top_expr: p_top_expr_body
2111
+ | p_top_expr_body kIF_MOD expr_value
2112
+ {
2113
+ body, _, cond = val
2114
+ body = remove_begin body
2115
+
2116
+ result = s(:if, cond, body, nil).line body.line
2117
+ }
2118
+ | p_top_expr_body kUNLESS_MOD expr_value
2119
+ {
2120
+ body, _, cond = val
2121
+ body = remove_begin body
2122
+
2123
+ result = s(:if, cond, nil, body).line body.line
2124
+ }
2125
+
2126
+ p_top_expr_body: p_expr
2127
+ | p_expr tCOMMA
2128
+ {
2129
+ expr, _ = val
2130
+
2131
+ tail = new_array_pattern_tail nil, true, nil, nil
2132
+ result = new_array_pattern nil, expr, tail, expr.line
2133
+ }
2134
+ | p_expr tCOMMA p_args
2135
+ {
2136
+ expr, _, args = val
2137
+
2138
+ result = new_array_pattern nil, expr, args, expr.line
2139
+ }
2140
+ | p_args_tail
2141
+ {
2142
+ args, = val
2143
+ result = new_array_pattern nil, nil, args, args.line
2144
+ }
2145
+ | p_kwargs
2146
+ {
2147
+ kwargs, = val
2148
+ result = new_hash_pattern nil, kwargs, kwargs.line
2149
+ }
2150
+
2151
+ p_expr: p_as
2152
+
2153
+ p_as: p_expr tASSOC p_variable
2154
+ {
2155
+ # NODE *n = NEW_LIST($1, &@$);
2156
+ # n = list_append(p, n, $3);
2157
+ # $$ = new_hash(p, n, &@$);
2158
+
2159
+ expr, _, var = val
2160
+
2161
+ id = var.last
2162
+
2163
+ self.env[id] = :lvar # HACK: need to extend env
2164
+ lhs = s(:lasgn, id).line var.line
2165
+
2166
+ result = new_assign lhs, expr
2167
+ }
2168
+ | p_alt
2169
+
2170
+ p_alt: p_alt tPIPE p_expr_basic
2171
+ {
2172
+ lhs, _, rhs = val
2173
+
2174
+ result = s(:or, lhs, rhs).line lhs.line
2175
+ }
2176
+ | p_expr_basic
2177
+
2178
+ p_lparen: tLPAREN2 { push_pktbl }
2179
+ p_lbracket: tLBRACK2 { push_pktbl }
2180
+
2181
+ p_expr_basic: p_value
2182
+ | p_const p_lparen p_args tRPAREN
2183
+ {
2184
+ lhs, _, args, _ = val
2185
+
2186
+ pop_pktbl
2187
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2188
+ }
2189
+ | p_const p_lparen p_kwargs tRPAREN
2190
+ {
2191
+ lhs, _, kwargs, _ = val
2192
+
2193
+ pop_pktbl
2194
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2195
+ }
2196
+ | p_const tLPAREN2 tRPAREN
2197
+ {
2198
+ const, _, _ = val
2199
+
2200
+ tail = new_array_pattern_tail nil, nil, nil, nil
2201
+ result = new_array_pattern const, nil, tail, const.line
2202
+ }
2203
+ | p_const p_lbracket p_args rbracket
2204
+ {
2205
+ const, _, pre_arg, _ = val
2206
+
2207
+ pop_pktbl
2208
+ result = new_array_pattern const, nil, pre_arg, const.line
2209
+ }
2210
+ | p_const p_lbracket p_kwargs rbracket
2211
+ {
2212
+ const, _, kwargs, _ = val
2213
+
2214
+ result = new_hash_pattern const, kwargs, const.line
2215
+ }
2216
+ | p_const tLBRACK2 rbracket
2217
+ {
2218
+ const, _, _ = val
2219
+
2220
+ tail = new_array_pattern_tail nil, nil, nil, nil
2221
+ result = new_array_pattern const, nil, tail, const.line
2222
+ }
2223
+ | tLBRACK { push_pktbl } p_args rbracket
2224
+ {
2225
+ _, _, pat, _ = val
2226
+
2227
+ pop_pktbl
2228
+ result = new_array_pattern nil, nil, pat, pat.line
2229
+ }
2230
+ | tLBRACK rbracket
2231
+ {
2232
+ (_, line), _ = val
2233
+
2234
+ result = s(:array_pat).line line
2235
+ }
2236
+ | tLBRACE
2237
+ {
2238
+ push_pktbl
2239
+ result = self.in_kwarg
2240
+ self.in_kwarg = false
2241
+ }
2242
+ p_kwargs rbrace
2243
+ {
2244
+ _, in_kwarg, kwargs, _ = val
2245
+
2246
+ pop_pktbl
2247
+ self.in_kwarg = in_kwarg
2248
+
2249
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2250
+ }
2251
+ | tLBRACE rbrace
2252
+ {
2253
+ (_, line), _ = val
2254
+
2255
+ tail = new_hash_pattern_tail nil, nil, line
2256
+ result = new_hash_pattern nil, tail, line
2257
+ }
2258
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2259
+ {
2260
+ _, _, expr, _ = val
2261
+
2262
+ pop_pktbl
2263
+ result = expr
2264
+ }
2265
+
2266
+ p_args: p_expr
2267
+ {
2268
+ expr, = val
2269
+
2270
+ ary = s(:array_TAIL, expr).line expr.line
2271
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2272
+ }
2273
+ | p_args_head
2274
+ {
2275
+ head, = val
2276
+
2277
+ result = new_array_pattern_tail head, true, nil, nil
2278
+ }
2279
+ | p_args_head p_arg
2280
+ {
2281
+ head, tail = val
2282
+
2283
+ both = array_pat_concat head, tail
2284
+
2285
+ result = new_array_pattern_tail both, nil, nil, nil
2286
+ result.line head.line
2287
+ }
2288
+ | p_args_head tSTAR tIDENTIFIER
2289
+ {
2290
+ head, _, (id, _line) = val
2291
+
2292
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2293
+ result.line head.line
2294
+ }
2295
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2296
+ {
2297
+ head, _, (id, _line), _, post = val
2298
+
2299
+ result = new_array_pattern_tail head, true, id.to_sym, post
2300
+ result.line head.line
2301
+ }
2302
+ | p_args_head tSTAR
2303
+ {
2304
+ expr, _ = val
2305
+
2306
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2307
+ }
2308
+ | p_args_head tSTAR tCOMMA p_args_post
2309
+ {
2310
+ head, _, _, post = val
2311
+
2312
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2313
+ }
2314
+ | p_args_tail
2315
+
2316
+ p_args_head: p_arg tCOMMA
2317
+ {
2318
+ arg, _ = val
2319
+ result = arg
2320
+ }
2321
+ | p_args_head p_arg tCOMMA
2322
+ {
2323
+ head, tail, _ = val
2324
+
2325
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2326
+ result.line head.line
2327
+ }
2328
+
2329
+ p_args_tail: tSTAR tIDENTIFIER
2330
+ {
2331
+ _, (id, line) = val
2332
+
2333
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2334
+ result.line line
2335
+ }
2336
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2337
+ {
2338
+ _, (id, line), _, rhs = val
2339
+
2340
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2341
+ result.line line
2342
+ }
2343
+ | tSTAR
2344
+ {
2345
+ (_, line), = val
2346
+
2347
+ result = new_array_pattern_tail nil, true, nil, nil
2348
+ result.line line
2349
+ }
2350
+ | tSTAR tCOMMA p_args_post
2351
+ {
2352
+ (_, line), _, args = val
2353
+
2354
+ result = new_array_pattern_tail nil, true, nil, args
2355
+ result.line line
2356
+ }
2357
+
2358
+ p_args_post: p_arg
2359
+ | p_args_post tCOMMA p_arg
2360
+ {
2361
+ lhs, _, rhs = val
2362
+
2363
+ result = array_pat_concat lhs, rhs
2364
+ }
2365
+
2366
+ p_arg: p_expr
2367
+ {
2368
+ expr, = val
2369
+ expr = s(:array_TAIL, expr).line expr.line unless
2370
+ expr.sexp_type == :array_TAIL
2371
+ result = expr
2372
+ }
2373
+
2374
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2375
+ {
2376
+ kw_arg, _, rest = val
2377
+ # TODO? new_unique_key_hash(p, $1, &@$)
2378
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2379
+ }
2380
+ | p_kwarg
2381
+ {
2382
+ kwarg, = val
2383
+ # TODO? new_unique_key_hash(p, $1, &@$)
2384
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2385
+ }
2386
+ | p_kwarg tCOMMA
2387
+ {
2388
+ kwarg, _ = val
2389
+ # TODO? new_unique_key_hash(p, $1, &@$)
2390
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2391
+ }
2392
+ | p_kwrest
2393
+ {
2394
+ rest, = val
2395
+
2396
+ result = new_hash_pattern_tail nil, rest, rest.line
2397
+ }
2398
+ | p_kwarg tCOMMA p_kwnorest
2399
+ {
2400
+ kwarg, _, norest = val
2401
+
2402
+ # TODO? new_unique_key_hash(p, $1, &@$)
2403
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2404
+ }
2405
+ | p_kwnorest
2406
+ {
2407
+ norest, = val
2408
+
2409
+ result = new_hash_pattern_tail nil, norest, norest.line
2410
+ }
2411
+
2412
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2413
+ | p_kwarg tCOMMA p_kw
2414
+ {
2415
+ kwarg, _, kw = val
2416
+ kwarg.concat kw.sexp_body
2417
+ result = kwarg
2418
+ }
2419
+
2420
+ p_kw: p_kw_label p_expr
2421
+ {
2422
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2423
+ lhs, rhs = val
2424
+
2425
+ result = s(:PAIR, lhs, rhs).line lhs.line
2426
+ }
2427
+ | p_kw_label
2428
+ {
2429
+ lhs, = val
2430
+
2431
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2432
+
2433
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2434
+ # yyerror1(&@1, "key must be valid as local variables");
2435
+ # }
2436
+
2437
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2438
+ # assignable(p, $1, 0, &@$));
2439
+
2440
+
2441
+ case lhs.sexp_type
2442
+ when :lit then
2443
+ assignable [lhs.value, lhs.line]
2444
+ else
2445
+ # TODO or done?
2446
+ debug 666
2447
+ end
2448
+
2449
+ # TODO PAIR -> LIST ?
2450
+ result = s(:PAIR, lhs, nil).line lhs.line
2451
+ }
2452
+
2453
+ p_kw_label: tLABEL
2454
+ {
2455
+ result = wrap :lit, val[0]
2456
+ }
2457
+
2458
+ p_kwrest: kwrest_mark tIDENTIFIER
2459
+ {
2460
+ _, (id, line) = val
2461
+
2462
+ name = id.to_sym
2463
+ self.assignable [name, line]
2464
+ result = s(:kwrest, :"**#{name}").line line
2465
+ }
2466
+ | kwrest_mark
2467
+ {
2468
+ (_, line), = val
2469
+
2470
+ result = s(:kwrest, :"**").line line
2471
+ }
2472
+
2473
+ p_kwnorest: kwrest_mark kNIL
2474
+ {
2475
+ (_, line), _ = val
2476
+
2477
+ # TODO: or s(:norest)? s(:**nil)?
2478
+ result = s(:kwrest, :"**nil").line line
2479
+ }
2480
+
2481
+ p_value: p_primitive
2482
+ | p_primitive tDOT2 p_primitive
2483
+ {
2484
+ lhs, _, rhs = val
2485
+
2486
+ lhs = value_expr lhs
2487
+ rhs = value_expr rhs
2488
+
2489
+ result = s(:dot2, lhs, rhs).line lhs.line
2490
+ }
2491
+ | p_primitive tDOT3 p_primitive
2492
+ {
2493
+ lhs, _, rhs = val
2494
+
2495
+ lhs = value_expr lhs
2496
+ rhs = value_expr rhs
2497
+
2498
+ result = s(:dot3, lhs, rhs).line lhs.line
2499
+ }
2500
+ | p_primitive tDOT2
2501
+ {
2502
+ v1, _ = val
2503
+
2504
+ result = s(:dot2, v1, nil).line v1.line
2505
+ }
2506
+ | p_primitive tDOT3
2507
+ {
2508
+ v1, _ = val
2509
+
2510
+ result = s(:dot3, v1, nil).line v1.line
2511
+ }
2512
+ | p_variable
2513
+ | p_var_ref
2514
+ | p_const
2515
+ | tBDOT2 p_primitive
2516
+ {
2517
+ _, v1 = val
2518
+
2519
+ result = s(:dot2, nil, v1).line v1.line
2520
+ }
2521
+ | tBDOT3 p_primitive
2522
+ {
2523
+ _, v1 = val
2524
+
2525
+ result = s(:dot3, nil, v1).line v1.line
2526
+ }
2527
+
2528
+ p_primitive: literal
2529
+ | strings
2530
+ | xstring
2531
+ | regexp
2532
+ | words
2533
+ | qwords
2534
+ | symbols
2535
+ | qsymbols
2536
+ | keyword_variable
2537
+ {
2538
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2539
+ var, = val
2540
+
2541
+ result = var
2542
+ }
2543
+ | lambda
2544
+
2545
+ p_variable: tIDENTIFIER
2546
+ {
2547
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2548
+ # TODO: assignable(p, $1, 0, &@$);
2549
+ result = wrap :lvar, val[0]
2550
+ }
2551
+
2552
+ p_var_ref: tCARET tIDENTIFIER
2553
+ {
2554
+ # TODO: check id against env for lvar or dvar
2555
+ result = wrap :lvar, val[1]
2556
+ }
2557
+
2558
+ p_const: tCOLON3 cname
2559
+ {
2560
+ result = wrap :colon3, val[1]
2561
+ }
2562
+ | p_const tCOLON2 cname
2563
+ {
2564
+ lhs, _, (id, _line) = val
2565
+
2566
+ l = lhs.line
2567
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2568
+ }
2569
+ | tCONSTANT
2570
+ {
2571
+ # TODO $$ = gettable(p, $1, &@$);
2572
+ result = wrap :const, val[0]
2573
+ }
2574
+ ######################################################################
2575
+ #endif
1987
2576
 
1988
2577
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1989
2578
  {
@@ -2025,17 +2614,10 @@ opt_block_args_tail: tCOMMA block_args_tail
2025
2614
 
2026
2615
  literal: numeric
2027
2616
  {
2028
- line = lexer.lineno
2029
- result = s(:lit, val[0])
2030
- result.line = line
2617
+ (lit, line), = val
2618
+ result = s(:lit, lit).line line
2031
2619
  }
2032
2620
  | symbol
2033
- {
2034
- line = lexer.lineno
2035
- result = s(:lit, val[0])
2036
- result.line = line
2037
- }
2038
- | dsym
2039
2621
 
2040
2622
  strings: string
2041
2623
  {
@@ -2046,7 +2628,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2046
2628
 
2047
2629
  string: tCHAR
2048
2630
  {
2049
- debug20 23, val, result
2631
+ debug 37
2050
2632
  }
2051
2633
  | string1
2052
2634
  | string string1
@@ -2056,11 +2638,11 @@ opt_block_args_tail: tCOMMA block_args_tail
2056
2638
 
2057
2639
  string1: tSTRING_BEG string_contents tSTRING_END
2058
2640
  {
2059
- _, str, (_, func) = val
2641
+ (_, line), str, (_, func) = val
2060
2642
 
2061
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2643
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2062
2644
 
2063
- result = str
2645
+ result = str.line line
2064
2646
  }
2065
2647
  | tSTRING
2066
2648
  {
@@ -2080,11 +2662,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2080
2662
 
2081
2663
  words: tWORDS_BEG tSPACE tSTRING_END
2082
2664
  {
2083
- result = s(:array).line lexer.lineno
2665
+ (_, line), _, _ = val
2666
+
2667
+ result = s(:array).line line
2084
2668
  }
2085
2669
  | tWORDS_BEG word_list tSTRING_END
2086
2670
  {
2087
- result = val[1]
2671
+ (_, line), list, _ = val
2672
+
2673
+ result = list.line line
2088
2674
  }
2089
2675
 
2090
2676
  word_list: none
@@ -2104,18 +2690,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2104
2690
 
2105
2691
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2106
2692
  {
2107
- result = s(:array).line lexer.lineno
2693
+ (_, line), _, _ = val
2694
+
2695
+ result = s(:array).line line
2108
2696
  }
2109
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2697
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2110
2698
  {
2111
- _, line, list, _, = val
2112
- list.line = line
2699
+ (_, line), list, _, = val
2700
+ list.line line
2113
2701
  result = list
2114
2702
  }
2115
2703
 
2116
2704
  symbol_list: none
2117
2705
  {
2118
- result = new_symbol_list.line lexer.lineno
2706
+ result = new_symbol_list
2119
2707
  }
2120
2708
  | symbol_list word tSPACE
2121
2709
  {
@@ -2125,20 +2713,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2125
2713
 
2126
2714
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2127
2715
  {
2128
- result = s(:array).line lexer.lineno
2716
+ (_, line), _, _ = val
2717
+
2718
+ result = s(:array).line line
2129
2719
  }
2130
2720
  | tQWORDS_BEG qword_list tSTRING_END
2131
2721
  {
2132
- result = val[1]
2722
+ (_, line), list, _ = val
2723
+
2724
+ result = list.line line
2133
2725
  }
2134
2726
 
2135
2727
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2136
2728
  {
2137
- result = s(:array).line lexer.lineno # FIX
2729
+ (_, line), _, _ = val
2730
+
2731
+ result = s(:array).line line
2138
2732
  }
2139
2733
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2140
2734
  {
2141
- result = val[1]
2735
+ (_, line), list, _ = val
2736
+
2737
+ result = list.line line
2142
2738
  }
2143
2739
 
2144
2740
  qword_list: none
@@ -2161,7 +2757,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2161
2757
 
2162
2758
  string_contents: none
2163
2759
  {
2164
- result = s(:str, "").line lexer.lineno
2760
+ line = prev_value_to_lineno _values.last
2761
+ result = s(:str, +"").line line
2165
2762
  }
2166
2763
  | string_contents string_content
2167
2764
  {
@@ -2236,8 +2833,8 @@ regexp_contents: none
2236
2833
  lexer.brace_nest = brace_nest
2237
2834
  lexer.string_nest = string_nest
2238
2835
 
2239
- lexer.cmdarg.pop
2240
2836
  lexer.cond.pop
2837
+ lexer.cmdarg.pop
2241
2838
 
2242
2839
  lexer.lex_state = oldlex_state
2243
2840
 
@@ -2252,29 +2849,42 @@ regexp_contents: none
2252
2849
  when nil then
2253
2850
  result = s(:evstr).line line
2254
2851
  else
2255
- debug20 25
2852
+ debug 38
2256
2853
  raise "unknown string body: #{stmt.inspect}"
2257
2854
  end
2258
2855
  }
2259
2856
 
2260
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2261
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2262
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2857
+ string_dvar: tGVAR
2858
+ {
2859
+ result = wrap :gvar, val[0]
2860
+ }
2861
+ | tIVAR
2862
+ {
2863
+ result = wrap :ivar, val[0]
2864
+ }
2865
+ | tCVAR
2866
+ {
2867
+ result = wrap :cvar, val[0]
2868
+ }
2263
2869
  | backref
2264
2870
 
2265
- symbol: tSYMBEG sym
2871
+ symbol: ssym
2872
+ | dsym
2873
+
2874
+ ssym: tSYMBEG sym
2266
2875
  {
2267
2876
  lexer.lex_state = EXPR_END
2268
- result = val[1].to_sym
2877
+ result = wrap :lit, val[1]
2269
2878
  }
2270
2879
  | tSYMBOL
2271
2880
  {
2272
- result = val[0].to_sym
2881
+ lexer.lex_state = EXPR_END
2882
+ result = wrap :lit, val[0]
2273
2883
  }
2274
2884
 
2275
2885
  sym: fname | tIVAR | tGVAR | tCVAR
2276
2886
 
2277
- dsym: tSYMBEG xstring_contents tSTRING_END
2887
+ dsym: tSYMBEG string_contents tSTRING_END
2278
2888
  {
2279
2889
  _, result, _ = val
2280
2890
 
@@ -2290,7 +2900,7 @@ regexp_contents: none
2290
2900
  when :evstr then
2291
2901
  result = s(:dsym, "", result).line result.line
2292
2902
  else
2293
- debug20 26, val, result
2903
+ debug 39
2294
2904
  end
2295
2905
  }
2296
2906
 
@@ -2300,15 +2910,17 @@ regexp_contents: none
2300
2910
  | tUMINUS_NUM tINTEGER =tLOWEST
2301
2911
  #else
2302
2912
  numeric: simple_numeric
2303
- | tUMINUS_NUM simple_numeric
2913
+ | tUMINUS_NUM simple_numeric =tLOWEST
2304
2914
  #endif
2305
2915
  {
2306
- result = -val[1] # TODO: pt_testcase
2916
+ _, (num, line) = val
2917
+ result = [-num, line]
2307
2918
  #if V == 20
2308
2919
  }
2309
2920
  | tUMINUS_NUM tFLOAT =tLOWEST
2310
2921
  {
2311
- result = -val[1] # TODO: pt_testcase
2922
+ _, (num, line) = val
2923
+ result = [-num, line]
2312
2924
  #endif
2313
2925
  }
2314
2926
 
@@ -2344,8 +2956,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
2956
 
2345
2957
  var_ref: user_variable
2346
2958
  {
2347
- var = val[0]
2959
+ raise "NO: #{val.inspect}" if Sexp === val.first
2960
+ (var, line), = val
2348
2961
  result = Sexp === var ? var : self.gettable(var)
2962
+ result.line line
2349
2963
  }
2350
2964
  | keyword_variable
2351
2965
  {
@@ -2360,11 +2974,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2360
2974
  | keyword_variable
2361
2975
  {
2362
2976
  result = self.assignable val[0]
2363
- debug20 29, val, result
2977
+ debug 40
2364
2978
  }
2365
2979
 
2366
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2367
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2980
+ backref: tNTH_REF
2981
+ {
2982
+ (ref, line), = val
2983
+ result = s(:nth_ref, ref).line line
2984
+ }
2985
+ | tBACK_REF
2986
+ {
2987
+ (ref, line), = val
2988
+ result = s(:back_ref, ref).line line
2989
+ }
2368
2990
 
2369
2991
  superclass: tLT
2370
2992
  {
@@ -2382,24 +3004,16 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2382
3004
 
2383
3005
  f_arglist: tLPAREN2 f_args rparen
2384
3006
  {
2385
- result = val[1]
2386
- self.lexer.lex_state = EXPR_BEG
2387
- self.lexer.command_start = true
3007
+ result = end_args val
2388
3008
  }
2389
- #if V >= 27
3009
+ #if V == 27
2390
3010
  | tLPAREN2 f_arg tCOMMA args_forward rparen
2391
3011
  {
2392
- result = args val
2393
-
2394
- self.lexer.lex_state = EXPR_BEG
2395
- self.lexer.command_start = true
3012
+ result = end_args val
2396
3013
  }
2397
3014
  | tLPAREN2 args_forward rparen
2398
3015
  {
2399
- result = args val
2400
-
2401
- self.lexer.lex_state = EXPR_BEG
2402
- self.lexer.command_start = true
3016
+ result = end_args val
2403
3017
  }
2404
3018
  #endif
2405
3019
  | {
@@ -2409,12 +3023,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2409
3023
  }
2410
3024
  f_args term
2411
3025
  {
2412
- kwarg, args, _ = val
2413
-
2414
- self.in_kwarg = kwarg
2415
- result = args
2416
- lexer.lex_state = EXPR_BEG
2417
- lexer.command_start = true
3026
+ result = end_args val
2418
3027
  }
2419
3028
 
2420
3029
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2429,6 +3038,12 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2429
3038
  {
2430
3039
  result = args val
2431
3040
  }
3041
+ #if V >= 27
3042
+ | f_no_kwarg opt_f_block_arg
3043
+ {
3044
+ result = args val
3045
+ }
3046
+ #endif
2432
3047
  | f_block_arg
2433
3048
 
2434
3049
  opt_args_tail: tCOMMA args_tail
@@ -2499,6 +3114,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2499
3114
  |
2500
3115
  {
2501
3116
  result = args val
3117
+ # result.line lexer.lineno
2502
3118
  }
2503
3119
 
2504
3120
  #if V >= 27
@@ -2528,10 +3144,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2528
3144
  f_norm_arg: f_bad_arg
2529
3145
  | tIDENTIFIER
2530
3146
  {
2531
- identifier = val[0].to_sym
3147
+ (id, line), = val
3148
+ identifier = id.to_sym
2532
3149
  self.env[identifier] = :lvar
2533
3150
 
2534
- result = identifier
3151
+ result = [identifier, line]
2535
3152
  }
2536
3153
 
2537
3154
  #if V >= 22
@@ -2540,29 +3157,23 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2540
3157
  f_arg_item: f_arg_asgn
2541
3158
  | tLPAREN f_margs rparen
2542
3159
  {
2543
- result = val[1]
3160
+ _, margs, _ = val
3161
+
3162
+ result = margs
2544
3163
  }
2545
3164
  #else
2546
3165
  f_arg_item: f_norm_arg
2547
3166
  | tLPAREN f_margs rparen
2548
3167
  {
2549
- result = val[1]
3168
+ _, margs, _ = val
3169
+
3170
+ result = margs
2550
3171
  }
2551
3172
  #endif
2552
3173
 
2553
3174
  f_arg: f_arg_item
2554
3175
  {
2555
- arg, = val
2556
-
2557
- case arg
2558
- when Symbol then
2559
- result = s(:args, arg).line lexer.lineno
2560
- when Sexp then
2561
- result = arg
2562
- else
2563
- debug20 32
2564
- raise "Unknown f_arg type: #{val.inspect}"
2565
- end
3176
+ result = new_arg val
2566
3177
  }
2567
3178
  | f_arg tCOMMA f_arg_item
2568
3179
  {
@@ -2574,7 +3185,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2574
3185
  result = s(:args, list).line list.line
2575
3186
  end
2576
3187
 
2577
- result << item
3188
+ result << (Sexp === item ? item : item.first)
2578
3189
  }
2579
3190
 
2580
3191
  #if V == 20
@@ -2647,16 +3258,26 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2647
3258
  kwrest_mark: tPOW
2648
3259
  | tDSTAR
2649
3260
 
3261
+ #if V >= 27
3262
+ f_no_kwarg: kwrest_mark kNIL
3263
+ {
3264
+ result = :"**nil"
3265
+ }
3266
+ #endif
3267
+
2650
3268
  f_kwrest: kwrest_mark tIDENTIFIER
2651
3269
  {
2652
- name = val[1].to_sym
2653
- self.assignable name
2654
- result = :"**#{name}"
3270
+ _, (id, line) = val
3271
+
3272
+ name = id.to_sym
3273
+ self.assignable [name, line]
3274
+ result = [:"**#{name}", line]
2655
3275
  }
2656
3276
  | kwrest_mark
2657
3277
  {
2658
- result = :"**"
2659
- self.env[result] = :lvar
3278
+ id = :"**"
3279
+ self.env[id] = :lvar # TODO: needed?!?
3280
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2660
3281
  }
2661
3282
 
2662
3283
  #if V == 20
@@ -2667,7 +3288,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2667
3288
  f_opt: f_arg_asgn tEQL arg_value
2668
3289
  #endif
2669
3290
  {
2670
- result = self.assignable val[0], val[2]
3291
+ lhs, _, rhs = val
3292
+ result = self.assignable lhs, rhs
2671
3293
  # TODO: detect duplicate names
2672
3294
  }
2673
3295
 
@@ -2679,7 +3301,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2679
3301
  f_block_opt: f_arg_asgn tEQL primary_value
2680
3302
  #endif
2681
3303
  {
2682
- result = self.assignable val[0], val[2]
3304
+ lhs, _, rhs = val
3305
+ result = self.assignable lhs, rhs
2683
3306
  }
2684
3307
 
2685
3308
  f_block_optarg: f_block_opt
@@ -2709,30 +3332,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2709
3332
  f_rest_arg: restarg_mark tIDENTIFIER
2710
3333
  {
2711
3334
  # TODO: differs from parse.y - needs tests
2712
- name = val[1].to_sym
2713
- self.assignable name
2714
- result = :"*#{name}"
3335
+ _, (id, line) = val
3336
+ name = id.to_sym
3337
+ self.assignable [name, line]
3338
+ result = [:"*#{name}", line]
2715
3339
  }
2716
3340
  | restarg_mark
2717
3341
  {
2718
3342
  name = :"*"
2719
3343
  self.env[name] = :lvar
2720
- result = name
3344
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2721
3345
  }
2722
3346
 
2723
3347
  blkarg_mark: tAMPER2 | tAMPER
2724
3348
 
2725
3349
  f_block_arg: blkarg_mark tIDENTIFIER
2726
3350
  {
2727
- identifier = val[1].to_sym
3351
+ _, (id, line) = val
3352
+ identifier = id.to_sym
2728
3353
 
2729
3354
  self.env[identifier] = :lvar
2730
- result = "&#{identifier}".to_sym
3355
+ result = ["&#{identifier}".to_sym, line]
2731
3356
  }
2732
3357
 
2733
3358
  opt_f_block_arg: tCOMMA f_block_arg
2734
3359
  {
2735
- result = val[1]
3360
+ _, arg = val
3361
+ result = arg
2736
3362
  }
2737
3363
  |
2738
3364
  {
@@ -2774,17 +3400,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2774
3400
  }
2775
3401
  | tLABEL arg_value
2776
3402
  {
2777
- (label, line), arg = val
3403
+ label, arg = val
2778
3404
 
2779
- lit = s(:lit, label.to_sym).line line
2780
- result = s(:array, lit, arg).line line
3405
+ lit = wrap :lit, label
3406
+ result = s(:array, lit, arg).line lit.line
2781
3407
  }
2782
3408
  #if V >= 22
2783
3409
  | tSTRING_BEG string_contents tLABEL_END arg_value
2784
3410
  {
2785
- _, sym, _, value = val
3411
+ (_, line), sym, _, value = val
3412
+
2786
3413
  sym.sexp_type = :dsym
2787
- result = s(:array, sym, value).line sym.line
3414
+
3415
+ result = s(:array, sym, value).line line
2788
3416
  }
2789
3417
  #endif
2790
3418
  | tDSTAR arg_value
@@ -2810,6 +3438,9 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2810
3438
  opt_nl: | tNL
2811
3439
  rparen: opt_nl tRPAREN
2812
3440
  rbracket: opt_nl tRBRACK
3441
+ #if V >= 27
3442
+ rbrace: opt_nl tRCURLY
3443
+ #endif
2813
3444
  trailer: | tNL | tCOMMA
2814
3445
 
2815
3446
  term: tSEMI { yyerrok }