ruby_parser 3.15.1 → 3.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/ruby25_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
@@ -33,7 +33,7 @@ preclow
33
33
  right tEQL tOP_ASGN
34
34
  left kRESCUE_MOD
35
35
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
36
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
37
  left tOROP
38
38
  left tANDOP
39
39
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +56,9 @@ rule
56
56
  top_compstmt
57
57
  {
58
58
  result = new_compstmt val
59
+
60
+ lexer.cond.pop # local_pop
61
+ lexer.cmdarg.pop
59
62
  }
60
63
 
61
64
  top_compstmt: top_stmts opt_terms
@@ -76,7 +79,7 @@ rule
76
79
  | klBEGIN
77
80
  {
78
81
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
82
+ debug 11
80
83
  yyerror "BEGIN in method"
81
84
  end
82
85
  self.env.extend
@@ -101,7 +104,9 @@ rule
101
104
  bodystmt: compstmt opt_rescue k_else
102
105
  {
103
106
  res = _values[-2]
104
- 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
105
110
  }
106
111
  compstmt
107
112
  opt_ensure
@@ -131,7 +136,7 @@ rule
131
136
  | error stmt
132
137
  {
133
138
  result = val[1]
134
- debug20 2, val, result
139
+ debug 12
135
140
  }
136
141
 
137
142
  stmt_or_begin: stmt
@@ -139,6 +144,10 @@ rule
139
144
  {
140
145
  yyerror "BEGIN is permitted only at toplevel"
141
146
  }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
150
+ }
142
151
 
143
152
  stmt: kALIAS fitem
144
153
  {
@@ -151,12 +160,12 @@ rule
151
160
  }
152
161
  | kALIAS tGVAR tGVAR
153
162
  {
154
- (_, line), lhs, rhs = val
163
+ (_, line), (lhs, _), (rhs, _) = val
155
164
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
165
  }
157
166
  | kALIAS tGVAR tBACK_REF
158
167
  {
159
- (_, line), lhs, rhs = val
168
+ (_, line), (lhs, _), (rhs, _) = val
160
169
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
170
  }
162
171
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +208,7 @@ rule
199
208
  (_, line), _, stmt, _ = val
200
209
 
201
210
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
211
+ debug 13
203
212
  yyerror "END in method; use at_exit"
204
213
  end
205
214
 
@@ -239,32 +248,31 @@ rule
239
248
  }
240
249
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
250
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
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
248
256
  }
249
257
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
258
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
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
256
264
  }
257
265
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
266
  {
259
- lhs1, _, lhs2, op, rhs = val
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
268
 
261
- 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
262
270
  }
263
271
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
272
  {
265
- lhs1, _, lhs2, op, rhs = val
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
274
 
267
- 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
268
276
  }
269
277
  | backref tOP_ASGN command_rhs
270
278
  {
@@ -310,7 +318,7 @@ rule
310
318
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
319
  # REFACTOR: call_uni_op -- see parse26.y
312
320
  }
313
- | arg
321
+ | arg =tLBRACE_ARG
314
322
 
315
323
  expr_value: expr
316
324
  {
@@ -335,7 +343,7 @@ rule
335
343
  block_command: block_call
336
344
  | block_call call_op2 operation2 command_args
337
345
  {
338
- blk, _, msg, args = val
346
+ blk, _, (msg, _line), args = val
339
347
  result = new_call(blk, msg.to_sym, args).line blk.line
340
348
  }
341
349
 
@@ -349,15 +357,15 @@ rule
349
357
  _, line, body, _ = val
350
358
 
351
359
  result = body
352
- result.line = line
360
+ result.line line
353
361
 
354
362
  # self.env.unextend
355
363
  }
356
364
 
357
365
  fcall: operation
358
366
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
367
+ (msg, line), = val
368
+ result = new_call(nil, msg.to_sym).line line
361
369
  }
362
370
 
363
371
  command: fcall command_args =tLOWEST
@@ -380,12 +388,14 @@ rule
380
388
  }
381
389
  | primary_value call_op operation2 command_args =tLOWEST
382
390
  {
383
- lhs, callop, op, args = val
391
+ lhs, callop, (op, _), args = val
392
+
384
393
  result = new_call lhs, op.to_sym, args, callop
394
+ result.line lhs.line
385
395
  }
386
396
  | primary_value call_op operation2 command_args cmd_brace_block
387
397
  {
388
- recv, _, msg, args, block = val
398
+ recv, _, (msg, _line), args, block = val
389
399
  call = new_call recv, msg.to_sym, args, val[1]
390
400
 
391
401
  block_dup_check call, block
@@ -395,11 +405,14 @@ rule
395
405
  }
396
406
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
407
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
408
+ lhs, _, (id, line), args = val
409
+
410
+ result = new_call lhs, id.to_sym, args
411
+ result.line line
399
412
  }
400
413
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
414
  {
402
- recv, _, msg, args, block = val
415
+ recv, _, (msg, _line), args, block = val
403
416
  call = new_call recv, msg.to_sym, args
404
417
 
405
418
  block_dup_check call, block
@@ -557,25 +570,29 @@ rule
557
570
  }
558
571
  | primary_value call_op tIDENTIFIER
559
572
  {
560
- result = new_attrasgn val[0], val[2], val[1]
573
+ lhs, call_op, (id, _line) = val
574
+
575
+ result = new_attrasgn lhs, id, call_op
561
576
  }
562
577
  | primary_value tCOLON2 tIDENTIFIER
563
578
  {
564
- recv, _, id = val
579
+ recv, _, (id, _line) = val
565
580
  result = new_attrasgn recv, id
566
581
  }
567
582
  | primary_value call_op tCONSTANT
568
583
  {
569
- result = new_attrasgn val[0], val[2], val[1]
584
+ lhs, call_op, (id, _line) = val
585
+
586
+ result = new_attrasgn lhs, id, call_op
570
587
  }
571
588
  | primary_value tCOLON2 tCONSTANT
572
589
  {
573
590
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
591
+ debug 14
575
592
  yyerror "dynamic constant assignment"
576
593
  end
577
594
 
578
- expr, _, id = val
595
+ expr, _, (id, _line) = val
579
596
  l = expr.line
580
597
 
581
598
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +600,65 @@ rule
583
600
  | tCOLON3 tCONSTANT
584
601
  {
585
602
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
603
+ debug 15
587
604
  yyerror "dynamic constant assignment"
588
605
  end
589
606
 
590
- _, id = val
591
- l = lexer.lineno
607
+ _, (id, l) = val
592
608
 
593
609
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
610
  }
595
611
  | backref
596
612
  {
597
- self.backref_assign_error val[0]
613
+ ref, = val
614
+
615
+ self.backref_assign_error ref
598
616
  }
599
617
 
600
618
  lhs: user_variable
601
619
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
620
+ var, = val
621
+
622
+ result = self.assignable var
605
623
  }
606
624
  | keyword_variable
607
625
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
626
+ var, = val
627
+
628
+ result = self.assignable var
629
+
630
+ debug 16
612
631
  }
613
632
  | primary_value tLBRACK2 opt_call_args rbracket
614
633
  {
615
634
  lhs, _, args, _ = val
635
+
616
636
  result = self.aryset lhs, args
617
637
  }
618
638
  | primary_value call_op tIDENTIFIER # REFACTOR
619
639
  {
620
- lhs, op, id = val
640
+ lhs, op, (id, _line) = val
641
+
621
642
  result = new_attrasgn lhs, id, op
622
643
  }
623
644
  | primary_value tCOLON2 tIDENTIFIER
624
645
  {
625
- lhs, _, id = val
646
+ lhs, _, (id, _line) = val
647
+
626
648
  result = new_attrasgn lhs, id
627
649
  }
628
650
  | primary_value call_op tCONSTANT # REFACTOR?
629
651
  {
630
- result = new_attrasgn val[0], val[2], val[1]
652
+ lhs, call_op, (id, _line) = val
653
+
654
+ result = new_attrasgn lhs, id, call_op
631
655
  }
632
656
  | primary_value tCOLON2 tCONSTANT
633
657
  {
634
- expr, _, id = val
658
+ expr, _, (id, _line) = val
635
659
 
636
660
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
661
+ debug 17
638
662
  yyerror "dynamic constant assignment"
639
663
  end
640
664
 
@@ -643,14 +667,13 @@ rule
643
667
  }
644
668
  | tCOLON3 tCONSTANT
645
669
  {
646
- _, id = val
670
+ _, (id, l) = val
647
671
 
648
672
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
673
+ debug 18
650
674
  yyerror "dynamic constant assignment"
651
675
  end
652
676
 
653
- l = lexer.lineno
654
677
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
678
  }
656
679
  | backref
@@ -666,16 +689,17 @@ rule
666
689
 
667
690
  cpath: tCOLON3 cname
668
691
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
692
+ _, (name, line) = val
693
+ result = s(:colon3, name.to_sym).line line
671
694
  }
672
695
  | cname
673
696
  {
674
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
675
699
  }
676
700
  | primary_value tCOLON2 cname
677
701
  {
678
- pval, _, name = val
702
+ pval, _, (name, _line) = val
679
703
 
680
704
  result = s(:colon2, pval, name.to_sym)
681
705
  result.line pval.line
@@ -685,24 +709,17 @@ rule
685
709
  | op
686
710
  {
687
711
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
712
  }
690
713
 
691
714
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
715
 
698
- fsym: fname | symbol
699
-
700
- fitem: fsym
716
+ fitem: fname
701
717
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
718
+ (id, line), = val
719
+
720
+ result = s(:lit, id.to_sym).line line
704
721
  }
705
- | dsym
722
+ | symbol
706
723
 
707
724
  undef_list: fitem
708
725
  {
@@ -723,8 +740,6 @@ rule
723
740
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
741
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
742
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
743
 
729
744
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
745
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,24 +773,20 @@ rule
758
773
  }
759
774
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
775
  {
761
- lhs, _, id, op, rhs = val
776
+ lhs, _, (id, _line), (op, _), rhs = val
762
777
 
763
778
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
779
  }
765
780
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
781
  {
767
- lhs1, _, lhs2, op, rhs = val
782
+ lhs1, _, (lhs2, _line), op, rhs = val
768
783
 
769
784
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
785
  result = new_const_op_asgn [lhs, op, rhs]
771
786
  }
772
- | tCOLON3 tCONSTANT
787
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
788
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
789
+ _, (lhs, line), op, rhs = val
779
790
 
780
791
  lhs = s(:colon3, lhs.to_sym).line line
781
792
  result = new_const_op_asgn [lhs, op, rhs]
@@ -789,7 +800,7 @@ rule
789
800
  | arg tDOT2 arg
790
801
  {
791
802
  v1, v2 = val[0], val[2]
792
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
804
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
805
  else
795
806
  result = s(:dot2, v1, v2).line v1.line
@@ -798,12 +809,14 @@ rule
798
809
  | arg tDOT3 arg
799
810
  {
800
811
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
812
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
813
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
814
  else
804
815
  result = s(:dot3, v1, v2).line v1.line
805
816
  end
806
817
  }
818
+
819
+
807
820
  | arg tPLUS arg
808
821
  {
809
822
  result = new_call val[0], :+, argl(val[2])
@@ -830,8 +843,9 @@ rule
830
843
  }
831
844
  | tUMINUS_NUM simple_numeric tPOW arg
832
845
  {
833
- lit = s(:lit, val[1]).line lexer.lineno
834
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
846
+ _, (num, line), _, arg = val
847
+ lit = s(:lit, num).line line
848
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
835
849
 
836
850
  }
837
851
  | tUPLUS arg
@@ -930,12 +944,12 @@ rule
930
944
 
931
945
  rel_expr: arg relop arg =tGT
932
946
  {
933
- lhs, op, rhs = val
947
+ lhs, (op, _), rhs = val
934
948
  result = new_call lhs, op.to_sym, argl(rhs)
935
949
  }
936
950
  | rel_expr relop arg =tGT
937
951
  {
938
- lhs, op, rhs = val
952
+ lhs, (op, _), rhs = val
939
953
  warn "comparison '%s' after comparison", op
940
954
  result = new_call lhs, op.to_sym, argl(rhs)
941
955
  }
@@ -1126,8 +1140,9 @@ rule
1126
1140
  | backref
1127
1141
  | tFID
1128
1142
  {
1129
- msg, = val
1143
+ (msg, line), = val
1130
1144
  result = new_call nil, msg.to_sym
1145
+ result.line line
1131
1146
  }
1132
1147
  | k_begin
1133
1148
  {
@@ -1169,15 +1184,15 @@ rule
1169
1184
  }
1170
1185
  | primary_value tCOLON2 tCONSTANT
1171
1186
  {
1172
- expr, _, id = val
1187
+ expr, _, (id, _line) = val
1173
1188
 
1174
1189
  result = s(:colon2, expr, id.to_sym).line expr.line
1175
1190
  }
1176
1191
  | tCOLON3 tCONSTANT
1177
1192
  {
1178
- _, id = val
1193
+ _, (id, line) = val
1179
1194
 
1180
- result = s(:colon3, id.to_sym).line lexer.lineno
1195
+ result = s(:colon3, id.to_sym).line line
1181
1196
  }
1182
1197
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1183
1198
  {
@@ -1201,15 +1216,21 @@ rule
1201
1216
  }
1202
1217
  | kYIELD tLPAREN2 call_args rparen
1203
1218
  {
1204
- result = new_yield val[2]
1219
+ (_, line), _, args, _ = val
1220
+
1221
+ result = new_yield(args).line line
1205
1222
  }
1206
1223
  | kYIELD tLPAREN2 rparen
1207
1224
  {
1208
- result = new_yield
1225
+ (_, line), _, _ = val
1226
+
1227
+ result = new_yield.line line
1209
1228
  }
1210
1229
  | kYIELD
1211
1230
  {
1212
- result = new_yield
1231
+ (_, line), = val
1232
+
1233
+ result = new_yield.line line
1213
1234
  }
1214
1235
  | kDEFINED opt_nl tLPAREN2 expr rparen
1215
1236
  {
@@ -1224,7 +1245,7 @@ rule
1224
1245
  }
1225
1246
  | kNOT tLPAREN2 rparen
1226
1247
  {
1227
- debug20 14, val, result
1248
+ debug 20
1228
1249
  }
1229
1250
  | fcall brace_block
1230
1251
  {
@@ -1242,9 +1263,10 @@ rule
1242
1263
  iter.insert 1, call # FIX
1243
1264
  result = iter
1244
1265
  }
1245
- | tLAMBDA lambda
1266
+ | lambda
1246
1267
  {
1247
- result = val[1] # TODO: fix lineno
1268
+ expr, = val
1269
+ result = expr
1248
1270
  }
1249
1271
  | k_if expr_value then compstmt if_tail k_end
1250
1272
  {
@@ -1287,7 +1309,6 @@ rule
1287
1309
  }
1288
1310
  cpath superclass
1289
1311
  {
1290
- self.comments.push self.lexer.comments
1291
1312
  if (self.in_def || self.in_single > 0) then
1292
1313
  yyerror "class definition in method body"
1293
1314
  end
@@ -1297,7 +1318,7 @@ rule
1297
1318
  {
1298
1319
  result = new_class val
1299
1320
  self.env.unextend
1300
- self.lexer.comments # we don't care about comments in the body
1321
+ self.lexer.ignore_body_comments
1301
1322
  }
1302
1323
  | k_class tLSHFT
1303
1324
  {
@@ -1318,7 +1339,7 @@ rule
1318
1339
  {
1319
1340
  result = new_sclass val
1320
1341
  self.env.unextend
1321
- self.lexer.comments # we don't care about comments in the body
1342
+ self.lexer.ignore_body_comments
1322
1343
  }
1323
1344
  | k_module
1324
1345
  {
@@ -1326,7 +1347,6 @@ rule
1326
1347
  }
1327
1348
  cpath
1328
1349
  {
1329
- self.comments.push self.lexer.comments
1330
1350
  yyerror "module definition in method body" if
1331
1351
  self.in_def or self.in_single > 0
1332
1352
 
@@ -1336,7 +1356,7 @@ rule
1336
1356
  {
1337
1357
  result = new_module val
1338
1358
  self.env.unextend
1339
- self.lexer.comments # we don't care about comments in the body
1359
+ self.lexer.ignore_body_comments
1340
1360
  }
1341
1361
  | k_def fname
1342
1362
  {
@@ -1346,21 +1366,17 @@ rule
1346
1366
  self.env.extend
1347
1367
  lexer.cmdarg.push false
1348
1368
  lexer.cond.push false
1349
-
1350
- self.comments.push self.lexer.comments
1351
1369
  }
1352
- f_arglist bodystmt { result = lexer.lineno } k_end
1370
+ f_arglist bodystmt k_end
1353
1371
  {
1354
- in_def = val[2]
1355
-
1356
- result = new_defn val
1372
+ result, in_def = new_defn val
1357
1373
 
1358
1374
  lexer.cond.pop # group = local_pop
1359
1375
  lexer.cmdarg.pop
1360
1376
  self.env.unextend
1361
1377
  self.in_def = in_def
1362
1378
 
1363
- self.lexer.comments # we don't care about comments in the body
1379
+ self.lexer.ignore_body_comments
1364
1380
  }
1365
1381
  | k_def singleton dot_or_colon
1366
1382
  {
@@ -1368,7 +1384,7 @@ rule
1368
1384
  }
1369
1385
  fname
1370
1386
  {
1371
- result = [self.in_def, lexer.lineno]
1387
+ result = self.in_def
1372
1388
 
1373
1389
  self.in_single += 1 # TODO: remove?
1374
1390
 
@@ -1378,13 +1394,18 @@ rule
1378
1394
  lexer.cond.push false
1379
1395
 
1380
1396
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1381
- self.comments.push self.lexer.comments
1382
1397
  }
1383
1398
  f_arglist bodystmt k_end
1384
1399
  {
1385
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1386
1400
 
1387
- result = new_defs val
1401
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1402
+ # =>
1403
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1404
+
1405
+ val.delete_at 3
1406
+ val.delete_at 2
1407
+
1408
+ result, in_def = new_defs val
1388
1409
 
1389
1410
  lexer.cond.pop # group = local_pop
1390
1411
  lexer.cmdarg.pop
@@ -1395,7 +1416,7 @@ rule
1395
1416
 
1396
1417
  # TODO: restore cur_arg ? what's cur_arg?
1397
1418
 
1398
- self.lexer.comments # we don't care about comments in the body
1419
+ self.lexer.ignore_body_comments
1399
1420
  }
1400
1421
  | kBREAK
1401
1422
  {
@@ -1432,8 +1453,17 @@ rule
1432
1453
  k_case: kCASE
1433
1454
  k_for: kFOR
1434
1455
  k_class: kCLASS
1456
+ {
1457
+ self.comments.push self.lexer.comments
1458
+ }
1435
1459
  k_module: kMODULE
1460
+ {
1461
+ self.comments.push self.lexer.comments
1462
+ }
1436
1463
  k_def: kDEF
1464
+ {
1465
+ self.comments.push self.lexer.comments
1466
+ }
1437
1467
  k_do: kDO
1438
1468
  k_do_block: kDO_BLOCK
1439
1469
  k_rescue: kRESCUE
@@ -1494,51 +1524,42 @@ rule
1494
1524
 
1495
1525
  result = block_var args
1496
1526
  }
1497
- | f_marg_list tCOMMA tSTAR f_norm_arg
1527
+ | f_marg_list tCOMMA f_rest_marg
1498
1528
  {
1499
- args, _, _, splat = val
1529
+ args, _, rest = val
1500
1530
 
1501
- result = block_var args, "*#{splat}".to_sym
1531
+ result = block_var args, rest
1502
1532
  }
1503
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1533
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1504
1534
  {
1505
- args, _, _, splat, _, args2 = val
1535
+ lhs, _, splat, _, rhs = val
1506
1536
 
1507
- result = block_var args, "*#{splat}".to_sym, args2
1537
+ result = block_var lhs, splat, rhs
1508
1538
  }
1509
- | f_marg_list tCOMMA tSTAR
1539
+ | f_rest_marg
1510
1540
  {
1511
- args, _, _ = val
1541
+ rest, = val
1512
1542
 
1513
- result = block_var args, :*
1543
+ result = block_var rest
1514
1544
  }
1515
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1545
+ | f_rest_marg tCOMMA f_marg_list
1516
1546
  {
1517
- args, _, _, _, args2 = val
1547
+ splat, _, rest = val
1518
1548
 
1519
- result = block_var args, :*, args2
1549
+ result = block_var splat, rest
1520
1550
  }
1521
- | tSTAR f_norm_arg
1522
- {
1523
- _, splat = val
1524
1551
 
1525
- result = block_var :"*#{splat}"
1526
- }
1527
- | tSTAR f_norm_arg tCOMMA f_marg_list
1552
+ f_rest_marg: tSTAR f_norm_arg
1528
1553
  {
1529
- _, splat, _, args = val
1554
+ _, (id, line) = val
1530
1555
 
1531
- result = block_var :"*#{splat}", args
1556
+ result = args ["*#{id}".to_sym]
1557
+ result.line line
1532
1558
  }
1533
1559
  | tSTAR
1534
1560
  {
1535
- result = block_var :*
1536
- }
1537
- | tSTAR tCOMMA f_marg_list
1538
- {
1539
- _, _, args = val
1540
-
1541
- result = block_var :*, args
1561
+ result = args [:*]
1562
+ result.line lexer.lineno # FIX: tSTAR -> line
1542
1563
  }
1543
1564
 
1544
1565
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1555,8 +1576,8 @@ rule
1555
1576
  }
1556
1577
  | f_block_arg
1557
1578
  {
1558
- line = lexer.lineno
1559
- result = call_args val # TODO: push line down
1579
+ (id, line), = val
1580
+ result = call_args [id]
1560
1581
  result.line line
1561
1582
  }
1562
1583
 
@@ -1665,13 +1686,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1665
1686
 
1666
1687
  bvar: tIDENTIFIER
1667
1688
  {
1668
- id, = val
1669
- line = lexer.lineno
1689
+ (id, line), = val
1670
1690
  result = s(:shadow, id.to_sym).line line
1671
1691
  }
1672
1692
  | f_bad_arg
1673
1693
 
1674
- lambda: {
1694
+ lambda: tLAMBDA
1695
+ {
1675
1696
  self.env.extend :dynamic
1676
1697
  result = [lexer.lineno, lexer.lpar_beg]
1677
1698
  lexer.paren_nest += 1
@@ -1683,14 +1704,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1683
1704
  }
1684
1705
  lambda_body
1685
1706
  {
1686
- (line, lpar), args, _cmdarg, body = val
1707
+ _, (line, lpar), args, _cmdarg, body = val
1687
1708
  lexer.lpar_beg = lpar
1688
1709
 
1689
1710
  lexer.cmdarg.pop
1690
1711
 
1691
1712
  call = s(:lambda).line line
1692
1713
  result = new_iter call, args, body
1693
- result.line = line
1714
+ result.line line
1694
1715
  self.env.unextend # TODO: dynapush & dynapop
1695
1716
  }
1696
1717
 
@@ -1725,23 +1746,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1725
1746
  ## if (nd_type($1) == NODE_YIELD) {
1726
1747
  ## compile_error(PARSER_ARG "block given to yield");
1727
1748
 
1728
- syntax_error "Both block arg and actual block given." if
1729
- val[0].block_pass?
1749
+ cmd, blk = val
1730
1750
 
1731
- val = invert_block_call val if inverted? val
1751
+ syntax_error "Both block arg and actual block given." if
1752
+ cmd.block_pass?
1732
1753
 
1733
- cmd, blk = val
1754
+ if inverted? val then
1755
+ val = invert_block_call val
1756
+ cmd, blk = val
1757
+ end
1734
1758
 
1735
1759
  result = blk
1736
1760
  result.insert 1, cmd
1737
1761
  }
1738
1762
  | block_call call_op2 operation2 opt_paren_args
1739
1763
  {
1740
- result = new_call val[0], val[2].to_sym, val[3]
1764
+ lhs, _, (id, _line), args = val
1765
+
1766
+ result = new_call lhs, id.to_sym, args
1741
1767
  }
1742
1768
  | block_call call_op2 operation2 opt_paren_args brace_block
1743
1769
  {
1744
- iter1, _, name, args, iter2 = val
1770
+ iter1, _, (name, _line), args, iter2 = val
1745
1771
 
1746
1772
  call = new_call iter1, name.to_sym, args
1747
1773
  iter2.insert 1, call
@@ -1750,7 +1776,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1776
  }
1751
1777
  | block_call call_op2 operation2 command_args do_block
1752
1778
  {
1753
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1754
1780
 
1755
1781
  call = new_call iter1, name.to_sym, args
1756
1782
  iter2.insert 1, call
@@ -1758,28 +1784,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1758
1784
  result = iter2
1759
1785
  }
1760
1786
 
1761
- method_call: fcall
1762
- {
1763
- result = self.lexer.lineno
1764
- }
1765
- paren_args
1787
+ method_call: fcall paren_args
1766
1788
  {
1767
- call, lineno, args = val
1789
+ call, args = val
1768
1790
 
1769
1791
  result = call.concat args.sexp_body if args
1770
- result.line lineno
1771
1792
  }
1772
1793
  | primary_value call_op operation2 opt_paren_args
1773
1794
  {
1774
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1795
+ recv, call_op, (op, _line), args = val
1796
+
1797
+ result = new_call recv, op.to_sym, args, call_op
1775
1798
  }
1776
1799
  | primary_value tCOLON2 operation2 paren_args
1777
1800
  {
1778
- result = new_call val[0], val[2].to_sym, val[3]
1801
+ recv, _, (op, _line), args = val
1802
+
1803
+ result = new_call recv, op.to_sym, args
1779
1804
  }
1780
1805
  | primary_value tCOLON2 operation3
1781
1806
  {
1782
- result = new_call val[0], val[2].to_sym
1807
+ lhs, _, (id, _line) = val
1808
+
1809
+ result = new_call lhs, id.to_sym
1783
1810
  }
1784
1811
  | primary_value call_op paren_args
1785
1812
  {
@@ -1812,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1812
1839
  _, line, body, _ = val
1813
1840
 
1814
1841
  result = body
1815
- result.line = line
1842
+ result.line line
1816
1843
 
1817
1844
  self.env.unextend
1818
1845
  }
@@ -1826,7 +1853,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1853
  _, line, body, _ = val
1827
1854
 
1828
1855
  result = body
1829
- result.line = line
1856
+ result.line line
1830
1857
 
1831
1858
  self.env.unextend
1832
1859
  }
@@ -1855,14 +1882,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
1882
  self.env.unextend
1856
1883
  }
1857
1884
 
1885
+ case_args: arg_value
1886
+ {
1887
+ arg, = val
1888
+
1889
+ result = s(:array, arg).line arg.line
1890
+ }
1891
+ | tSTAR arg_value
1892
+ {
1893
+ _, arg = val
1894
+
1895
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1896
+ }
1897
+ | case_args tCOMMA arg_value
1898
+ {
1899
+ args, _, id = val
1900
+
1901
+ result = self.list_append args, id
1902
+ }
1903
+ | case_args tCOMMA tSTAR arg_value
1904
+ {
1905
+ args, _, _, id = val
1906
+
1907
+ result = self.list_append args, s(:splat, id).line(id.line)
1908
+ }
1909
+
1858
1910
  case_body: k_when
1859
1911
  {
1860
1912
  result = self.lexer.lineno
1861
1913
  }
1862
- args then compstmt cases
1914
+ case_args then compstmt cases
1863
1915
  {
1864
1916
  result = new_when(val[2], val[4])
1865
- result.line = val[1]
1917
+ result.line val[1]
1866
1918
  result << val[5] if val[5]
1867
1919
  }
1868
1920
 
@@ -1908,17 +1960,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1908
1960
 
1909
1961
  literal: numeric
1910
1962
  {
1911
- line = lexer.lineno
1912
- result = s(:lit, val[0])
1913
- result.line = line
1963
+ (lit, line), = val
1964
+ result = s(:lit, lit).line line
1914
1965
  }
1915
1966
  | symbol
1916
- {
1917
- line = lexer.lineno
1918
- result = s(:lit, val[0])
1919
- result.line = line
1920
- }
1921
- | dsym
1922
1967
 
1923
1968
  strings: string
1924
1969
  {
@@ -1929,7 +1974,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1929
1974
 
1930
1975
  string: tCHAR
1931
1976
  {
1932
- debug20 23, val, result
1977
+ debug 37
1933
1978
  }
1934
1979
  | string1
1935
1980
  | string string1
@@ -1939,11 +1984,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1939
1984
 
1940
1985
  string1: tSTRING_BEG string_contents tSTRING_END
1941
1986
  {
1942
- _, str, (_, func) = val
1987
+ (_, line), str, (_, func) = val
1943
1988
 
1944
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1989
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1945
1990
 
1946
- result = str
1991
+ result = str.line line
1947
1992
  }
1948
1993
  | tSTRING
1949
1994
  {
@@ -1963,11 +2008,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1963
2008
 
1964
2009
  words: tWORDS_BEG tSPACE tSTRING_END
1965
2010
  {
1966
- result = s(:array).line lexer.lineno
2011
+ (_, line), _, _ = val
2012
+
2013
+ result = s(:array).line line
1967
2014
  }
1968
2015
  | tWORDS_BEG word_list tSTRING_END
1969
2016
  {
1970
- result = val[1]
2017
+ (_, line), list, _ = val
2018
+
2019
+ result = list.line line
1971
2020
  }
1972
2021
 
1973
2022
  word_list: none
@@ -1987,18 +2036,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1987
2036
 
1988
2037
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1989
2038
  {
1990
- result = s(:array).line lexer.lineno
2039
+ (_, line), _, _ = val
2040
+
2041
+ result = s(:array).line line
1991
2042
  }
1992
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2043
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1993
2044
  {
1994
- _, line, list, _, = val
1995
- list.line = line
2045
+ (_, line), list, _, = val
2046
+ list.line line
1996
2047
  result = list
1997
2048
  }
1998
2049
 
1999
2050
  symbol_list: none
2000
2051
  {
2001
- result = new_symbol_list.line lexer.lineno
2052
+ result = new_symbol_list
2002
2053
  }
2003
2054
  | symbol_list word tSPACE
2004
2055
  {
@@ -2008,20 +2059,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2008
2059
 
2009
2060
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2010
2061
  {
2011
- result = s(:array).line lexer.lineno
2062
+ (_, line), _, _ = val
2063
+
2064
+ result = s(:array).line line
2012
2065
  }
2013
2066
  | tQWORDS_BEG qword_list tSTRING_END
2014
2067
  {
2015
- result = val[1]
2068
+ (_, line), list, _ = val
2069
+
2070
+ result = list.line line
2016
2071
  }
2017
2072
 
2018
2073
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2019
2074
  {
2020
- result = s(:array).line lexer.lineno # FIX
2075
+ (_, line), _, _ = val
2076
+
2077
+ result = s(:array).line line
2021
2078
  }
2022
2079
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2023
2080
  {
2024
- result = val[1]
2081
+ (_, line), list, _ = val
2082
+
2083
+ result = list.line line
2025
2084
  }
2026
2085
 
2027
2086
  qword_list: none
@@ -2044,7 +2103,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2044
2103
 
2045
2104
  string_contents: none
2046
2105
  {
2047
- result = s(:str, "").line lexer.lineno
2106
+ line = prev_value_to_lineno _values.last
2107
+ result = s(:str, +"").line line
2048
2108
  }
2049
2109
  | string_contents string_content
2050
2110
  {
@@ -2119,8 +2179,8 @@ regexp_contents: none
2119
2179
  lexer.brace_nest = brace_nest
2120
2180
  lexer.string_nest = string_nest
2121
2181
 
2122
- lexer.cmdarg.pop
2123
2182
  lexer.cond.pop
2183
+ lexer.cmdarg.pop
2124
2184
 
2125
2185
  lexer.lex_state = oldlex_state
2126
2186
 
@@ -2135,29 +2195,49 @@ regexp_contents: none
2135
2195
  when nil then
2136
2196
  result = s(:evstr).line line
2137
2197
  else
2138
- debug20 25
2198
+ debug 38
2139
2199
  raise "unknown string body: #{stmt.inspect}"
2140
2200
  end
2141
2201
  }
2142
2202
 
2143
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2144
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2145
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2203
+ string_dvar: tGVAR
2204
+ {
2205
+ (id, line), = val
2206
+ result = s(:gvar, id.to_sym).line line
2207
+ }
2208
+ | tIVAR
2209
+ {
2210
+ (id, line), = val
2211
+ result = s(:ivar, id.to_sym).line line
2212
+ }
2213
+ | tCVAR
2214
+ {
2215
+ (id, line), = val
2216
+ result = s(:cvar, id.to_sym).line line
2217
+ }
2146
2218
  | backref
2147
2219
 
2148
- symbol: tSYMBEG sym
2220
+ symbol: ssym
2221
+ | dsym
2222
+
2223
+ ssym: tSYMBEG sym
2149
2224
  {
2225
+ _, (id, line) = val
2226
+
2150
2227
  lexer.lex_state = EXPR_END
2151
- result = val[1].to_sym
2228
+ result = s(:lit, id.to_sym).line line
2152
2229
  }
2153
2230
  | tSYMBOL
2154
2231
  {
2155
- result = val[0].to_sym
2232
+ (id, line), = val
2233
+
2234
+ lexer.lex_state = EXPR_END
2235
+ result = s(:lit, id.to_sym).line line
2156
2236
  }
2157
2237
 
2158
2238
  sym: fname | tIVAR | tGVAR | tCVAR
2159
2239
 
2160
- dsym: tSYMBEG xstring_contents tSTRING_END
2240
+ dsym: tSYMBEG string_contents tSTRING_END
2161
2241
  {
2162
2242
  _, result, _ = val
2163
2243
 
@@ -2173,14 +2253,15 @@ regexp_contents: none
2173
2253
  when :evstr then
2174
2254
  result = s(:dsym, "", result).line result.line
2175
2255
  else
2176
- debug20 26, val, result
2256
+ debug 39
2177
2257
  end
2178
2258
  }
2179
2259
 
2180
2260
  numeric: simple_numeric
2181
- | tUMINUS_NUM simple_numeric
2261
+ | tUMINUS_NUM simple_numeric =tLOWEST
2182
2262
  {
2183
- result = -val[1] # TODO: pt_testcase
2263
+ _, (num, line) = val
2264
+ result = [-num, line]
2184
2265
  }
2185
2266
 
2186
2267
  simple_numeric: tINTEGER
@@ -2213,8 +2294,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2213
2294
 
2214
2295
  var_ref: user_variable
2215
2296
  {
2216
- var = val[0]
2297
+ raise "NO: #{val.inspect}" if Sexp === val.first
2298
+ (var, line), = val
2217
2299
  result = Sexp === var ? var : self.gettable(var)
2300
+ result.line line
2218
2301
  }
2219
2302
  | keyword_variable
2220
2303
  {
@@ -2229,11 +2312,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2229
2312
  | keyword_variable
2230
2313
  {
2231
2314
  result = self.assignable val[0]
2232
- debug20 29, val, result
2315
+ debug 40
2233
2316
  }
2234
2317
 
2235
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2236
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2318
+ backref: tNTH_REF
2319
+ {
2320
+ (ref, line), = val
2321
+ result = s(:nth_ref, ref).line line
2322
+ }
2323
+ | tBACK_REF
2324
+ {
2325
+ (ref, line), = val
2326
+ result = s(:back_ref, ref).line line
2327
+ }
2237
2328
 
2238
2329
  superclass: tLT
2239
2330
  {
@@ -2251,9 +2342,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2251
2342
 
2252
2343
  f_arglist: tLPAREN2 f_args rparen
2253
2344
  {
2254
- result = val[1]
2255
- self.lexer.lex_state = EXPR_BEG
2256
- self.lexer.command_start = true
2345
+ result = end_args val
2257
2346
  }
2258
2347
  | {
2259
2348
  result = self.in_kwarg
@@ -2262,12 +2351,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2262
2351
  }
2263
2352
  f_args term
2264
2353
  {
2265
- kwarg, args, _ = val
2266
-
2267
- self.in_kwarg = kwarg
2268
- result = args
2269
- lexer.lex_state = EXPR_BEG
2270
- lexer.command_start = true
2354
+ result = end_args val
2271
2355
  }
2272
2356
 
2273
2357
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2352,8 +2436,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2352
2436
  |
2353
2437
  {
2354
2438
  result = args val
2439
+ # result.line lexer.lineno
2355
2440
  }
2356
2441
 
2442
+
2357
2443
  f_bad_arg: tCONSTANT
2358
2444
  {
2359
2445
  yyerror "formal argument cannot be a constant"
@@ -2374,10 +2460,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2374
2460
  f_norm_arg: f_bad_arg
2375
2461
  | tIDENTIFIER
2376
2462
  {
2377
- identifier = val[0].to_sym
2463
+ (id, line), = val
2464
+ identifier = id.to_sym
2378
2465
  self.env[identifier] = :lvar
2379
2466
 
2380
- result = identifier
2467
+ result = [identifier, line]
2381
2468
  }
2382
2469
 
2383
2470
  f_arg_asgn: f_norm_arg
@@ -2385,22 +2472,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2385
2472
  f_arg_item: f_arg_asgn
2386
2473
  | tLPAREN f_margs rparen
2387
2474
  {
2388
- result = val[1]
2475
+ _, margs, _ = val
2476
+
2477
+ result = margs
2389
2478
  }
2390
2479
 
2391
2480
  f_arg: f_arg_item
2392
2481
  {
2393
- arg, = val
2394
-
2395
- case arg
2396
- when Symbol then
2397
- result = s(:args, arg).line lexer.lineno
2398
- when Sexp then
2399
- result = arg
2400
- else
2401
- debug20 32
2402
- raise "Unknown f_arg type: #{val.inspect}"
2403
- end
2482
+ result = new_arg val
2404
2483
  }
2405
2484
  | f_arg tCOMMA f_arg_item
2406
2485
  {
@@ -2412,7 +2491,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2412
2491
  result = s(:args, list).line list.line
2413
2492
  end
2414
2493
 
2415
- result << item
2494
+ result << (Sexp === item ? item : item.first)
2416
2495
  }
2417
2496
 
2418
2497
  f_label: tLABEL
@@ -2473,26 +2552,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2473
2552
  kwrest_mark: tPOW
2474
2553
  | tDSTAR
2475
2554
 
2555
+
2476
2556
  f_kwrest: kwrest_mark tIDENTIFIER
2477
2557
  {
2478
- name = val[1].to_sym
2479
- self.assignable name
2480
- result = :"**#{name}"
2558
+ _, (id, line) = val
2559
+
2560
+ name = id.to_sym
2561
+ self.assignable [name, line]
2562
+ result = [:"**#{name}", line]
2481
2563
  }
2482
2564
  | kwrest_mark
2483
2565
  {
2484
- result = :"**"
2566
+ id = :"**"
2567
+ self.env[id] = :lvar # TODO: needed?!?
2568
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2485
2569
  }
2486
2570
 
2487
2571
  f_opt: f_arg_asgn tEQL arg_value
2488
2572
  {
2489
- result = self.assignable val[0], val[2]
2573
+ lhs, _, rhs = val
2574
+ result = self.assignable lhs, rhs
2490
2575
  # TODO: detect duplicate names
2491
2576
  }
2492
2577
 
2493
2578
  f_block_opt: f_arg_asgn tEQL primary_value
2494
2579
  {
2495
- result = self.assignable val[0], val[2]
2580
+ lhs, _, rhs = val
2581
+ result = self.assignable lhs, rhs
2496
2582
  }
2497
2583
 
2498
2584
  f_block_optarg: f_block_opt
@@ -2522,30 +2608,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2522
2608
  f_rest_arg: restarg_mark tIDENTIFIER
2523
2609
  {
2524
2610
  # TODO: differs from parse.y - needs tests
2525
- name = val[1].to_sym
2526
- self.assignable name
2527
- result = :"*#{name}"
2611
+ _, (id, line) = val
2612
+ name = id.to_sym
2613
+ self.assignable [name, line]
2614
+ result = [:"*#{name}", line]
2528
2615
  }
2529
2616
  | restarg_mark
2530
2617
  {
2531
2618
  name = :"*"
2532
2619
  self.env[name] = :lvar
2533
- result = name
2620
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2534
2621
  }
2535
2622
 
2536
2623
  blkarg_mark: tAMPER2 | tAMPER
2537
2624
 
2538
2625
  f_block_arg: blkarg_mark tIDENTIFIER
2539
2626
  {
2540
- identifier = val[1].to_sym
2627
+ _, (id, line) = val
2628
+ identifier = id.to_sym
2541
2629
 
2542
2630
  self.env[identifier] = :lvar
2543
- result = "&#{identifier}".to_sym
2631
+ result = ["&#{identifier}".to_sym, line]
2544
2632
  }
2545
2633
 
2546
2634
  opt_f_block_arg: tCOMMA f_block_arg
2547
2635
  {
2548
- result = val[1]
2636
+ _, arg = val
2637
+ result = arg
2549
2638
  }
2550
2639
  |
2551
2640
  {
@@ -2594,9 +2683,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
2683
  }
2595
2684
  | tSTRING_BEG string_contents tLABEL_END arg_value
2596
2685
  {
2597
- _, sym, _, value = val
2686
+ (_, line), sym, _, value = val
2687
+
2598
2688
  sym.sexp_type = :dsym
2599
- result = s(:array, sym, value).line sym.line
2689
+
2690
+ result = s(:array, sym, value).line line
2600
2691
  }
2601
2692
  | tDSTAR arg_value
2602
2693
  {