ruby_parser 3.17.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
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 }