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