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/ruby27_parser.y CHANGED
@@ -18,7 +18,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
@@ -80,7 +80,7 @@ rule
80
80
  | klBEGIN
81
81
  {
82
82
  if (self.in_def || self.in_single > 0) then
83
- debug20 1
83
+ debug 11
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -105,6 +105,8 @@ rule
105
105
  bodystmt: compstmt opt_rescue k_else
106
106
  {
107
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
108
110
  yyerror "else without rescue is useless" unless res
109
111
  }
110
112
  compstmt
@@ -135,7 +137,7 @@ rule
135
137
  | error stmt
136
138
  {
137
139
  result = val[1]
138
- debug20 2, val, result
140
+ debug 12
139
141
  }
140
142
 
141
143
  stmt_or_begin: stmt
@@ -143,6 +145,10 @@ rule
143
145
  {
144
146
  yyerror "BEGIN is permitted only at toplevel"
145
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
146
152
 
147
153
  stmt: kALIAS fitem
148
154
  {
@@ -155,12 +161,12 @@ rule
155
161
  }
156
162
  | kALIAS tGVAR tGVAR
157
163
  {
158
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
159
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
166
  }
161
167
  | kALIAS tGVAR tBACK_REF
162
168
  {
163
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
164
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
171
  }
166
172
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +209,7 @@ rule
203
209
  (_, line), _, stmt, _ = val
204
210
 
205
211
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
212
+ debug 13
207
213
  yyerror "END in method; use at_exit"
208
214
  end
209
215
 
@@ -219,6 +225,15 @@ rule
219
225
  lhs, _, rhs = val
220
226
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
221
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
+ }
222
237
  | mlhs tEQL mrhs_arg
223
238
  {
224
239
  result = new_masgn val[0], val[2]
@@ -243,32 +258,31 @@ rule
243
258
  }
244
259
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
260
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- 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
252
266
  }
253
267
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
268
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- 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
260
274
  }
261
275
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
276
  {
263
- lhs1, _, lhs2, op, rhs = val
277
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
278
 
265
- 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
266
280
  }
267
281
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
282
  {
269
- lhs1, _, lhs2, op, rhs = val
283
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
284
 
271
- 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
272
286
  }
273
287
  | backref tOP_ASGN command_rhs
274
288
  {
@@ -315,6 +329,28 @@ rule
315
329
  # REFACTOR: call_uni_op -- see parse26.y
316
330
  }
317
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
318
354
 
319
355
  expr_value: expr
320
356
  {
@@ -339,7 +375,7 @@ rule
339
375
  block_command: block_call
340
376
  | block_call call_op2 operation2 command_args
341
377
  {
342
- blk, _, msg, args = val
378
+ blk, _, (msg, _line), args = val
343
379
  result = new_call(blk, msg.to_sym, args).line blk.line
344
380
  }
345
381
 
@@ -353,15 +389,15 @@ rule
353
389
  _, line, body, _ = val
354
390
 
355
391
  result = body
356
- result.line = line
392
+ result.line line
357
393
 
358
394
  # self.env.unextend
359
395
  }
360
396
 
361
397
  fcall: operation
362
398
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
399
+ (msg, line), = val
400
+ result = new_call(nil, msg.to_sym).line line
365
401
  }
366
402
 
367
403
  command: fcall command_args =tLOWEST
@@ -384,12 +420,14 @@ rule
384
420
  }
385
421
  | primary_value call_op operation2 command_args =tLOWEST
386
422
  {
387
- lhs, callop, op, args = val
423
+ lhs, callop, (op, _), args = val
424
+
388
425
  result = new_call lhs, op.to_sym, args, callop
426
+ result.line lhs.line
389
427
  }
390
428
  | primary_value call_op operation2 command_args cmd_brace_block
391
429
  {
392
- recv, _, msg, args, block = val
430
+ recv, _, (msg, _line), args, block = val
393
431
  call = new_call recv, msg.to_sym, args, val[1]
394
432
 
395
433
  block_dup_check call, block
@@ -399,11 +437,14 @@ rule
399
437
  }
400
438
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
439
  {
402
- 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
403
444
  }
404
445
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
446
  {
406
- recv, _, msg, args, block = val
447
+ recv, _, (msg, _line), args, block = val
407
448
  call = new_call recv, msg.to_sym, args
408
449
 
409
450
  block_dup_check call, block
@@ -561,25 +602,29 @@ rule
561
602
  }
562
603
  | primary_value call_op tIDENTIFIER
563
604
  {
564
- 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
565
608
  }
566
609
  | primary_value tCOLON2 tIDENTIFIER
567
610
  {
568
- recv, _, id = val
611
+ recv, _, (id, _line) = val
569
612
  result = new_attrasgn recv, id
570
613
  }
571
614
  | primary_value call_op tCONSTANT
572
615
  {
573
- 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
574
619
  }
575
620
  | primary_value tCOLON2 tCONSTANT
576
621
  {
577
622
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
623
+ debug 14
579
624
  yyerror "dynamic constant assignment"
580
625
  end
581
626
 
582
- expr, _, id = val
627
+ expr, _, (id, _line) = val
583
628
  l = expr.line
584
629
 
585
630
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +632,65 @@ rule
587
632
  | tCOLON3 tCONSTANT
588
633
  {
589
634
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
635
+ debug 15
591
636
  yyerror "dynamic constant assignment"
592
637
  end
593
638
 
594
- _, id = val
595
- l = lexer.lineno
639
+ _, (id, l) = val
596
640
 
597
641
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
642
  }
599
643
  | backref
600
644
  {
601
- self.backref_assign_error val[0]
645
+ ref, = val
646
+
647
+ self.backref_assign_error ref
602
648
  }
603
649
 
604
650
  lhs: user_variable
605
651
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
652
+ var, = val
653
+
654
+ result = self.assignable var
609
655
  }
610
656
  | keyword_variable
611
657
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
658
+ var, = val
659
+
660
+ result = self.assignable var
661
+
662
+ debug 16
616
663
  }
617
664
  | primary_value tLBRACK2 opt_call_args rbracket
618
665
  {
619
666
  lhs, _, args, _ = val
667
+
620
668
  result = self.aryset lhs, args
621
669
  }
622
670
  | primary_value call_op tIDENTIFIER # REFACTOR
623
671
  {
624
- lhs, op, id = val
672
+ lhs, op, (id, _line) = val
673
+
625
674
  result = new_attrasgn lhs, id, op
626
675
  }
627
676
  | primary_value tCOLON2 tIDENTIFIER
628
677
  {
629
- lhs, _, id = val
678
+ lhs, _, (id, _line) = val
679
+
630
680
  result = new_attrasgn lhs, id
631
681
  }
632
682
  | primary_value call_op tCONSTANT # REFACTOR?
633
683
  {
634
- 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
635
687
  }
636
688
  | primary_value tCOLON2 tCONSTANT
637
689
  {
638
- expr, _, id = val
690
+ expr, _, (id, _line) = val
639
691
 
640
692
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
693
+ debug 17
642
694
  yyerror "dynamic constant assignment"
643
695
  end
644
696
 
@@ -647,14 +699,13 @@ rule
647
699
  }
648
700
  | tCOLON3 tCONSTANT
649
701
  {
650
- _, id = val
702
+ _, (id, l) = val
651
703
 
652
704
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
705
+ debug 18
654
706
  yyerror "dynamic constant assignment"
655
707
  end
656
708
 
657
- l = lexer.lineno
658
709
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
710
  }
660
711
  | backref
@@ -670,16 +721,16 @@ rule
670
721
 
671
722
  cpath: tCOLON3 cname
672
723
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
724
+ result = wrap :colon3, val[1]
675
725
  }
676
726
  | cname
677
727
  {
678
- result = val[0].to_sym
728
+ (id, line), = val
729
+ result = [id.to_sym, line] # TODO: sexp?
679
730
  }
680
731
  | primary_value tCOLON2 cname
681
732
  {
682
- pval, _, name = val
733
+ pval, _, (name, _line) = val
683
734
 
684
735
  result = s(:colon2, pval, name.to_sym)
685
736
  result.line pval.line
@@ -689,24 +740,15 @@ rule
689
740
  | op
690
741
  {
691
742
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
743
  }
694
744
 
695
745
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
746
 
704
- fitem: fsym
747
+ fitem: fname
705
748
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
749
+ result = wrap :lit, val[0]
708
750
  }
709
- | dsym
751
+ | symbol
710
752
 
711
753
  undef_list: fitem
712
754
  {
@@ -727,8 +769,6 @@ rule
727
769
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
770
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
771
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
772
 
733
773
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
774
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,26 +802,22 @@ rule
762
802
  }
763
803
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
804
  {
765
- lhs, _, id, op, rhs = val
805
+ lhs, _, (id, _line), (op, _), rhs = val
766
806
 
767
807
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
808
  }
769
809
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
810
  {
771
- lhs1, _, lhs2, op, rhs = val
811
+ lhs1, _, (lhs2, _line), op, rhs = val
772
812
 
773
813
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
814
  result = new_const_op_asgn [lhs, op, rhs]
775
815
  }
776
- | tCOLON3 tCONSTANT
816
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
777
817
  {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
781
- {
782
- _, lhs, line, op, rhs = val
818
+ _, lhs, op, rhs = val
783
819
 
784
- lhs = s(:colon3, lhs.to_sym).line line
820
+ lhs = wrap :colon3, lhs
785
821
  result = new_const_op_asgn [lhs, op, rhs]
786
822
  }
787
823
  | backref tOP_ASGN arg_rhs
@@ -793,7 +829,7 @@ rule
793
829
  | arg tDOT2 arg
794
830
  {
795
831
  v1, v2 = val[0], val[2]
796
- 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
797
833
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
834
  else
799
835
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +838,7 @@ rule
802
838
  | arg tDOT3 arg
803
839
  {
804
840
  v1, v2 = val[0], val[2]
805
- 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
806
842
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
843
  else
808
844
  result = s(:dot3, v1, v2).line v1.line
@@ -864,8 +900,9 @@ rule
864
900
  }
865
901
  | tUMINUS_NUM simple_numeric tPOW arg
866
902
  {
867
- lit = s(:lit, val[1]).line lexer.lineno
868
- 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)), :"-@")
869
906
 
870
907
  }
871
908
  | tUPLUS arg
@@ -964,12 +1001,12 @@ rule
964
1001
 
965
1002
  rel_expr: arg relop arg =tGT
966
1003
  {
967
- lhs, op, rhs = val
1004
+ lhs, (op, _), rhs = val
968
1005
  result = new_call lhs, op.to_sym, argl(rhs)
969
1006
  }
970
1007
  | rel_expr relop arg =tGT
971
1008
  {
972
- lhs, op, rhs = val
1009
+ lhs, (op, _), rhs = val
973
1010
  warn "comparison '%s' after comparison", op
974
1011
  result = new_call lhs, op.to_sym, argl(rhs)
975
1012
  }
@@ -1178,8 +1215,9 @@ rule
1178
1215
  | backref
1179
1216
  | tFID
1180
1217
  {
1181
- msg, = val
1218
+ (msg, line), = val
1182
1219
  result = new_call nil, msg.to_sym
1220
+ result.line line
1183
1221
  }
1184
1222
  | k_begin
1185
1223
  {
@@ -1221,15 +1259,13 @@ rule
1221
1259
  }
1222
1260
  | primary_value tCOLON2 tCONSTANT
1223
1261
  {
1224
- expr, _, id = val
1262
+ expr, _, (id, _line) = val
1225
1263
 
1226
1264
  result = s(:colon2, expr, id.to_sym).line expr.line
1227
1265
  }
1228
1266
  | tCOLON3 tCONSTANT
1229
1267
  {
1230
- _, id = val
1231
-
1232
- result = s(:colon3, id.to_sym).line lexer.lineno
1268
+ result = wrap :colon3, val[1]
1233
1269
  }
1234
1270
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1235
1271
  {
@@ -1253,15 +1289,21 @@ rule
1253
1289
  }
1254
1290
  | kYIELD tLPAREN2 call_args rparen
1255
1291
  {
1256
- result = new_yield val[2]
1292
+ (_, line), _, args, _ = val
1293
+
1294
+ result = new_yield(args).line line
1257
1295
  }
1258
1296
  | kYIELD tLPAREN2 rparen
1259
1297
  {
1260
- result = new_yield
1298
+ (_, line), _, _ = val
1299
+
1300
+ result = new_yield.line line
1261
1301
  }
1262
1302
  | kYIELD
1263
1303
  {
1264
- result = new_yield
1304
+ (_, line), = val
1305
+
1306
+ result = new_yield.line line
1265
1307
  }
1266
1308
  | kDEFINED opt_nl tLPAREN2 expr rparen
1267
1309
  {
@@ -1276,7 +1318,7 @@ rule
1276
1318
  }
1277
1319
  | kNOT tLPAREN2 rparen
1278
1320
  {
1279
- debug20 14, val, result
1321
+ debug 20
1280
1322
  }
1281
1323
  | fcall brace_block
1282
1324
  {
@@ -1294,9 +1336,10 @@ rule
1294
1336
  iter.insert 1, call # FIX
1295
1337
  result = iter
1296
1338
  }
1297
- | tLAMBDA lambda
1339
+ | lambda
1298
1340
  {
1299
- result = val[1] # TODO: fix lineno
1341
+ expr, = val
1342
+ result = expr
1300
1343
  }
1301
1344
  | k_if expr_value then compstmt if_tail k_end
1302
1345
  {
@@ -1328,6 +1371,12 @@ rule
1328
1371
  (_, line), _, body, _ = val
1329
1372
  result = new_case nil, body, line
1330
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
+ }
1331
1380
  | k_for for_var kIN expr_value_do compstmt k_end
1332
1381
  {
1333
1382
  _, var, _, iter, body, _ = val
@@ -1339,7 +1388,6 @@ rule
1339
1388
  }
1340
1389
  cpath superclass
1341
1390
  {
1342
- self.comments.push self.lexer.comments
1343
1391
  if (self.in_def || self.in_single > 0) then
1344
1392
  yyerror "class definition in method body"
1345
1393
  end
@@ -1349,7 +1397,7 @@ rule
1349
1397
  {
1350
1398
  result = new_class val
1351
1399
  self.env.unextend
1352
- self.lexer.comments # we don't care about comments in the body
1400
+ self.lexer.ignore_body_comments
1353
1401
  }
1354
1402
  | k_class tLSHFT
1355
1403
  {
@@ -1370,7 +1418,7 @@ rule
1370
1418
  {
1371
1419
  result = new_sclass val
1372
1420
  self.env.unextend
1373
- self.lexer.comments # we don't care about comments in the body
1421
+ self.lexer.ignore_body_comments
1374
1422
  }
1375
1423
  | k_module
1376
1424
  {
@@ -1378,7 +1426,6 @@ rule
1378
1426
  }
1379
1427
  cpath
1380
1428
  {
1381
- self.comments.push self.lexer.comments
1382
1429
  yyerror "module definition in method body" if
1383
1430
  self.in_def or self.in_single > 0
1384
1431
 
@@ -1388,7 +1435,7 @@ rule
1388
1435
  {
1389
1436
  result = new_module val
1390
1437
  self.env.unextend
1391
- self.lexer.comments # we don't care about comments in the body
1438
+ self.lexer.ignore_body_comments
1392
1439
  }
1393
1440
  | k_def fname
1394
1441
  {
@@ -1398,21 +1445,17 @@ rule
1398
1445
  self.env.extend
1399
1446
  lexer.cmdarg.push false
1400
1447
  lexer.cond.push false
1401
-
1402
- self.comments.push self.lexer.comments
1403
1448
  }
1404
- f_arglist bodystmt { result = lexer.lineno } k_end
1449
+ f_arglist bodystmt k_end
1405
1450
  {
1406
- in_def = val[2]
1407
-
1408
- result = new_defn val
1451
+ result, in_def = new_defn val
1409
1452
 
1410
1453
  lexer.cond.pop # group = local_pop
1411
1454
  lexer.cmdarg.pop
1412
1455
  self.env.unextend
1413
1456
  self.in_def = in_def
1414
1457
 
1415
- self.lexer.comments # we don't care about comments in the body
1458
+ self.lexer.ignore_body_comments
1416
1459
  }
1417
1460
  | k_def singleton dot_or_colon
1418
1461
  {
@@ -1420,7 +1463,7 @@ rule
1420
1463
  }
1421
1464
  fname
1422
1465
  {
1423
- result = [self.in_def, lexer.lineno]
1466
+ result = self.in_def
1424
1467
 
1425
1468
  self.in_single += 1 # TODO: remove?
1426
1469
 
@@ -1430,13 +1473,18 @@ rule
1430
1473
  lexer.cond.push false
1431
1474
 
1432
1475
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1433
- self.comments.push self.lexer.comments
1434
1476
  }
1435
1477
  f_arglist bodystmt k_end
1436
1478
  {
1437
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1438
1479
 
1439
- 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
1440
1488
 
1441
1489
  lexer.cond.pop # group = local_pop
1442
1490
  lexer.cmdarg.pop
@@ -1447,7 +1495,7 @@ rule
1447
1495
 
1448
1496
  # TODO: restore cur_arg ? what's cur_arg?
1449
1497
 
1450
- self.lexer.comments # we don't care about comments in the body
1498
+ self.lexer.ignore_body_comments
1451
1499
  }
1452
1500
  | kBREAK
1453
1501
  {
@@ -1484,8 +1532,17 @@ rule
1484
1532
  k_case: kCASE
1485
1533
  k_for: kFOR
1486
1534
  k_class: kCLASS
1535
+ {
1536
+ self.comments.push self.lexer.comments
1537
+ }
1487
1538
  k_module: kMODULE
1539
+ {
1540
+ self.comments.push self.lexer.comments
1541
+ }
1488
1542
  k_def: kDEF
1543
+ {
1544
+ self.comments.push self.lexer.comments
1545
+ }
1489
1546
  k_do: kDO
1490
1547
  k_do_block: kDO_BLOCK
1491
1548
  k_rescue: kRESCUE
@@ -1546,51 +1603,42 @@ rule
1546
1603
 
1547
1604
  result = block_var args
1548
1605
  }
1549
- | f_marg_list tCOMMA tSTAR f_norm_arg
1606
+ | f_marg_list tCOMMA f_rest_marg
1550
1607
  {
1551
- args, _, _, splat = val
1608
+ args, _, rest = val
1552
1609
 
1553
- result = block_var args, "*#{splat}".to_sym
1610
+ result = block_var args, rest
1554
1611
  }
1555
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1612
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1556
1613
  {
1557
- args, _, _, splat, _, args2 = val
1614
+ lhs, _, splat, _, rhs = val
1558
1615
 
1559
- result = block_var args, "*#{splat}".to_sym, args2
1616
+ result = block_var lhs, splat, rhs
1560
1617
  }
1561
- | f_marg_list tCOMMA tSTAR
1618
+ | f_rest_marg
1562
1619
  {
1563
- args, _, _ = val
1620
+ rest, = val
1564
1621
 
1565
- result = block_var args, :*
1622
+ result = block_var rest
1566
1623
  }
1567
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1624
+ | f_rest_marg tCOMMA f_marg_list
1568
1625
  {
1569
- args, _, _, _, args2 = val
1626
+ splat, _, rest = val
1570
1627
 
1571
- result = block_var args, :*, args2
1628
+ result = block_var splat, rest
1572
1629
  }
1573
- | tSTAR f_norm_arg
1574
- {
1575
- _, splat = val
1576
1630
 
1577
- result = block_var :"*#{splat}"
1578
- }
1579
- | tSTAR f_norm_arg tCOMMA f_marg_list
1631
+ f_rest_marg: tSTAR f_norm_arg
1580
1632
  {
1581
- _, splat, _, args = val
1633
+ _, (id, line) = val
1582
1634
 
1583
- result = block_var :"*#{splat}", args
1635
+ result = args ["*#{id}".to_sym]
1636
+ result.line line
1584
1637
  }
1585
1638
  | tSTAR
1586
1639
  {
1587
- result = block_var :*
1588
- }
1589
- | tSTAR tCOMMA f_marg_list
1590
- {
1591
- _, _, args = val
1592
-
1593
- result = block_var :*, args
1640
+ result = args [:*]
1641
+ result.line lexer.lineno # FIX: tSTAR -> line
1594
1642
  }
1595
1643
 
1596
1644
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1605,10 +1653,14 @@ rule
1605
1653
  {
1606
1654
  result = call_args val
1607
1655
  }
1656
+ | f_no_kwarg opt_f_block_arg
1657
+ {
1658
+ result = args val
1659
+ }
1608
1660
  | f_block_arg
1609
1661
  {
1610
- line = lexer.lineno
1611
- result = call_args val # TODO: push line down
1662
+ (id, line), = val
1663
+ result = call_args [id]
1612
1664
  result.line line
1613
1665
  }
1614
1666
 
@@ -1717,13 +1769,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1769
 
1718
1770
  bvar: tIDENTIFIER
1719
1771
  {
1720
- id, = val
1721
- line = lexer.lineno
1722
- result = s(:shadow, id.to_sym).line line
1772
+ result = wrap :shadow, val[0]
1723
1773
  }
1724
1774
  | f_bad_arg
1725
1775
 
1726
- lambda: {
1776
+ lambda: tLAMBDA
1777
+ {
1727
1778
  self.env.extend :dynamic
1728
1779
  result = [lexer.lineno, lexer.lpar_beg]
1729
1780
  lexer.paren_nest += 1
@@ -1735,14 +1786,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1735
1786
  }
1736
1787
  lambda_body
1737
1788
  {
1738
- (line, lpar), args, _cmdarg, body = val
1789
+ _, (line, lpar), args, _cmdarg, body = val
1739
1790
  lexer.lpar_beg = lpar
1740
1791
 
1741
1792
  lexer.cmdarg.pop
1742
1793
 
1743
1794
  call = s(:lambda).line line
1744
1795
  result = new_iter call, args, body
1745
- result.line = line
1796
+ result.line line
1746
1797
  self.env.unextend # TODO: dynapush & dynapop
1747
1798
  }
1748
1799
 
@@ -1777,23 +1828,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1777
1828
  ## if (nd_type($1) == NODE_YIELD) {
1778
1829
  ## compile_error(PARSER_ARG "block given to yield");
1779
1830
 
1780
- syntax_error "Both block arg and actual block given." if
1781
- val[0].block_pass?
1831
+ cmd, blk = val
1782
1832
 
1783
- val = invert_block_call val if inverted? val
1833
+ syntax_error "Both block arg and actual block given." if
1834
+ cmd.block_pass?
1784
1835
 
1785
- cmd, blk = val
1836
+ if inverted? val then
1837
+ val = invert_block_call val
1838
+ cmd, blk = val
1839
+ end
1786
1840
 
1787
1841
  result = blk
1788
1842
  result.insert 1, cmd
1789
1843
  }
1790
1844
  | block_call call_op2 operation2 opt_paren_args
1791
1845
  {
1792
- 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
1793
1849
  }
1794
1850
  | block_call call_op2 operation2 opt_paren_args brace_block
1795
1851
  {
1796
- iter1, _, name, args, iter2 = val
1852
+ iter1, _, (name, _line), args, iter2 = val
1797
1853
 
1798
1854
  call = new_call iter1, name.to_sym, args
1799
1855
  iter2.insert 1, call
@@ -1802,7 +1858,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1858
  }
1803
1859
  | block_call call_op2 operation2 command_args do_block
1804
1860
  {
1805
- iter1, _, name, args, iter2 = val
1861
+ iter1, _, (name, _line), args, iter2 = val
1806
1862
 
1807
1863
  call = new_call iter1, name.to_sym, args
1808
1864
  iter2.insert 1, call
@@ -1810,28 +1866,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
1866
  result = iter2
1811
1867
  }
1812
1868
 
1813
- method_call: fcall
1814
- {
1815
- result = self.lexer.lineno
1816
- }
1817
- paren_args
1869
+ method_call: fcall paren_args
1818
1870
  {
1819
- call, lineno, args = val
1871
+ call, args = val
1820
1872
 
1821
1873
  result = call.concat args.sexp_body if args
1822
- result.line lineno
1823
1874
  }
1824
1875
  | primary_value call_op operation2 opt_paren_args
1825
1876
  {
1826
- 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
1827
1880
  }
1828
1881
  | primary_value tCOLON2 operation2 paren_args
1829
1882
  {
1830
- 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
1831
1886
  }
1832
1887
  | primary_value tCOLON2 operation3
1833
1888
  {
1834
- result = new_call val[0], val[2].to_sym
1889
+ lhs, _, (id, _line) = val
1890
+
1891
+ result = new_call lhs, id.to_sym
1835
1892
  }
1836
1893
  | primary_value call_op paren_args
1837
1894
  {
@@ -1864,7 +1921,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
1921
  _, line, body, _ = val
1865
1922
 
1866
1923
  result = body
1867
- result.line = line
1924
+ result.line line
1868
1925
 
1869
1926
  self.env.unextend
1870
1927
  }
@@ -1878,7 +1935,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1878
1935
  _, line, body, _ = val
1879
1936
 
1880
1937
  result = body
1881
- result.line = line
1938
+ result.line line
1882
1939
 
1883
1940
  self.env.unextend
1884
1941
  }
@@ -1907,18 +1964,537 @@ opt_block_args_tail: tCOMMA block_args_tail
1907
1964
  self.env.unextend
1908
1965
  }
1909
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
+
1910
1992
  case_body: k_when
1911
1993
  {
1912
1994
  result = self.lexer.lineno
1913
1995
  }
1914
- args then compstmt cases
1996
+ case_args then compstmt cases
1915
1997
  {
1916
1998
  result = new_when(val[2], val[4])
1917
- result.line = val[1]
1999
+ result.line val[1]
1918
2000
  result << val[5] if val[5]
1919
2001
  }
1920
2002
 
1921
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
+ | qwords
2457
+ | symbols
2458
+ | qsymbols
2459
+ | keyword_variable
2460
+ {
2461
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2462
+ var, = val
2463
+
2464
+ result = var
2465
+ }
2466
+ | lambda
2467
+
2468
+ p_variable: tIDENTIFIER
2469
+ {
2470
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2471
+ # TODO: assignable(p, $1, 0, &@$);
2472
+ result = wrap :lvar, val[0]
2473
+ }
2474
+
2475
+ p_var_ref: tCARET tIDENTIFIER
2476
+ {
2477
+ # TODO: check id against env for lvar or dvar
2478
+ result = wrap :lvar, val[1]
2479
+ }
2480
+
2481
+ p_const: tCOLON3 cname
2482
+ {
2483
+ result = wrap :colon3, val[1]
2484
+ }
2485
+ | p_const tCOLON2 cname
2486
+ {
2487
+ lhs, _, (id, _line) = val
2488
+
2489
+ l = lhs.line
2490
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2491
+ }
2492
+ | tCONSTANT
2493
+ {
2494
+ # TODO $$ = gettable(p, $1, &@$);
2495
+ result = wrap :const, val[0]
2496
+ }
2497
+ ######################################################################
1922
2498
 
1923
2499
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1924
2500
  {
@@ -1960,17 +2536,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1960
2536
 
1961
2537
  literal: numeric
1962
2538
  {
1963
- line = lexer.lineno
1964
- result = s(:lit, val[0])
1965
- result.line = line
2539
+ (lit, line), = val
2540
+ result = s(:lit, lit).line line
1966
2541
  }
1967
2542
  | symbol
1968
- {
1969
- line = lexer.lineno
1970
- result = s(:lit, val[0])
1971
- result.line = line
1972
- }
1973
- | dsym
1974
2543
 
1975
2544
  strings: string
1976
2545
  {
@@ -1981,7 +2550,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1981
2550
 
1982
2551
  string: tCHAR
1983
2552
  {
1984
- debug20 23, val, result
2553
+ debug 37
1985
2554
  }
1986
2555
  | string1
1987
2556
  | string string1
@@ -1991,11 +2560,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1991
2560
 
1992
2561
  string1: tSTRING_BEG string_contents tSTRING_END
1993
2562
  {
1994
- _, str, (_, func) = val
2563
+ (_, line), str, (_, func) = val
1995
2564
 
1996
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2565
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1997
2566
 
1998
- result = str
2567
+ result = str.line line
1999
2568
  }
2000
2569
  | tSTRING
2001
2570
  {
@@ -2015,11 +2584,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2015
2584
 
2016
2585
  words: tWORDS_BEG tSPACE tSTRING_END
2017
2586
  {
2018
- result = s(:array).line lexer.lineno
2587
+ (_, line), _, _ = val
2588
+
2589
+ result = s(:array).line line
2019
2590
  }
2020
2591
  | tWORDS_BEG word_list tSTRING_END
2021
2592
  {
2022
- result = val[1]
2593
+ (_, line), list, _ = val
2594
+
2595
+ result = list.line line
2023
2596
  }
2024
2597
 
2025
2598
  word_list: none
@@ -2039,18 +2612,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2039
2612
 
2040
2613
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2041
2614
  {
2042
- result = s(:array).line lexer.lineno
2615
+ (_, line), _, _ = val
2616
+
2617
+ result = s(:array).line line
2043
2618
  }
2044
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2619
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2045
2620
  {
2046
- _, line, list, _, = val
2047
- list.line = line
2621
+ (_, line), list, _, = val
2622
+ list.line line
2048
2623
  result = list
2049
2624
  }
2050
2625
 
2051
2626
  symbol_list: none
2052
2627
  {
2053
- result = new_symbol_list.line lexer.lineno
2628
+ result = new_symbol_list
2054
2629
  }
2055
2630
  | symbol_list word tSPACE
2056
2631
  {
@@ -2060,20 +2635,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2060
2635
 
2061
2636
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2062
2637
  {
2063
- result = s(:array).line lexer.lineno
2638
+ (_, line), _, _ = val
2639
+
2640
+ result = s(:array).line line
2064
2641
  }
2065
2642
  | tQWORDS_BEG qword_list tSTRING_END
2066
2643
  {
2067
- result = val[1]
2644
+ (_, line), list, _ = val
2645
+
2646
+ result = list.line line
2068
2647
  }
2069
2648
 
2070
2649
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2071
2650
  {
2072
- result = s(:array).line lexer.lineno # FIX
2651
+ (_, line), _, _ = val
2652
+
2653
+ result = s(:array).line line
2073
2654
  }
2074
2655
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2075
2656
  {
2076
- result = val[1]
2657
+ (_, line), list, _ = val
2658
+
2659
+ result = list.line line
2077
2660
  }
2078
2661
 
2079
2662
  qword_list: none
@@ -2096,7 +2679,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2096
2679
 
2097
2680
  string_contents: none
2098
2681
  {
2099
- result = s(:str, "").line lexer.lineno
2682
+ line = prev_value_to_lineno _values.last
2683
+ result = s(:str, +"").line line
2100
2684
  }
2101
2685
  | string_contents string_content
2102
2686
  {
@@ -2171,8 +2755,8 @@ regexp_contents: none
2171
2755
  lexer.brace_nest = brace_nest
2172
2756
  lexer.string_nest = string_nest
2173
2757
 
2174
- lexer.cmdarg.pop
2175
2758
  lexer.cond.pop
2759
+ lexer.cmdarg.pop
2176
2760
 
2177
2761
  lexer.lex_state = oldlex_state
2178
2762
 
@@ -2187,29 +2771,42 @@ regexp_contents: none
2187
2771
  when nil then
2188
2772
  result = s(:evstr).line line
2189
2773
  else
2190
- debug20 25
2774
+ debug 38
2191
2775
  raise "unknown string body: #{stmt.inspect}"
2192
2776
  end
2193
2777
  }
2194
2778
 
2195
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2196
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2197
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2779
+ string_dvar: tGVAR
2780
+ {
2781
+ result = wrap :gvar, val[0]
2782
+ }
2783
+ | tIVAR
2784
+ {
2785
+ result = wrap :ivar, val[0]
2786
+ }
2787
+ | tCVAR
2788
+ {
2789
+ result = wrap :cvar, val[0]
2790
+ }
2198
2791
  | backref
2199
2792
 
2200
- symbol: tSYMBEG sym
2793
+ symbol: ssym
2794
+ | dsym
2795
+
2796
+ ssym: tSYMBEG sym
2201
2797
  {
2202
2798
  lexer.lex_state = EXPR_END
2203
- result = val[1].to_sym
2799
+ result = wrap :lit, val[1]
2204
2800
  }
2205
2801
  | tSYMBOL
2206
2802
  {
2207
- result = val[0].to_sym
2803
+ lexer.lex_state = EXPR_END
2804
+ result = wrap :lit, val[0]
2208
2805
  }
2209
2806
 
2210
2807
  sym: fname | tIVAR | tGVAR | tCVAR
2211
2808
 
2212
- dsym: tSYMBEG xstring_contents tSTRING_END
2809
+ dsym: tSYMBEG string_contents tSTRING_END
2213
2810
  {
2214
2811
  _, result, _ = val
2215
2812
 
@@ -2225,14 +2822,15 @@ regexp_contents: none
2225
2822
  when :evstr then
2226
2823
  result = s(:dsym, "", result).line result.line
2227
2824
  else
2228
- debug20 26, val, result
2825
+ debug 39
2229
2826
  end
2230
2827
  }
2231
2828
 
2232
2829
  numeric: simple_numeric
2233
- | tUMINUS_NUM simple_numeric
2830
+ | tUMINUS_NUM simple_numeric =tLOWEST
2234
2831
  {
2235
- result = -val[1] # TODO: pt_testcase
2832
+ _, (num, line) = val
2833
+ result = [-num, line]
2236
2834
  }
2237
2835
 
2238
2836
  simple_numeric: tINTEGER
@@ -2265,8 +2863,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2863
 
2266
2864
  var_ref: user_variable
2267
2865
  {
2268
- var = val[0]
2866
+ raise "NO: #{val.inspect}" if Sexp === val.first
2867
+ (var, line), = val
2269
2868
  result = Sexp === var ? var : self.gettable(var)
2869
+ result.line line
2270
2870
  }
2271
2871
  | keyword_variable
2272
2872
  {
@@ -2281,11 +2881,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2281
2881
  | keyword_variable
2282
2882
  {
2283
2883
  result = self.assignable val[0]
2284
- debug20 29, val, result
2884
+ debug 40
2285
2885
  }
2286
2886
 
2287
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2288
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2887
+ backref: tNTH_REF
2888
+ {
2889
+ (ref, line), = val
2890
+ result = s(:nth_ref, ref).line line
2891
+ }
2892
+ | tBACK_REF
2893
+ {
2894
+ (ref, line), = val
2895
+ result = s(:back_ref, ref).line line
2896
+ }
2289
2897
 
2290
2898
  superclass: tLT
2291
2899
  {
@@ -2303,23 +2911,15 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2303
2911
 
2304
2912
  f_arglist: tLPAREN2 f_args rparen
2305
2913
  {
2306
- result = val[1]
2307
- self.lexer.lex_state = EXPR_BEG
2308
- self.lexer.command_start = true
2914
+ result = end_args val
2309
2915
  }
2310
2916
  | tLPAREN2 f_arg tCOMMA args_forward rparen
2311
2917
  {
2312
- result = args val
2313
-
2314
- self.lexer.lex_state = EXPR_BEG
2315
- self.lexer.command_start = true
2918
+ result = end_args val
2316
2919
  }
2317
2920
  | tLPAREN2 args_forward rparen
2318
2921
  {
2319
- result = args val
2320
-
2321
- self.lexer.lex_state = EXPR_BEG
2322
- self.lexer.command_start = true
2922
+ result = end_args val
2323
2923
  }
2324
2924
  | {
2325
2925
  result = self.in_kwarg
@@ -2328,12 +2928,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2328
2928
  }
2329
2929
  f_args term
2330
2930
  {
2331
- kwarg, args, _ = val
2332
-
2333
- self.in_kwarg = kwarg
2334
- result = args
2335
- lexer.lex_state = EXPR_BEG
2336
- lexer.command_start = true
2931
+ result = end_args val
2337
2932
  }
2338
2933
 
2339
2934
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2348,6 +2943,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2348
2943
  {
2349
2944
  result = args val
2350
2945
  }
2946
+ | f_no_kwarg opt_f_block_arg
2947
+ {
2948
+ result = args val
2949
+ }
2351
2950
  | f_block_arg
2352
2951
 
2353
2952
  opt_args_tail: tCOMMA args_tail
@@ -2418,6 +3017,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2418
3017
  |
2419
3018
  {
2420
3019
  result = args val
3020
+ # result.line lexer.lineno
2421
3021
  }
2422
3022
 
2423
3023
  args_forward: tBDOT3
@@ -2445,10 +3045,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2445
3045
  f_norm_arg: f_bad_arg
2446
3046
  | tIDENTIFIER
2447
3047
  {
2448
- identifier = val[0].to_sym
3048
+ (id, line), = val
3049
+ identifier = id.to_sym
2449
3050
  self.env[identifier] = :lvar
2450
3051
 
2451
- result = identifier
3052
+ result = [identifier, line]
2452
3053
  }
2453
3054
 
2454
3055
  f_arg_asgn: f_norm_arg
@@ -2456,22 +3057,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2456
3057
  f_arg_item: f_arg_asgn
2457
3058
  | tLPAREN f_margs rparen
2458
3059
  {
2459
- result = val[1]
3060
+ _, margs, _ = val
3061
+
3062
+ result = margs
2460
3063
  }
2461
3064
 
2462
3065
  f_arg: f_arg_item
2463
3066
  {
2464
- arg, = val
2465
-
2466
- case arg
2467
- when Symbol then
2468
- result = s(:args, arg).line lexer.lineno
2469
- when Sexp then
2470
- result = arg
2471
- else
2472
- debug20 32
2473
- raise "Unknown f_arg type: #{val.inspect}"
2474
- end
3067
+ result = new_arg val
2475
3068
  }
2476
3069
  | f_arg tCOMMA f_arg_item
2477
3070
  {
@@ -2483,7 +3076,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2483
3076
  result = s(:args, list).line list.line
2484
3077
  end
2485
3078
 
2486
- result << item
3079
+ result << (Sexp === item ? item : item.first)
2487
3080
  }
2488
3081
 
2489
3082
  f_label: tLABEL
@@ -2544,27 +3137,37 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
3137
  kwrest_mark: tPOW
2545
3138
  | tDSTAR
2546
3139
 
3140
+ f_no_kwarg: kwrest_mark kNIL
3141
+ {
3142
+ result = :"**nil"
3143
+ }
3144
+
2547
3145
  f_kwrest: kwrest_mark tIDENTIFIER
2548
3146
  {
2549
- name = val[1].to_sym
2550
- self.assignable name
2551
- result = :"**#{name}"
3147
+ _, (id, line) = val
3148
+
3149
+ name = id.to_sym
3150
+ self.assignable [name, line]
3151
+ result = [:"**#{name}", line]
2552
3152
  }
2553
3153
  | kwrest_mark
2554
3154
  {
2555
- result = :"**"
2556
- self.env[result] = :lvar
3155
+ id = :"**"
3156
+ self.env[id] = :lvar # TODO: needed?!?
3157
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2557
3158
  }
2558
3159
 
2559
3160
  f_opt: f_arg_asgn tEQL arg_value
2560
3161
  {
2561
- result = self.assignable val[0], val[2]
3162
+ lhs, _, rhs = val
3163
+ result = self.assignable lhs, rhs
2562
3164
  # TODO: detect duplicate names
2563
3165
  }
2564
3166
 
2565
3167
  f_block_opt: f_arg_asgn tEQL primary_value
2566
3168
  {
2567
- result = self.assignable val[0], val[2]
3169
+ lhs, _, rhs = val
3170
+ result = self.assignable lhs, rhs
2568
3171
  }
2569
3172
 
2570
3173
  f_block_optarg: f_block_opt
@@ -2594,30 +3197,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
3197
  f_rest_arg: restarg_mark tIDENTIFIER
2595
3198
  {
2596
3199
  # TODO: differs from parse.y - needs tests
2597
- name = val[1].to_sym
2598
- self.assignable name
2599
- result = :"*#{name}"
3200
+ _, (id, line) = val
3201
+ name = id.to_sym
3202
+ self.assignable [name, line]
3203
+ result = [:"*#{name}", line]
2600
3204
  }
2601
3205
  | restarg_mark
2602
3206
  {
2603
3207
  name = :"*"
2604
3208
  self.env[name] = :lvar
2605
- result = name
3209
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2606
3210
  }
2607
3211
 
2608
3212
  blkarg_mark: tAMPER2 | tAMPER
2609
3213
 
2610
3214
  f_block_arg: blkarg_mark tIDENTIFIER
2611
3215
  {
2612
- identifier = val[1].to_sym
3216
+ _, (id, line) = val
3217
+ identifier = id.to_sym
2613
3218
 
2614
3219
  self.env[identifier] = :lvar
2615
- result = "&#{identifier}".to_sym
3220
+ result = ["&#{identifier}".to_sym, line]
2616
3221
  }
2617
3222
 
2618
3223
  opt_f_block_arg: tCOMMA f_block_arg
2619
3224
  {
2620
- result = val[1]
3225
+ _, arg = val
3226
+ result = arg
2621
3227
  }
2622
3228
  |
2623
3229
  {
@@ -2659,16 +3265,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2659
3265
  }
2660
3266
  | tLABEL arg_value
2661
3267
  {
2662
- (label, line), arg = val
3268
+ label, arg = val
2663
3269
 
2664
- lit = s(:lit, label.to_sym).line line
2665
- result = s(:array, lit, arg).line line
3270
+ lit = wrap :lit, label
3271
+ result = s(:array, lit, arg).line lit.line
2666
3272
  }
2667
3273
  | tSTRING_BEG string_contents tLABEL_END arg_value
2668
3274
  {
2669
- _, sym, _, value = val
3275
+ (_, line), sym, _, value = val
3276
+
2670
3277
  sym.sexp_type = :dsym
2671
- result = s(:array, sym, value).line sym.line
3278
+
3279
+ result = s(:array, sym, value).line line
2672
3280
  }
2673
3281
  | tDSTAR arg_value
2674
3282
  {
@@ -2691,6 +3299,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2691
3299
  opt_nl: | tNL
2692
3300
  rparen: opt_nl tRPAREN
2693
3301
  rbracket: opt_nl tRBRACK
3302
+ rbrace: opt_nl tRCURLY
2694
3303
  trailer: | tNL | tCOMMA
2695
3304
 
2696
3305
  term: tSEMI { yyerrok }