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/ruby23_parser.y CHANGED
@@ -18,7 +18,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
@@ -79,7 +79,7 @@ rule
79
79
  | klBEGIN
80
80
  {
81
81
  if (self.in_def || self.in_single > 0) then
82
- debug20 1
82
+ debug 11
83
83
  yyerror "BEGIN in method"
84
84
  end
85
85
  self.env.extend
@@ -104,7 +104,9 @@ rule
104
104
  bodystmt: compstmt opt_rescue k_else
105
105
  {
106
106
  res = _values[-2]
107
- yyerror "else without rescue is useless" unless res
107
+ # TODO: move down to main match so I can just use val
108
+
109
+ warn "else without rescue is useless" unless res
108
110
  }
109
111
  compstmt
110
112
  opt_ensure
@@ -134,7 +136,7 @@ rule
134
136
  | error stmt
135
137
  {
136
138
  result = val[1]
137
- debug20 2, val, result
139
+ debug 12
138
140
  }
139
141
 
140
142
  stmt_or_begin: stmt
@@ -142,6 +144,10 @@ rule
142
144
  {
143
145
  yyerror "BEGIN is permitted only at toplevel"
144
146
  }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
150
+ }
145
151
 
146
152
  stmt: kALIAS fitem
147
153
  {
@@ -154,12 +160,12 @@ rule
154
160
  }
155
161
  | kALIAS tGVAR tGVAR
156
162
  {
157
- (_, line), lhs, rhs = val
163
+ (_, line), (lhs, _), (rhs, _) = val
158
164
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
159
165
  }
160
166
  | kALIAS tGVAR tBACK_REF
161
167
  {
162
- (_, line), lhs, rhs = val
168
+ (_, line), (lhs, _), (rhs, _) = val
163
169
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
164
170
  }
165
171
  | kALIAS tGVAR tNTH_REF
@@ -202,7 +208,7 @@ rule
202
208
  (_, line), _, stmt, _ = val
203
209
 
204
210
  if (self.in_def || self.in_single > 0) then
205
- debug20 3
211
+ debug 13
206
212
  yyerror "END in method; use at_exit"
207
213
  end
208
214
 
@@ -242,32 +248,31 @@ rule
242
248
  }
243
249
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
244
250
  {
245
- prim, _, id, opasgn, rhs = val
246
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
247
- if val[1] == '&.'
248
- result.sexp_type = :safe_op_asgn
249
- end
250
- result.line = val[0].line
251
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
252
+
253
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
254
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
255
+ result.line prim.line
251
256
  }
252
257
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
253
258
  {
254
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
255
- if val[1] == '&.'
256
- result.sexp_type = :safe_op_asgn
257
- end
258
- result.line = val[0].line
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
259
264
  }
260
265
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
261
266
  {
262
- lhs1, _, lhs2, op, rhs = val
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
263
268
 
264
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
269
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
265
270
  }
266
271
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
267
272
  {
268
- lhs1, _, lhs2, op, rhs = val
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
269
274
 
270
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
275
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
271
276
  }
272
277
  | backref tOP_ASGN command_rhs
273
278
  {
@@ -305,7 +310,7 @@ rule
305
310
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
306
311
  # REFACTOR: call_uni_op -- see parse26.y
307
312
  }
308
- | arg
313
+ | arg =tLBRACE_ARG
309
314
 
310
315
  expr_value: expr
311
316
  {
@@ -330,7 +335,7 @@ rule
330
335
  block_command: block_call
331
336
  | block_call call_op2 operation2 command_args
332
337
  {
333
- blk, _, msg, args = val
338
+ blk, _, (msg, _line), args = val
334
339
  result = new_call(blk, msg.to_sym, args).line blk.line
335
340
  }
336
341
 
@@ -344,15 +349,15 @@ rule
344
349
  _, line, body, _ = val
345
350
 
346
351
  result = body
347
- result.line = line
352
+ result.line line
348
353
 
349
354
  # self.env.unextend
350
355
  }
351
356
 
352
357
  fcall: operation
353
358
  {
354
- msg, = val
355
- result = new_call(nil, msg.to_sym).line lexer.lineno
359
+ (msg, line), = val
360
+ result = new_call(nil, msg.to_sym).line line
356
361
  }
357
362
 
358
363
  command: fcall command_args =tLOWEST
@@ -375,12 +380,14 @@ rule
375
380
  }
376
381
  | primary_value call_op operation2 command_args =tLOWEST
377
382
  {
378
- lhs, callop, op, args = val
383
+ lhs, callop, (op, _), args = val
384
+
379
385
  result = new_call lhs, op.to_sym, args, callop
386
+ result.line lhs.line
380
387
  }
381
388
  | primary_value call_op operation2 command_args cmd_brace_block
382
389
  {
383
- recv, _, msg, args, block = val
390
+ recv, _, (msg, _line), args, block = val
384
391
  call = new_call recv, msg.to_sym, args, val[1]
385
392
 
386
393
  block_dup_check call, block
@@ -390,11 +397,14 @@ rule
390
397
  }
391
398
  | primary_value tCOLON2 operation2 command_args =tLOWEST
392
399
  {
393
- result = new_call val[0], val[2].to_sym, val[3]
400
+ lhs, _, (id, line), args = val
401
+
402
+ result = new_call lhs, id.to_sym, args
403
+ result.line line
394
404
  }
395
405
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
396
406
  {
397
- recv, _, msg, args, block = val
407
+ recv, _, (msg, _line), args, block = val
398
408
  call = new_call recv, msg.to_sym, args
399
409
 
400
410
  block_dup_check call, block
@@ -552,25 +562,29 @@ rule
552
562
  }
553
563
  | primary_value call_op tIDENTIFIER
554
564
  {
555
- result = new_attrasgn val[0], val[2], val[1]
565
+ lhs, call_op, (id, _line) = val
566
+
567
+ result = new_attrasgn lhs, id, call_op
556
568
  }
557
569
  | primary_value tCOLON2 tIDENTIFIER
558
570
  {
559
- recv, _, id = val
571
+ recv, _, (id, _line) = val
560
572
  result = new_attrasgn recv, id
561
573
  }
562
574
  | primary_value call_op tCONSTANT
563
575
  {
564
- result = new_attrasgn val[0], val[2], val[1]
576
+ lhs, call_op, (id, _line) = val
577
+
578
+ result = new_attrasgn lhs, id, call_op
565
579
  }
566
580
  | primary_value tCOLON2 tCONSTANT
567
581
  {
568
582
  if (self.in_def || self.in_single > 0) then
569
- debug20 7
583
+ debug 14
570
584
  yyerror "dynamic constant assignment"
571
585
  end
572
586
 
573
- expr, _, id = val
587
+ expr, _, (id, _line) = val
574
588
  l = expr.line
575
589
 
576
590
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -578,58 +592,65 @@ rule
578
592
  | tCOLON3 tCONSTANT
579
593
  {
580
594
  if (self.in_def || self.in_single > 0) then
581
- debug20 8
595
+ debug 15
582
596
  yyerror "dynamic constant assignment"
583
597
  end
584
598
 
585
- _, id = val
586
- l = lexer.lineno
599
+ _, (id, l) = val
587
600
 
588
601
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
589
602
  }
590
603
  | backref
591
604
  {
592
- self.backref_assign_error val[0]
605
+ ref, = val
606
+
607
+ self.backref_assign_error ref
593
608
  }
594
609
 
595
610
  lhs: user_variable
596
611
  {
597
- line = lexer.lineno
598
- result = self.assignable val[0]
599
- result.line = line
612
+ var, = val
613
+
614
+ result = self.assignable var
600
615
  }
601
616
  | keyword_variable
602
617
  {
603
- line = lexer.lineno
604
- result = self.assignable val[0]
605
- result.line = line
606
- debug20 9, val, result
618
+ var, = val
619
+
620
+ result = self.assignable var
621
+
622
+ debug 16
607
623
  }
608
624
  | primary_value tLBRACK2 opt_call_args rbracket
609
625
  {
610
626
  lhs, _, args, _ = val
627
+
611
628
  result = self.aryset lhs, args
612
629
  }
613
630
  | primary_value call_op tIDENTIFIER # REFACTOR
614
631
  {
615
- lhs, op, id = val
632
+ lhs, op, (id, _line) = val
633
+
616
634
  result = new_attrasgn lhs, id, op
617
635
  }
618
636
  | primary_value tCOLON2 tIDENTIFIER
619
637
  {
620
- lhs, _, id = val
638
+ lhs, _, (id, _line) = val
639
+
621
640
  result = new_attrasgn lhs, id
622
641
  }
623
642
  | primary_value call_op tCONSTANT # REFACTOR?
624
643
  {
625
- result = new_attrasgn val[0], val[2], val[1]
644
+ lhs, call_op, (id, _line) = val
645
+
646
+ result = new_attrasgn lhs, id, call_op
626
647
  }
627
648
  | primary_value tCOLON2 tCONSTANT
628
649
  {
629
- expr, _, id = val
650
+ expr, _, (id, _line) = val
630
651
 
631
652
  if (self.in_def || self.in_single > 0) then
632
- debug20 10
653
+ debug 17
633
654
  yyerror "dynamic constant assignment"
634
655
  end
635
656
 
@@ -638,14 +659,13 @@ rule
638
659
  }
639
660
  | tCOLON3 tCONSTANT
640
661
  {
641
- _, id = val
662
+ _, (id, l) = val
642
663
 
643
664
  if (self.in_def || self.in_single > 0) then
644
- debug20 11
665
+ debug 18
645
666
  yyerror "dynamic constant assignment"
646
667
  end
647
668
 
648
- l = lexer.lineno
649
669
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
650
670
  }
651
671
  | backref
@@ -661,16 +681,17 @@ rule
661
681
 
662
682
  cpath: tCOLON3 cname
663
683
  {
664
- _, name = val
665
- result = s(:colon3, name.to_sym).line lexer.lineno
684
+ _, (name, line) = val
685
+ result = s(:colon3, name.to_sym).line line
666
686
  }
667
687
  | cname
668
688
  {
669
- result = val[0].to_sym
689
+ (id, line), = val
690
+ result = [id.to_sym, line] # TODO: sexp?
670
691
  }
671
692
  | primary_value tCOLON2 cname
672
693
  {
673
- pval, _, name = val
694
+ pval, _, (name, _line) = val
674
695
 
675
696
  result = s(:colon2, pval, name.to_sym)
676
697
  result.line pval.line
@@ -680,24 +701,17 @@ rule
680
701
  | op
681
702
  {
682
703
  lexer.lex_state = EXPR_END
683
- result = val[0]
684
704
  }
685
705
 
686
706
  | reswords
687
- {
688
- (sym, _line), = val
689
- lexer.lex_state = EXPR_END
690
- result = sym
691
- }
692
-
693
- fsym: fname | symbol
694
707
 
695
- fitem: fsym
708
+ fitem: fname
696
709
  {
697
- id, = val
698
- result = s(:lit, id.to_sym).line lexer.lineno
710
+ (id, line), = val
711
+
712
+ result = s(:lit, id.to_sym).line line
699
713
  }
700
- | dsym
714
+ | symbol
701
715
 
702
716
  undef_list: fitem
703
717
  {
@@ -718,8 +732,6 @@ rule
718
732
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
719
733
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
720
734
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
721
- # TODO: tUBANG dead?
722
- | tUBANG
723
735
 
724
736
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
725
737
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -753,24 +765,20 @@ rule
753
765
  }
754
766
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
755
767
  {
756
- lhs, _, id, op, rhs = val
768
+ lhs, _, (id, _line), (op, _), rhs = val
757
769
 
758
770
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
759
771
  }
760
772
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
761
773
  {
762
- lhs1, _, lhs2, op, rhs = val
774
+ lhs1, _, (lhs2, _line), op, rhs = val
763
775
 
764
776
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
765
777
  result = new_const_op_asgn [lhs, op, rhs]
766
778
  }
767
- | tCOLON3 tCONSTANT
768
- {
769
- result = self.lexer.lineno
770
- }
771
- tOP_ASGN arg_rhs
779
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
772
780
  {
773
- _, lhs, line, op, rhs = val
781
+ _, (lhs, line), op, rhs = val
774
782
 
775
783
  lhs = s(:colon3, lhs.to_sym).line line
776
784
  result = new_const_op_asgn [lhs, op, rhs]
@@ -784,7 +792,7 @@ rule
784
792
  | arg tDOT2 arg
785
793
  {
786
794
  v1, v2 = val[0], val[2]
787
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
795
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
788
796
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
789
797
  else
790
798
  result = s(:dot2, v1, v2).line v1.line
@@ -793,7 +801,7 @@ rule
793
801
  | arg tDOT3 arg
794
802
  {
795
803
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
804
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
805
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
798
806
  else
799
807
  result = s(:dot3, v1, v2).line v1.line
@@ -827,8 +835,9 @@ rule
827
835
  }
828
836
  | tUMINUS_NUM simple_numeric tPOW arg
829
837
  {
830
- lit = s(:lit, val[1]).line lexer.lineno
831
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
838
+ _, (num, line), _, arg = val
839
+ lit = s(:lit, num).line line
840
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
832
841
 
833
842
  }
834
843
  | tUPLUS arg
@@ -927,12 +936,12 @@ rule
927
936
 
928
937
  rel_expr: arg relop arg =tGT
929
938
  {
930
- lhs, op, rhs = val
939
+ lhs, (op, _), rhs = val
931
940
  result = new_call lhs, op.to_sym, argl(rhs)
932
941
  }
933
942
  | rel_expr relop arg =tGT
934
943
  {
935
- lhs, op, rhs = val
944
+ lhs, (op, _), rhs = val
936
945
  warn "comparison '%s' after comparison", op
937
946
  result = new_call lhs, op.to_sym, argl(rhs)
938
947
  }
@@ -1123,8 +1132,9 @@ rule
1123
1132
  | backref
1124
1133
  | tFID
1125
1134
  {
1126
- msg, = val
1135
+ (msg, line), = val
1127
1136
  result = new_call nil, msg.to_sym
1137
+ result.line line
1128
1138
  }
1129
1139
  | k_begin
1130
1140
  {
@@ -1166,15 +1176,15 @@ rule
1166
1176
  }
1167
1177
  | primary_value tCOLON2 tCONSTANT
1168
1178
  {
1169
- expr, _, id = val
1179
+ expr, _, (id, _line) = val
1170
1180
 
1171
1181
  result = s(:colon2, expr, id.to_sym).line expr.line
1172
1182
  }
1173
1183
  | tCOLON3 tCONSTANT
1174
1184
  {
1175
- _, id = val
1185
+ _, (id, line) = val
1176
1186
 
1177
- result = s(:colon3, id.to_sym).line lexer.lineno
1187
+ result = s(:colon3, id.to_sym).line line
1178
1188
  }
1179
1189
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1180
1190
  {
@@ -1221,7 +1231,7 @@ rule
1221
1231
  }
1222
1232
  | kNOT tLPAREN2 rparen
1223
1233
  {
1224
- debug20 14, val, result
1234
+ debug 20
1225
1235
  }
1226
1236
  | fcall brace_block
1227
1237
  {
@@ -1239,9 +1249,10 @@ rule
1239
1249
  iter.insert 1, call # FIX
1240
1250
  result = iter
1241
1251
  }
1242
- | tLAMBDA lambda
1252
+ | lambda
1243
1253
  {
1244
- result = val[1] # TODO: fix lineno
1254
+ expr, = val
1255
+ result = expr
1245
1256
  }
1246
1257
  | k_if expr_value then compstmt if_tail k_end
1247
1258
  {
@@ -1284,7 +1295,6 @@ rule
1284
1295
  }
1285
1296
  cpath superclass
1286
1297
  {
1287
- self.comments.push self.lexer.comments
1288
1298
  if (self.in_def || self.in_single > 0) then
1289
1299
  yyerror "class definition in method body"
1290
1300
  end
@@ -1294,7 +1304,7 @@ rule
1294
1304
  {
1295
1305
  result = new_class val
1296
1306
  self.env.unextend
1297
- self.lexer.comments # we don't care about comments in the body
1307
+ self.lexer.ignore_body_comments
1298
1308
  }
1299
1309
  | k_class tLSHFT
1300
1310
  {
@@ -1315,7 +1325,7 @@ rule
1315
1325
  {
1316
1326
  result = new_sclass val
1317
1327
  self.env.unextend
1318
- self.lexer.comments # we don't care about comments in the body
1328
+ self.lexer.ignore_body_comments
1319
1329
  }
1320
1330
  | k_module
1321
1331
  {
@@ -1323,7 +1333,6 @@ rule
1323
1333
  }
1324
1334
  cpath
1325
1335
  {
1326
- self.comments.push self.lexer.comments
1327
1336
  yyerror "module definition in method body" if
1328
1337
  self.in_def or self.in_single > 0
1329
1338
 
@@ -1333,7 +1342,7 @@ rule
1333
1342
  {
1334
1343
  result = new_module val
1335
1344
  self.env.unextend
1336
- self.lexer.comments # we don't care about comments in the body
1345
+ self.lexer.ignore_body_comments
1337
1346
  }
1338
1347
  | k_def fname
1339
1348
  {
@@ -1343,21 +1352,17 @@ rule
1343
1352
  self.env.extend
1344
1353
  lexer.cmdarg.push false
1345
1354
  lexer.cond.push false
1346
-
1347
- self.comments.push self.lexer.comments
1348
1355
  }
1349
- f_arglist bodystmt { result = lexer.lineno } k_end
1356
+ f_arglist bodystmt k_end
1350
1357
  {
1351
- in_def = val[2]
1352
-
1353
- result = new_defn val
1358
+ result, in_def = new_defn val
1354
1359
 
1355
1360
  lexer.cond.pop # group = local_pop
1356
1361
  lexer.cmdarg.pop
1357
1362
  self.env.unextend
1358
1363
  self.in_def = in_def
1359
1364
 
1360
- self.lexer.comments # we don't care about comments in the body
1365
+ self.lexer.ignore_body_comments
1361
1366
  }
1362
1367
  | k_def singleton dot_or_colon
1363
1368
  {
@@ -1365,7 +1370,7 @@ rule
1365
1370
  }
1366
1371
  fname
1367
1372
  {
1368
- result = [self.in_def, lexer.lineno]
1373
+ result = self.in_def
1369
1374
 
1370
1375
  self.in_single += 1 # TODO: remove?
1371
1376
 
@@ -1375,13 +1380,18 @@ rule
1375
1380
  lexer.cond.push false
1376
1381
 
1377
1382
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1378
- self.comments.push self.lexer.comments
1379
1383
  }
1380
1384
  f_arglist bodystmt k_end
1381
1385
  {
1382
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1383
1386
 
1384
- result = new_defs val
1387
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1388
+ # =>
1389
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1390
+
1391
+ val.delete_at 3
1392
+ val.delete_at 2
1393
+
1394
+ result, in_def = new_defs val
1385
1395
 
1386
1396
  lexer.cond.pop # group = local_pop
1387
1397
  lexer.cmdarg.pop
@@ -1392,7 +1402,7 @@ rule
1392
1402
 
1393
1403
  # TODO: restore cur_arg ? what's cur_arg?
1394
1404
 
1395
- self.lexer.comments # we don't care about comments in the body
1405
+ self.lexer.ignore_body_comments
1396
1406
  }
1397
1407
  | kBREAK
1398
1408
  {
@@ -1429,8 +1439,17 @@ rule
1429
1439
  k_case: kCASE
1430
1440
  k_for: kFOR
1431
1441
  k_class: kCLASS
1442
+ {
1443
+ self.comments.push self.lexer.comments
1444
+ }
1432
1445
  k_module: kMODULE
1446
+ {
1447
+ self.comments.push self.lexer.comments
1448
+ }
1433
1449
  k_def: kDEF
1450
+ {
1451
+ self.comments.push self.lexer.comments
1452
+ }
1434
1453
  k_do: kDO
1435
1454
  k_do_block: kDO_BLOCK
1436
1455
  k_rescue: kRESCUE
@@ -1491,51 +1510,42 @@ rule
1491
1510
 
1492
1511
  result = block_var args
1493
1512
  }
1494
- | f_marg_list tCOMMA tSTAR f_norm_arg
1513
+ | f_marg_list tCOMMA f_rest_marg
1495
1514
  {
1496
- args, _, _, splat = val
1515
+ args, _, rest = val
1497
1516
 
1498
- result = block_var args, "*#{splat}".to_sym
1517
+ result = block_var args, rest
1499
1518
  }
1500
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1519
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1501
1520
  {
1502
- args, _, _, splat, _, args2 = val
1521
+ lhs, _, splat, _, rhs = val
1503
1522
 
1504
- result = block_var args, "*#{splat}".to_sym, args2
1523
+ result = block_var lhs, splat, rhs
1505
1524
  }
1506
- | f_marg_list tCOMMA tSTAR
1525
+ | f_rest_marg
1507
1526
  {
1508
- args, _, _ = val
1527
+ rest, = val
1509
1528
 
1510
- result = block_var args, :*
1529
+ result = block_var rest
1511
1530
  }
1512
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1531
+ | f_rest_marg tCOMMA f_marg_list
1513
1532
  {
1514
- args, _, _, _, args2 = val
1533
+ splat, _, rest = val
1515
1534
 
1516
- result = block_var args, :*, args2
1535
+ result = block_var splat, rest
1517
1536
  }
1518
- | tSTAR f_norm_arg
1519
- {
1520
- _, splat = val
1521
1537
 
1522
- result = block_var :"*#{splat}"
1523
- }
1524
- | tSTAR f_norm_arg tCOMMA f_marg_list
1538
+ f_rest_marg: tSTAR f_norm_arg
1525
1539
  {
1526
- _, splat, _, args = val
1540
+ _, (id, line) = val
1527
1541
 
1528
- result = block_var :"*#{splat}", args
1542
+ result = args ["*#{id}".to_sym]
1543
+ result.line line
1529
1544
  }
1530
1545
  | tSTAR
1531
1546
  {
1532
- result = block_var :*
1533
- }
1534
- | tSTAR tCOMMA f_marg_list
1535
- {
1536
- _, _, args = val
1537
-
1538
- result = block_var :*, args
1547
+ result = args [:*]
1548
+ result.line lexer.lineno # FIX: tSTAR -> line
1539
1549
  }
1540
1550
 
1541
1551
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1552,8 +1562,8 @@ rule
1552
1562
  }
1553
1563
  | f_block_arg
1554
1564
  {
1555
- line = lexer.lineno
1556
- result = call_args val # TODO: push line down
1565
+ (id, line), = val
1566
+ result = call_args [id]
1557
1567
  result.line line
1558
1568
  }
1559
1569
 
@@ -1662,13 +1672,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1662
1672
 
1663
1673
  bvar: tIDENTIFIER
1664
1674
  {
1665
- id, = val
1666
- line = lexer.lineno
1675
+ (id, line), = val
1667
1676
  result = s(:shadow, id.to_sym).line line
1668
1677
  }
1669
1678
  | f_bad_arg
1670
1679
 
1671
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1672
1682
  self.env.extend :dynamic
1673
1683
  result = [lexer.lineno, lexer.lpar_beg]
1674
1684
  lexer.paren_nest += 1
@@ -1680,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1680
1690
  }
1681
1691
  lambda_body
1682
1692
  {
1683
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1684
1694
  lexer.lpar_beg = lpar
1685
1695
 
1686
1696
  lexer.cmdarg.pop
1687
1697
 
1688
1698
  call = s(:lambda).line line
1689
1699
  result = new_iter call, args, body
1690
- result.line = line
1700
+ result.line line
1691
1701
  self.env.unextend # TODO: dynapush & dynapop
1692
1702
  }
1693
1703
 
@@ -1722,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1722
1732
  ## if (nd_type($1) == NODE_YIELD) {
1723
1733
  ## compile_error(PARSER_ARG "block given to yield");
1724
1734
 
1725
- syntax_error "Both block arg and actual block given." if
1726
- val[0].block_pass?
1735
+ cmd, blk = val
1727
1736
 
1728
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1729
1739
 
1730
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1731
1744
 
1732
1745
  result = blk
1733
1746
  result.insert 1, cmd
1734
1747
  }
1735
1748
  | block_call call_op2 operation2 opt_paren_args
1736
1749
  {
1737
- result = new_call val[0], val[2].to_sym, val[3]
1750
+ lhs, _, (id, _line), args = val
1751
+
1752
+ result = new_call lhs, id.to_sym, args
1738
1753
  }
1739
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1740
1755
  {
1741
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1742
1757
 
1743
1758
  call = new_call iter1, name.to_sym, args
1744
1759
  iter2.insert 1, call
@@ -1747,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1747
1762
  }
1748
1763
  | block_call call_op2 operation2 command_args do_block
1749
1764
  {
1750
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1751
1766
 
1752
1767
  call = new_call iter1, name.to_sym, args
1753
1768
  iter2.insert 1, call
@@ -1755,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1755
1770
  result = iter2
1756
1771
  }
1757
1772
 
1758
- method_call: fcall
1759
- {
1760
- result = self.lexer.lineno
1761
- }
1762
- paren_args
1773
+ method_call: fcall paren_args
1763
1774
  {
1764
- call, lineno, args = val
1775
+ call, args = val
1765
1776
 
1766
1777
  result = call.concat args.sexp_body if args
1767
- result.line lineno
1768
1778
  }
1769
1779
  | primary_value call_op operation2 opt_paren_args
1770
1780
  {
1771
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1781
+ recv, call_op, (op, _line), args = val
1782
+
1783
+ result = new_call recv, op.to_sym, args, call_op
1772
1784
  }
1773
1785
  | primary_value tCOLON2 operation2 paren_args
1774
1786
  {
1775
- result = new_call val[0], val[2].to_sym, val[3]
1787
+ recv, _, (op, _line), args = val
1788
+
1789
+ result = new_call recv, op.to_sym, args
1776
1790
  }
1777
1791
  | primary_value tCOLON2 operation3
1778
1792
  {
1779
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1780
1796
  }
1781
1797
  | primary_value call_op paren_args
1782
1798
  {
@@ -1809,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1809
1825
  _, line, body, _ = val
1810
1826
 
1811
1827
  result = body
1812
- result.line = line
1828
+ result.line line
1813
1829
 
1814
1830
  self.env.unextend
1815
1831
  }
@@ -1823,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1823
1839
  _, line, body, _ = val
1824
1840
 
1825
1841
  result = body
1826
- result.line = line
1842
+ result.line line
1827
1843
 
1828
1844
  self.env.unextend
1829
1845
  }
@@ -1852,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1852
1868
  self.env.unextend
1853
1869
  }
1854
1870
 
1871
+ case_args: arg_value
1872
+ {
1873
+ arg, = val
1874
+
1875
+ result = s(:array, arg).line arg.line
1876
+ }
1877
+ | tSTAR arg_value
1878
+ {
1879
+ _, arg = val
1880
+
1881
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1882
+ }
1883
+ | case_args tCOMMA arg_value
1884
+ {
1885
+ args, _, id = val
1886
+
1887
+ result = self.list_append args, id
1888
+ }
1889
+ | case_args tCOMMA tSTAR arg_value
1890
+ {
1891
+ args, _, _, id = val
1892
+
1893
+ result = self.list_append args, s(:splat, id).line(id.line)
1894
+ }
1895
+
1855
1896
  case_body: k_when
1856
1897
  {
1857
1898
  result = self.lexer.lineno
1858
1899
  }
1859
- args then compstmt cases
1900
+ case_args then compstmt cases
1860
1901
  {
1861
1902
  result = new_when(val[2], val[4])
1862
- result.line = val[1]
1903
+ result.line val[1]
1863
1904
  result << val[5] if val[5]
1864
1905
  }
1865
1906
 
@@ -1905,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1905
1946
 
1906
1947
  literal: numeric
1907
1948
  {
1908
- line = lexer.lineno
1909
- result = s(:lit, val[0])
1910
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1911
1951
  }
1912
1952
  | symbol
1913
- {
1914
- line = lexer.lineno
1915
- result = s(:lit, val[0])
1916
- result.line = line
1917
- }
1918
- | dsym
1919
1953
 
1920
1954
  strings: string
1921
1955
  {
@@ -1926,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1926
1960
 
1927
1961
  string: tCHAR
1928
1962
  {
1929
- debug20 23, val, result
1963
+ debug 37
1930
1964
  }
1931
1965
  | string1
1932
1966
  | string string1
@@ -1936,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1936
1970
 
1937
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1938
1972
  {
1939
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1940
1974
 
1941
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1942
1976
 
1943
- result = str
1977
+ result = str.line line
1944
1978
  }
1945
1979
  | tSTRING
1946
1980
  {
@@ -1960,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1960
1994
 
1961
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1962
1996
  {
1963
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1964
2000
  }
1965
2001
  | tWORDS_BEG word_list tSTRING_END
1966
2002
  {
1967
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1968
2006
  }
1969
2007
 
1970
2008
  word_list: none
@@ -1984,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1984
2022
 
1985
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1986
2024
  {
1987
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1988
2028
  }
1989
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1990
2030
  {
1991
- _, line, list, _, = val
1992
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1993
2033
  result = list
1994
2034
  }
1995
2035
 
1996
2036
  symbol_list: none
1997
2037
  {
1998
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1999
2039
  }
2000
2040
  | symbol_list word tSPACE
2001
2041
  {
@@ -2005,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2005
2045
 
2006
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2007
2047
  {
2008
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2009
2051
  }
2010
2052
  | tQWORDS_BEG qword_list tSTRING_END
2011
2053
  {
2012
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2013
2057
  }
2014
2058
 
2015
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2016
2060
  {
2017
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2018
2064
  }
2019
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2020
2066
  {
2021
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2022
2070
  }
2023
2071
 
2024
2072
  qword_list: none
@@ -2041,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2041
2089
 
2042
2090
  string_contents: none
2043
2091
  {
2044
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2045
2094
  }
2046
2095
  | string_contents string_content
2047
2096
  {
@@ -2116,8 +2165,8 @@ regexp_contents: none
2116
2165
  lexer.brace_nest = brace_nest
2117
2166
  lexer.string_nest = string_nest
2118
2167
 
2119
- lexer.cmdarg.pop
2120
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2121
2170
 
2122
2171
  lexer.lex_state = oldlex_state
2123
2172
 
@@ -2132,29 +2181,49 @@ regexp_contents: none
2132
2181
  when nil then
2133
2182
  result = s(:evstr).line line
2134
2183
  else
2135
- debug20 25
2184
+ debug 38
2136
2185
  raise "unknown string body: #{stmt.inspect}"
2137
2186
  end
2138
2187
  }
2139
2188
 
2140
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2141
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2142
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2189
+ string_dvar: tGVAR
2190
+ {
2191
+ (id, line), = val
2192
+ result = s(:gvar, id.to_sym).line line
2193
+ }
2194
+ | tIVAR
2195
+ {
2196
+ (id, line), = val
2197
+ result = s(:ivar, id.to_sym).line line
2198
+ }
2199
+ | tCVAR
2200
+ {
2201
+ (id, line), = val
2202
+ result = s(:cvar, id.to_sym).line line
2203
+ }
2143
2204
  | backref
2144
2205
 
2145
- symbol: tSYMBEG sym
2206
+ symbol: ssym
2207
+ | dsym
2208
+
2209
+ ssym: tSYMBEG sym
2146
2210
  {
2211
+ _, (id, line) = val
2212
+
2147
2213
  lexer.lex_state = EXPR_END
2148
- result = val[1].to_sym
2214
+ result = s(:lit, id.to_sym).line line
2149
2215
  }
2150
2216
  | tSYMBOL
2151
2217
  {
2152
- result = val[0].to_sym
2218
+ (id, line), = val
2219
+
2220
+ lexer.lex_state = EXPR_END
2221
+ result = s(:lit, id.to_sym).line line
2153
2222
  }
2154
2223
 
2155
2224
  sym: fname | tIVAR | tGVAR | tCVAR
2156
2225
 
2157
- dsym: tSYMBEG xstring_contents tSTRING_END
2226
+ dsym: tSYMBEG string_contents tSTRING_END
2158
2227
  {
2159
2228
  _, result, _ = val
2160
2229
 
@@ -2170,14 +2239,15 @@ regexp_contents: none
2170
2239
  when :evstr then
2171
2240
  result = s(:dsym, "", result).line result.line
2172
2241
  else
2173
- debug20 26, val, result
2242
+ debug 39
2174
2243
  end
2175
2244
  }
2176
2245
 
2177
2246
  numeric: simple_numeric
2178
- | tUMINUS_NUM simple_numeric
2247
+ | tUMINUS_NUM simple_numeric =tLOWEST
2179
2248
  {
2180
- result = -val[1] # TODO: pt_testcase
2249
+ _, (num, line) = val
2250
+ result = [-num, line]
2181
2251
  }
2182
2252
 
2183
2253
  simple_numeric: tINTEGER
@@ -2210,8 +2280,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2210
2280
 
2211
2281
  var_ref: user_variable
2212
2282
  {
2213
- var = val[0]
2283
+ raise "NO: #{val.inspect}" if Sexp === val.first
2284
+ (var, line), = val
2214
2285
  result = Sexp === var ? var : self.gettable(var)
2286
+ result.line line
2215
2287
  }
2216
2288
  | keyword_variable
2217
2289
  {
@@ -2226,11 +2298,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2226
2298
  | keyword_variable
2227
2299
  {
2228
2300
  result = self.assignable val[0]
2229
- debug20 29, val, result
2301
+ debug 40
2230
2302
  }
2231
2303
 
2232
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2233
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2304
+ backref: tNTH_REF
2305
+ {
2306
+ (ref, line), = val
2307
+ result = s(:nth_ref, ref).line line
2308
+ }
2309
+ | tBACK_REF
2310
+ {
2311
+ (ref, line), = val
2312
+ result = s(:back_ref, ref).line line
2313
+ }
2234
2314
 
2235
2315
  superclass: tLT
2236
2316
  {
@@ -2248,9 +2328,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2248
2328
 
2249
2329
  f_arglist: tLPAREN2 f_args rparen
2250
2330
  {
2251
- result = val[1]
2252
- self.lexer.lex_state = EXPR_BEG
2253
- self.lexer.command_start = true
2331
+ result = end_args val
2254
2332
  }
2255
2333
  | {
2256
2334
  result = self.in_kwarg
@@ -2259,12 +2337,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2259
2337
  }
2260
2338
  f_args term
2261
2339
  {
2262
- kwarg, args, _ = val
2263
-
2264
- self.in_kwarg = kwarg
2265
- result = args
2266
- lexer.lex_state = EXPR_BEG
2267
- lexer.command_start = true
2340
+ result = end_args val
2268
2341
  }
2269
2342
 
2270
2343
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2349,6 +2422,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2349
2422
  |
2350
2423
  {
2351
2424
  result = args val
2425
+ # result.line lexer.lineno
2352
2426
  }
2353
2427
 
2354
2428
 
@@ -2372,10 +2446,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2372
2446
  f_norm_arg: f_bad_arg
2373
2447
  | tIDENTIFIER
2374
2448
  {
2375
- identifier = val[0].to_sym
2449
+ (id, line), = val
2450
+ identifier = id.to_sym
2376
2451
  self.env[identifier] = :lvar
2377
2452
 
2378
- result = identifier
2453
+ result = [identifier, line]
2379
2454
  }
2380
2455
 
2381
2456
  f_arg_asgn: f_norm_arg
@@ -2383,22 +2458,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2383
2458
  f_arg_item: f_arg_asgn
2384
2459
  | tLPAREN f_margs rparen
2385
2460
  {
2386
- result = val[1]
2461
+ _, margs, _ = val
2462
+
2463
+ result = margs
2387
2464
  }
2388
2465
 
2389
2466
  f_arg: f_arg_item
2390
2467
  {
2391
- arg, = val
2392
-
2393
- case arg
2394
- when Symbol then
2395
- result = s(:args, arg).line lexer.lineno
2396
- when Sexp then
2397
- result = arg
2398
- else
2399
- debug20 32
2400
- raise "Unknown f_arg type: #{val.inspect}"
2401
- end
2468
+ result = new_arg val
2402
2469
  }
2403
2470
  | f_arg tCOMMA f_arg_item
2404
2471
  {
@@ -2410,7 +2477,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2410
2477
  result = s(:args, list).line list.line
2411
2478
  end
2412
2479
 
2413
- result << item
2480
+ result << (Sexp === item ? item : item.first)
2414
2481
  }
2415
2482
 
2416
2483
  f_label: tLABEL
@@ -2471,27 +2538,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2471
2538
  kwrest_mark: tPOW
2472
2539
  | tDSTAR
2473
2540
 
2541
+
2474
2542
  f_kwrest: kwrest_mark tIDENTIFIER
2475
2543
  {
2476
- name = val[1].to_sym
2477
- self.assignable name
2478
- result = :"**#{name}"
2544
+ _, (id, line) = val
2545
+
2546
+ name = id.to_sym
2547
+ self.assignable [name, line]
2548
+ result = [:"**#{name}", line]
2479
2549
  }
2480
2550
  | kwrest_mark
2481
2551
  {
2482
- result = :"**"
2483
- self.env[result] = :lvar
2552
+ id = :"**"
2553
+ self.env[id] = :lvar # TODO: needed?!?
2554
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2484
2555
  }
2485
2556
 
2486
2557
  f_opt: f_arg_asgn tEQL arg_value
2487
2558
  {
2488
- result = self.assignable val[0], val[2]
2559
+ lhs, _, rhs = val
2560
+ result = self.assignable lhs, rhs
2489
2561
  # TODO: detect duplicate names
2490
2562
  }
2491
2563
 
2492
2564
  f_block_opt: f_arg_asgn tEQL primary_value
2493
2565
  {
2494
- result = self.assignable val[0], val[2]
2566
+ lhs, _, rhs = val
2567
+ result = self.assignable lhs, rhs
2495
2568
  }
2496
2569
 
2497
2570
  f_block_optarg: f_block_opt
@@ -2521,30 +2594,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2521
2594
  f_rest_arg: restarg_mark tIDENTIFIER
2522
2595
  {
2523
2596
  # TODO: differs from parse.y - needs tests
2524
- name = val[1].to_sym
2525
- self.assignable name
2526
- result = :"*#{name}"
2597
+ _, (id, line) = val
2598
+ name = id.to_sym
2599
+ self.assignable [name, line]
2600
+ result = [:"*#{name}", line]
2527
2601
  }
2528
2602
  | restarg_mark
2529
2603
  {
2530
2604
  name = :"*"
2531
2605
  self.env[name] = :lvar
2532
- result = name
2606
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2533
2607
  }
2534
2608
 
2535
2609
  blkarg_mark: tAMPER2 | tAMPER
2536
2610
 
2537
2611
  f_block_arg: blkarg_mark tIDENTIFIER
2538
2612
  {
2539
- identifier = val[1].to_sym
2613
+ _, (id, line) = val
2614
+ identifier = id.to_sym
2540
2615
 
2541
2616
  self.env[identifier] = :lvar
2542
- result = "&#{identifier}".to_sym
2617
+ result = ["&#{identifier}".to_sym, line]
2543
2618
  }
2544
2619
 
2545
2620
  opt_f_block_arg: tCOMMA f_block_arg
2546
2621
  {
2547
- result = val[1]
2622
+ _, arg = val
2623
+ result = arg
2548
2624
  }
2549
2625
  |
2550
2626
  {
@@ -2593,9 +2669,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2593
2669
  }
2594
2670
  | tSTRING_BEG string_contents tLABEL_END arg_value
2595
2671
  {
2596
- _, sym, _, value = val
2672
+ (_, line), sym, _, value = val
2673
+
2597
2674
  sym.sexp_type = :dsym
2598
- result = s(:array, sym, value).line sym.line
2675
+
2676
+ result = s(:array, sym, value).line line
2599
2677
  }
2600
2678
  | tDSTAR arg_value
2601
2679
  {