ruby_parser 3.17.0 → 3.18.0

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