ruby_parser 3.15.1 → 3.18.1

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