ruby_parser 3.13.1 → 3.15.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.
@@ -23,30 +23,30 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
23
23
  tLABEL_END
24
24
  tLONELY
25
25
 
26
- prechigh
27
- right tBANG tTILDE tUPLUS
28
- right tPOW
29
- right tUMINUS_NUM tUMINUS
30
- left tSTAR2 tDIVIDE tPERCENT
31
- left tPLUS tMINUS
32
- left tLSHFT tRSHFT
33
- left tAMPER2
34
- left tPIPE tCARET
35
- left tGT tGEQ tLT tLEQ
36
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
37
- left tANDOP
38
- left tOROP
39
- nonassoc tDOT2 tDOT3
40
- right tEH tCOLON
41
- left kRESCUE_MOD
42
- right tEQL tOP_ASGN
43
- nonassoc kDEFINED
44
- right kNOT
45
- left kOR kAND
46
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
47
- nonassoc tLBRACE_ARG
48
- nonassoc tLOWEST
49
26
  preclow
27
+ nonassoc tLOWEST
28
+ nonassoc tLBRACE_ARG
29
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
30
+ left kOR kAND
31
+ right kNOT
32
+ nonassoc kDEFINED
33
+ right tEQL tOP_ASGN
34
+ left kRESCUE_MOD
35
+ right tEH tCOLON
36
+ nonassoc tDOT2 tDOT3
37
+ left tOROP
38
+ left tANDOP
39
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
40
+ left tGT tGEQ tLT tLEQ
41
+ left tPIPE tCARET
42
+ left tAMPER2
43
+ left tLSHFT tRSHFT
44
+ left tPLUS tMINUS
45
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
46
+ right tUMINUS_NUM tUMINUS
47
+ right tPOW
48
+ right tBANG tTILDE tUPLUS
49
+ prechigh
50
50
 
51
51
  rule
52
52
 
@@ -60,7 +60,8 @@ rule
60
60
 
61
61
  top_compstmt: top_stmts opt_terms
62
62
  {
63
- result = val[0]
63
+ stmt, _ = val
64
+ result = stmt
64
65
  }
65
66
 
66
67
  top_stmts: none
@@ -72,14 +73,6 @@ rule
72
73
  | error top_stmt
73
74
 
74
75
  top_stmt: stmt
75
- {
76
- result = val[0]
77
-
78
- # TODO: remove once I have more confidence this is fixed
79
- # result.each_of_type :call_args do |s|
80
- # debug20 666, s, result
81
- # end
82
- }
83
76
  | klBEGIN
84
77
  {
85
78
  if (self.in_def || self.in_single > 0) then
@@ -90,14 +83,19 @@ rule
90
83
  }
91
84
  begin_block
92
85
  {
93
- _, _, block = val
94
- result = block
86
+ (_, lineno), _, iter = val
87
+ iter.line lineno
88
+
89
+ (_, preexe,) = iter
90
+ preexe.line lineno
91
+
92
+ result = iter
95
93
  }
96
94
 
97
- begin_block: tLCURLY top_compstmt tRCURLY
95
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
98
96
  {
99
- _, stmt, _ = val
100
- result = new_iter s(:preexe), 0, stmt
97
+ _, line, stmt, _ = val
98
+ result = new_iter s(:preexe).line(line), 0, stmt
101
99
  }
102
100
 
103
101
  bodystmt: compstmt opt_rescue k_else
@@ -139,34 +137,27 @@ rule
139
137
  stmt_or_begin: stmt
140
138
  | klBEGIN
141
139
  {
142
- if (self.in_def || self.in_single > 0) then
143
- debug20 1
144
- yyerror "BEGIN in method"
145
- end
146
- self.env.extend
147
- }
148
- begin_block
149
- {
150
- _, _, stmt = val
151
- result = stmt
140
+ yyerror "BEGIN is permitted only at toplevel"
152
141
  }
153
142
 
154
143
  stmt: kALIAS fitem
155
144
  {
156
145
  lexer.lex_state = EXPR_FNAME
157
- result = self.lexer.lineno
158
146
  }
159
147
  fitem
160
148
  {
161
- result = s(:alias, val[1], val[3]).line(val[2])
149
+ (_, line), lhs, _, rhs = val
150
+ result = s(:alias, lhs, rhs).line(line).line line
162
151
  }
163
152
  | kALIAS tGVAR tGVAR
164
153
  {
165
- result = s(:valias, val[1].to_sym, val[2].to_sym)
154
+ (_, line), lhs, rhs = val
155
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
166
156
  }
167
157
  | kALIAS tGVAR tBACK_REF
168
158
  {
169
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
159
+ (_, line), lhs, rhs = val
160
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
170
161
  }
171
162
  | kALIAS tGVAR tNTH_REF
172
163
  {
@@ -178,32 +169,41 @@ rule
178
169
  }
179
170
  | stmt kIF_MOD expr_value
180
171
  {
181
- result = new_if val[2], val[0], nil
172
+ t, _, c = val
173
+ result = new_if c, t, nil
182
174
  }
183
175
  | stmt kUNLESS_MOD expr_value
184
176
  {
185
- result = new_if val[2], nil, val[0]
177
+ f, _, c = val
178
+ result = new_if c, nil, f
186
179
  }
187
180
  | stmt kWHILE_MOD expr_value
188
181
  {
189
- result = new_while val[0], val[2], true
182
+ e, _, c = val
183
+ result = new_while e, c, true
190
184
  }
191
185
  | stmt kUNTIL_MOD expr_value
192
186
  {
193
- result = new_until val[0], val[2], true
187
+ e, _, c = val
188
+ result = new_until e, c, true
194
189
  }
195
190
  | stmt kRESCUE_MOD stmt
196
191
  {
197
192
  body, _, resbody = val
198
- result = new_rescue body, new_resbody(s(:array), resbody)
193
+
194
+ resbody = new_resbody s(:array).line(resbody.line), resbody
195
+ result = new_rescue body, resbody
199
196
  }
200
197
  | klEND tLCURLY compstmt tRCURLY
201
198
  {
199
+ (_, line), _, stmt, _ = val
200
+
202
201
  if (self.in_def || self.in_single > 0) then
203
202
  debug20 3
204
203
  yyerror "END in method; use at_exit"
205
204
  end
206
- result = new_iter s(:postexe), 0, val[2]
205
+
206
+ result = new_iter s(:postexe).line(line), 0, stmt
207
207
  }
208
208
  | command_asgn
209
209
  | mlhs tEQL command_call
@@ -212,7 +212,8 @@ rule
212
212
  }
213
213
  | lhs tEQL mrhs
214
214
  {
215
- result = new_assign val[0], s(:svalue, val[2])
215
+ lhs, _, rhs = val
216
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
216
217
  }
217
218
  | mlhs tEQL mrhs_arg
218
219
  {
@@ -234,11 +235,12 @@ rule
234
235
  }
235
236
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
236
237
  {
237
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
238
+ result = new_op_asgn1 val
238
239
  }
239
240
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
240
241
  {
241
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
242
+ prim, _, id, opasgn, rhs = val
243
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
242
244
  if val[1] == '&.'
243
245
  result.sexp_type = :safe_op_asgn
244
246
  end
@@ -254,13 +256,15 @@ rule
254
256
  }
255
257
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
258
  {
257
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
258
- debug20 4, val, result
259
+ lhs1, _, lhs2, op, rhs = val
260
+
261
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
259
262
  }
260
263
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
261
264
  {
262
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
263
- debug20 5, val, result
265
+ lhs1, _, lhs2, op, rhs = val
266
+
267
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
264
268
  }
265
269
  | backref tOP_ASGN command_rhs
266
270
  {
@@ -277,19 +281,26 @@ rule
277
281
  expr: command_call
278
282
  | expr kAND expr
279
283
  {
280
- result = logical_op :and, val[0], val[2]
284
+ lhs, _, rhs = val
285
+ result = logical_op :and, lhs, rhs
281
286
  }
282
287
  | expr kOR expr
283
288
  {
284
- result = logical_op :or, val[0], val[2]
289
+ lhs, _, rhs = val
290
+ result = logical_op :or, lhs, rhs
285
291
  }
286
292
  | kNOT opt_nl expr
287
293
  {
288
- result = s(:call, val[2], :"!")
294
+ (_, line), _, expr = val
295
+ result = new_call(expr, :"!").line line
296
+ # REFACTOR: call_uni_op
289
297
  }
290
298
  | tBANG command_call
291
299
  {
292
- result = s(:call, val[1], :"!")
300
+ _, cmd = val
301
+ result = new_call(cmd, :"!").line cmd.line
302
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
303
+ # REFACTOR: call_uni_op -- see parse26.y
293
304
  }
294
305
  | arg
295
306
 
@@ -316,7 +327,8 @@ rule
316
327
  block_command: block_call
317
328
  | block_call call_op2 operation2 command_args
318
329
  {
319
- result = new_call val[0], val[2].to_sym, val[3]
330
+ blk, _, msg, args = val
331
+ result = new_call(blk, msg.to_sym, args).line blk.line
320
332
  }
321
333
 
322
334
  cmd_brace_block: tLBRACE_ARG
@@ -336,26 +348,32 @@ rule
336
348
 
337
349
  fcall: operation
338
350
  {
339
- result = new_call nil, val[0].to_sym
351
+ msg, = val
352
+ result = new_call(nil, msg.to_sym).line lexer.lineno
340
353
  }
341
354
 
342
355
  command: fcall command_args =tLOWEST
343
356
  {
344
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
357
+ call, args = val
358
+ result = call.concat args.sexp_body
345
359
  }
346
360
  | fcall command_args cmd_brace_block
347
361
  {
348
- result = val[0].concat val[1].sexp_body
349
- if val[2] then
350
- block_dup_check result, val[2]
362
+ call, args, block = val
363
+
364
+ result = call.concat args.sexp_body
351
365
 
352
- result, operation = val[2], result
366
+ if block then
367
+ block_dup_check result, block
368
+
369
+ result, operation = block, result
353
370
  result.insert 1, operation
354
371
  end
355
372
  }
356
373
  | primary_value call_op operation2 command_args =tLOWEST
357
374
  {
358
- result = new_call val[0], val[2].to_sym, val[3], val[1]
375
+ lhs, callop, op, args = val
376
+ result = new_call lhs, op.to_sym, args, callop
359
377
  }
360
378
  | primary_value call_op operation2 command_args cmd_brace_block
361
379
  {
@@ -387,7 +405,9 @@ rule
387
405
  }
388
406
  | kYIELD command_args
389
407
  {
390
- result = new_yield val[1]
408
+ (_, line), args = val
409
+ result = new_yield args
410
+ result.line line # TODO: push to new_yield
391
411
  }
392
412
  | k_return call_args
393
413
  {
@@ -396,8 +416,8 @@ rule
396
416
  }
397
417
  | kBREAK call_args
398
418
  {
399
- line = val[0].last
400
- result = s(:break, ret_args(val[1])).line(line)
419
+ (_, line), args = val
420
+ result = s(:break, ret_args(args)).line line
401
421
  }
402
422
  | kNEXT call_args
403
423
  {
@@ -414,56 +434,79 @@ rule
414
434
  mlhs_inner: mlhs_basic
415
435
  | tLPAREN mlhs_inner rparen
416
436
  {
417
- result = s(:masgn, s(:array, val[1]))
437
+ _, arg, _ = val
438
+ l = arg.line
439
+
440
+ result = s(:masgn, s(:array, arg).line(l)).line l
418
441
  }
419
442
 
420
443
  mlhs_basic: mlhs_head
421
444
  {
422
- result = s(:masgn, val[0])
445
+ head, = val
446
+ result = s(:masgn, head).line head.line
423
447
  }
424
448
  | mlhs_head mlhs_item
425
449
  {
426
- result = s(:masgn, val[0] << val[1].compact)
450
+ lhs, rhs = val
451
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
427
452
  }
428
453
  | mlhs_head tSTAR mlhs_node
429
454
  {
430
- result = s(:masgn, val[0] << s(:splat, val[2]))
455
+ head, _, tail = val
456
+ head << s(:splat, tail).line(tail.line)
457
+ result = s(:masgn, head).line head.line
431
458
  }
432
459
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
433
460
  {
434
461
  ary1, _, splat, _, ary2 = val
435
462
 
436
- result = list_append ary1, s(:splat, splat)
463
+ result = list_append ary1, s(:splat, splat).line(splat.line)
437
464
  result.concat ary2.sexp_body
438
- result = s(:masgn, result)
465
+ result = s(:masgn, result).line result.line
439
466
  }
440
467
  | mlhs_head tSTAR
441
468
  {
442
- result = s(:masgn, val[0] << s(:splat))
469
+ head, _ = val
470
+ l = head.line
471
+ result = s(:masgn, head << s(:splat).line(l)).line l
443
472
  }
444
473
  | mlhs_head tSTAR tCOMMA mlhs_post
445
474
  {
446
- ary = list_append val[0], s(:splat)
447
- ary.concat val[3].sexp_body
448
- result = s(:masgn, ary)
475
+ head, _, _, post = val
476
+ ary = list_append head, s(:splat).line(head.line)
477
+ ary.concat post.sexp_body
478
+ result = s(:masgn, ary).line ary.line
449
479
  }
450
480
  | tSTAR mlhs_node
451
481
  {
452
- result = s(:masgn, s(:array, s(:splat, val[1])))
482
+ _, node = val
483
+ l = node.line
484
+ splat = s(:splat, node).line l
485
+ ary = s(:array, splat).line l
486
+ result = s(:masgn, ary).line l
453
487
  }
454
488
  | tSTAR mlhs_node tCOMMA mlhs_post
455
489
  {
456
- ary = s(:array, s(:splat, val[1]))
457
- ary.concat val[3].sexp_body
458
- result = s(:masgn, ary)
490
+ _, node, _, post = val
491
+
492
+ splat = s(:splat, node).line node.line
493
+ ary = s(:array, splat).line splat.line
494
+ ary.concat post.sexp_body
495
+ result = s(:masgn, ary).line ary.line
459
496
  }
460
497
  | tSTAR
461
498
  {
462
- result = s(:masgn, s(:array, s(:splat)))
499
+ l = lexer.lineno
500
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
463
501
  }
464
502
  | tSTAR tCOMMA mlhs_post
465
503
  {
466
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
504
+ _, _, post = val
505
+ l = post.line
506
+
507
+ splat = s(:splat).line l
508
+ ary = s(:array, splat, *post.sexp_body).line l
509
+ result = s(:masgn, ary).line l
467
510
  }
468
511
 
469
512
  mlhs_item: mlhs_node
@@ -474,7 +517,8 @@ rule
474
517
 
475
518
  mlhs_head: mlhs_item tCOMMA
476
519
  {
477
- result = s(:array, val[0])
520
+ lhs, _ = val
521
+ result = s(:array, lhs).line lhs.line
478
522
  }
479
523
  | mlhs_head mlhs_item tCOMMA
480
524
  {
@@ -483,7 +527,8 @@ rule
483
527
 
484
528
  mlhs_post: mlhs_item
485
529
  {
486
- result = s(:array, val[0])
530
+ item, = val
531
+ result = s(:array, item).line item.line
487
532
  }
488
533
  | mlhs_post tCOMMA mlhs_item
489
534
  {
@@ -508,7 +553,8 @@ rule
508
553
  }
509
554
  | primary_value tCOLON2 tIDENTIFIER
510
555
  {
511
- result = s(:attrasgn, val[0], :"#{val[2]}=")
556
+ recv, _, id = val
557
+ result = new_attrasgn recv, id
512
558
  }
513
559
  | primary_value call_op tCONSTANT
514
560
  {
@@ -521,7 +567,10 @@ rule
521
567
  yyerror "dynamic constant assignment"
522
568
  end
523
569
 
524
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
570
+ expr, _, id = val
571
+ l = expr.line
572
+
573
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
525
574
  }
526
575
  | tCOLON3 tCONSTANT
527
576
  {
@@ -530,7 +579,10 @@ rule
530
579
  yyerror "dynamic constant assignment"
531
580
  end
532
581
 
533
- result = s(:const, nil, s(:colon3, val[1].to_sym))
582
+ _, id = val
583
+ l = lexer.lineno
584
+
585
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
534
586
  }
535
587
  | backref
536
588
  {
@@ -539,24 +591,31 @@ rule
539
591
 
540
592
  lhs: user_variable
541
593
  {
594
+ line = lexer.lineno
542
595
  result = self.assignable val[0]
596
+ result.line = line
543
597
  }
544
598
  | keyword_variable
545
599
  {
600
+ line = lexer.lineno
546
601
  result = self.assignable val[0]
602
+ result.line = line
547
603
  debug20 9, val, result
548
604
  }
549
605
  | primary_value tLBRACK2 opt_call_args rbracket
550
606
  {
551
- result = self.aryset val[0], val[2]
607
+ lhs, _, args, _ = val
608
+ result = self.aryset lhs, args
552
609
  }
553
610
  | primary_value call_op tIDENTIFIER # REFACTOR
554
611
  {
555
- result = new_attrasgn val[0], val[2], val[1]
612
+ lhs, op, id = val
613
+ result = new_attrasgn lhs, id, op
556
614
  }
557
615
  | primary_value tCOLON2 tIDENTIFIER
558
616
  {
559
- result = s(:attrasgn, val[0], :"#{val[2]}=")
617
+ lhs, _, id = val
618
+ result = new_attrasgn lhs, id
560
619
  }
561
620
  | primary_value call_op tCONSTANT # REFACTOR?
562
621
  {
@@ -564,21 +623,27 @@ rule
564
623
  }
565
624
  | primary_value tCOLON2 tCONSTANT
566
625
  {
626
+ expr, _, id = val
627
+
567
628
  if (self.in_def || self.in_single > 0) then
568
629
  debug20 10
569
630
  yyerror "dynamic constant assignment"
570
631
  end
571
632
 
572
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
633
+ l = expr.line
634
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
573
635
  }
574
636
  | tCOLON3 tCONSTANT
575
637
  {
638
+ _, id = val
639
+
576
640
  if (self.in_def || self.in_single > 0) then
577
641
  debug20 11
578
642
  yyerror "dynamic constant assignment"
579
643
  end
580
644
 
581
- result = s(:const, s(:colon3, val[1].to_sym))
645
+ l = lexer.lineno
646
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
582
647
  }
583
648
  | backref
584
649
  {
@@ -593,7 +658,8 @@ rule
593
658
 
594
659
  cpath: tCOLON3 cname
595
660
  {
596
- result = s(:colon3, val[1].to_sym)
661
+ _, name = val
662
+ result = s(:colon3, name.to_sym).line lexer.lineno
597
663
  }
598
664
  | cname
599
665
  {
@@ -601,7 +667,10 @@ rule
601
667
  }
602
668
  | primary_value tCOLON2 cname
603
669
  {
604
- result = s(:colon2, val[0], val[2].to_sym)
670
+ pval, _, name = val
671
+
672
+ result = s(:colon2, pval, name.to_sym)
673
+ result.line pval.line
605
674
  }
606
675
 
607
676
  fname: tIDENTIFIER | tCONSTANT | tFID
@@ -622,7 +691,8 @@ rule
622
691
 
623
692
  fitem: fsym
624
693
  {
625
- result = s(:lit, val[0].to_sym)
694
+ id, = val
695
+ result = s(:lit, id.to_sym).line lexer.lineno
626
696
  }
627
697
  | dsym
628
698
 
@@ -645,6 +715,7 @@ rule
645
715
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
646
716
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
647
717
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
718
+ # TODO: tUBANG dead?
648
719
  | tUBANG
649
720
 
650
721
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -667,8 +738,7 @@ rule
667
738
  }
668
739
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
669
740
  {
670
- val[2].sexp_type = :arglist if val[2]
671
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
741
+ result = new_op_asgn1 val
672
742
  }
673
743
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
674
744
  {
@@ -680,7 +750,9 @@ rule
680
750
  }
681
751
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
682
752
  {
683
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
753
+ lhs, _, id, op, rhs = val
754
+
755
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
684
756
  }
685
757
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
686
758
  {
@@ -710,18 +782,18 @@ rule
710
782
  {
711
783
  v1, v2 = val[0], val[2]
712
784
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
713
- result = s(:lit, (v1.last)..(v2.last))
785
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
714
786
  else
715
- result = s(:dot2, v1, v2)
787
+ result = s(:dot2, v1, v2).line v1.line
716
788
  end
717
789
  }
718
790
  | arg tDOT3 arg
719
791
  {
720
792
  v1, v2 = val[0], val[2]
721
793
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
722
- result = s(:lit, (v1.last)...(v2.last))
794
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
723
795
  else
724
- result = s(:dot3, v1, v2)
796
+ result = s(:dot3, v1, v2).line v1.line
725
797
  end
726
798
  }
727
799
  | arg tPLUS arg
@@ -750,7 +822,9 @@ rule
750
822
  }
751
823
  | tUMINUS_NUM simple_numeric tPOW arg
752
824
  {
753
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
825
+ lit = s(:lit, val[1]).line lexer.lineno
826
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
827
+
754
828
  }
755
829
  | tUPLUS arg
756
830
  {
@@ -791,15 +865,19 @@ rule
791
865
  }
792
866
  | arg tMATCH arg
793
867
  {
794
- result = new_match val[0], val[2]
868
+ lhs, _, rhs = val
869
+ result = new_match lhs, rhs
795
870
  }
796
871
  | arg tNMATCH arg
797
872
  {
798
- result = s(:not, new_match(val[0], val[2]))
873
+ lhs, _, rhs = val
874
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
799
875
  }
800
876
  | tBANG arg
801
877
  {
802
- result = new_call val[1], :"!"
878
+ _, arg = val
879
+ result = new_call arg, :"!"
880
+ result.line arg.line
803
881
  }
804
882
  | tTILDE arg
805
883
  {
@@ -827,11 +905,13 @@ rule
827
905
  }
828
906
  | kDEFINED opt_nl arg
829
907
  {
830
- result = s(:defined, val[2])
908
+ (_, line), _, arg = val
909
+ result = s(:defined, arg).line line
831
910
  }
832
911
  | arg tEH arg opt_nl tCOLON arg
833
912
  {
834
- result = s(:if, val[0], val[2], val[5])
913
+ c, _, t, _, _, f = val
914
+ result = s(:if, c, t, f).line c.line
835
915
  }
836
916
  | primary
837
917
 
@@ -874,28 +954,25 @@ rule
874
954
  arg_rhs: arg =tOP_ASGN
875
955
  | arg kRESCUE_MOD arg
876
956
  {
877
- body, _, resbody = val
957
+ body, (_, line), resbody = val
878
958
  body = value_expr body
879
959
  resbody = remove_begin resbody
880
- result = new_rescue(body, new_resbody(s(:array), resbody))
960
+
961
+ ary = s(:array).line line
962
+ result = new_rescue(body, new_resbody(ary, resbody))
881
963
  }
882
964
 
883
965
  paren_args: tLPAREN2 opt_call_args rparen
884
966
  {
885
- result = val[1]
967
+ _, args, _ = val
968
+ result = args
886
969
  }
887
970
 
888
971
  opt_paren_args: none
889
972
  | paren_args
890
973
 
891
974
  opt_call_args: none
892
- {
893
- result = val[0]
894
- }
895
975
  | call_args
896
- {
897
- result = val[0]
898
- }
899
976
  | args tCOMMA
900
977
  {
901
978
  result = args val
@@ -917,17 +994,14 @@ rule
917
994
  | args opt_block_arg
918
995
  {
919
996
  result = call_args val
920
- result = self.arg_blk_pass val[0], val[1]
921
997
  }
922
998
  | assocs opt_block_arg
923
999
  {
924
- result = call_args [array_to_hash(val[0])]
925
- result = self.arg_blk_pass result, val[1]
1000
+ result = call_args [array_to_hash(val[0]), val[1]]
926
1001
  }
927
1002
  | args tCOMMA assocs opt_block_arg
928
1003
  {
929
- result = call_args [val[0], array_to_hash(val[2])]
930
- result = self.arg_blk_pass result, val[3]
1004
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
931
1005
  }
932
1006
  | block_arg
933
1007
  {
@@ -935,17 +1009,45 @@ rule
935
1009
  }
936
1010
 
937
1011
  command_args: {
938
- result = lexer.cmdarg.store true
1012
+ # parse26.y line 2200
1013
+
1014
+ # If call_args starts with a open paren '(' or
1015
+ # '[', look-ahead reading of the letters calls
1016
+ # CMDARG_PUSH(0), but the push must be done
1017
+ # after CMDARG_PUSH(1). So this code makes them
1018
+ # consistent by first cancelling the premature
1019
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1020
+ # finally redoing CMDARG_PUSH(0).
1021
+
1022
+ result = yychar = self.last_token_type.first
1023
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1024
+ lexer.cmdarg.pop if lookahead
1025
+ lexer.cmdarg.push true
1026
+ lexer.cmdarg.push false if lookahead
939
1027
  }
940
1028
  call_args
941
1029
  {
942
- lexer.cmdarg.restore val[0]
943
- result = val[1]
1030
+ yychar, args = val
1031
+
1032
+ # call_args can be followed by tLBRACE_ARG (that
1033
+ # does CMDARG_PUSH(0) in the lexer) but the push
1034
+ # must be done after CMDARG_POP() in the parser.
1035
+ # So this code does CMDARG_POP() to pop 0 pushed
1036
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1037
+ # by command_args, and CMDARG_PUSH(0) to restore
1038
+ # back the flag set by tLBRACE_ARG.
1039
+
1040
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1041
+ lexer.cmdarg.pop if lookahead
1042
+ lexer.cmdarg.pop
1043
+ lexer.cmdarg.push false if lookahead
1044
+ result = args
944
1045
  }
945
1046
 
946
1047
  block_arg: tAMPER arg_value
947
1048
  {
948
- result = s(:block_pass, val[1])
1049
+ _, arg = val
1050
+ result = s(:block_pass, arg).line arg.line
949
1051
  }
950
1052
 
951
1053
  opt_block_arg: tCOMMA block_arg
@@ -956,19 +1058,27 @@ rule
956
1058
 
957
1059
  args: arg_value
958
1060
  {
959
- result = s(:array, val[0])
1061
+ arg, = val
1062
+ lineno = arg.line || lexer.lineno # HACK
1063
+
1064
+ result = s(:array, arg).line lineno
960
1065
  }
961
1066
  | tSTAR arg_value
962
1067
  {
963
- result = s(:array, s(:splat, val[1]))
1068
+ _, arg = val
1069
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
964
1070
  }
965
1071
  | args tCOMMA arg_value
966
1072
  {
967
- result = self.list_append val[0], val[2]
1073
+ args, _, id = val
1074
+ result = self.list_append args, id
968
1075
  }
969
1076
  | args tCOMMA tSTAR arg_value
970
1077
  {
971
- result = self.list_append val[0], s(:splat, val[3])
1078
+ # TODO: the line number from tSTAR has been dropped
1079
+ args, _, _, id = val
1080
+ line = lexer.lineno
1081
+ result = self.list_append args, s(:splat, id).line(line)
972
1082
  }
973
1083
 
974
1084
  mrhs_arg: mrhs
@@ -986,11 +1096,14 @@ rule
986
1096
  }
987
1097
  | args tCOMMA tSTAR arg_value
988
1098
  {
989
- result = self.arg_concat val[0], val[3]
1099
+ # TODO: make all tXXXX terminals include lexer.lineno
1100
+ arg, _, _, splat = val
1101
+ result = self.arg_concat arg, splat
990
1102
  }
991
1103
  | tSTAR arg_value
992
1104
  {
993
- result = s(:splat, val[1])
1105
+ _, arg = val
1106
+ result = s(:splat, arg).line arg.line
994
1107
  }
995
1108
 
996
1109
  primary: literal
@@ -1005,65 +1118,65 @@ rule
1005
1118
  | backref
1006
1119
  | tFID
1007
1120
  {
1008
- result = new_call nil, val[0].to_sym
1121
+ msg, = val
1122
+ result = new_call nil, msg.to_sym
1009
1123
  }
1010
1124
  | k_begin
1011
1125
  {
1126
+ lexer.cmdarg.push false
1012
1127
  result = self.lexer.lineno
1013
- # TODO:
1014
- # $<val>1 = cmdarg_stack;
1015
- # CMDARG_SET(0);
1016
1128
  }
1017
1129
  bodystmt k_end
1018
1130
  {
1019
- # TODO: CMDARG_SET($<val>1);
1020
- unless val[2] then
1021
- result = s(:nil)
1022
- else
1023
- result = s(:begin, val[2])
1024
- end
1025
-
1026
- result.line = val[1]
1131
+ lexer.cmdarg.pop
1132
+ result = new_begin val
1027
1133
  }
1028
- | tLPAREN_ARG rparen
1134
+ | tLPAREN_ARG
1029
1135
  {
1030
- # TODO: lex_state = EXPR_ENDARG in between
1031
- debug20 13, val, result
1136
+ lexer.lex_state = EXPR_ENDARG
1137
+ result = lexer.lineno
1032
1138
  }
1033
- | tLPAREN_ARG
1139
+ rparen
1034
1140
  {
1035
- result = lexer.cmdarg.store false
1036
- # result = self.lexer.cmdarg.stack.dup
1037
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1141
+ _, line, _ = val
1142
+ result = s(:begin).line line
1038
1143
  }
1144
+ | tLPAREN_ARG
1039
1145
  stmt
1040
1146
  {
1041
1147
  lexer.lex_state = EXPR_ENDARG
1042
1148
  }
1043
1149
  rparen
1044
1150
  {
1045
- _, cmdarg, stmt, _, _, = val
1046
- warning "(...) interpreted as grouped expression"
1047
- lexer.cmdarg.restore cmdarg
1151
+ _, stmt, _, _, = val
1152
+ # warning "(...) interpreted as grouped expression"
1048
1153
  result = stmt
1049
1154
  }
1050
1155
  | tLPAREN compstmt tRPAREN
1051
1156
  {
1052
- result = val[1] || s(:nil)
1157
+ _, stmt, _ = val
1158
+ result = stmt
1159
+ result ||= s(:nil).line lexer.lineno
1053
1160
  result.paren = true
1054
1161
  }
1055
1162
  | primary_value tCOLON2 tCONSTANT
1056
1163
  {
1057
- result = s(:colon2, val[0], val[2].to_sym)
1164
+ expr, _, id = val
1165
+
1166
+ result = s(:colon2, expr, id.to_sym).line expr.line
1058
1167
  }
1059
1168
  | tCOLON3 tCONSTANT
1060
1169
  {
1061
- result = s(:colon3, val[1].to_sym)
1170
+ _, id = val
1171
+
1172
+ result = s(:colon3, id.to_sym).line lexer.lineno
1062
1173
  }
1063
- | tLBRACK aref_args tRBRACK
1174
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1064
1175
  {
1065
- result = val[1] || s(:array)
1176
+ _, line, args, _ = val
1177
+ result = args || s(:array)
1066
1178
  result.sexp_type = :array # aref_args is :args
1179
+ result.line line
1067
1180
  }
1068
1181
  | tLBRACE
1069
1182
  {
@@ -1075,7 +1188,8 @@ rule
1075
1188
  }
1076
1189
  | k_return
1077
1190
  {
1078
- result = s(:return)
1191
+ (_, line), = val
1192
+ result = s(:return).line line
1079
1193
  }
1080
1194
  | kYIELD tLPAREN2 call_args rparen
1081
1195
  {
@@ -1091,11 +1205,14 @@ rule
1091
1205
  }
1092
1206
  | kDEFINED opt_nl tLPAREN2 expr rparen
1093
1207
  {
1094
- result = s(:defined, val[3])
1208
+ (_, line), _, _, arg, _ = val
1209
+
1210
+ result = s(:defined, arg).line line
1095
1211
  }
1096
1212
  | kNOT tLPAREN2 expr rparen
1097
1213
  {
1098
- result = s(:call, val[2], :"!")
1214
+ _, _, lhs, _ = val
1215
+ result = new_call lhs, :"!"
1099
1216
  }
1100
1217
  | kNOT tLPAREN2 rparen
1101
1218
  {
@@ -1103,11 +1220,11 @@ rule
1103
1220
  }
1104
1221
  | fcall brace_block
1105
1222
  {
1106
- oper, iter = val[0], val[1]
1107
- call = oper # FIX
1223
+ call, iter = val
1224
+
1108
1225
  iter.insert 1, call
1109
1226
  result = iter
1110
- call.line = iter.line
1227
+ # FIX: probably not: call.line = iter.line
1111
1228
  }
1112
1229
  | method_call
1113
1230
  | method_call brace_block
@@ -1215,66 +1332,82 @@ rule
1215
1332
  }
1216
1333
  | k_def fname
1217
1334
  {
1218
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1335
+ result = self.in_def
1219
1336
 
1220
- self.comments.push self.lexer.comments
1221
- self.in_def = true
1337
+ self.in_def = true # group = local_push
1222
1338
  self.env.extend
1223
- # TODO: local->cmdargs = cmdarg_stack;
1224
- # TODO: port local_push_gen and local_pop_gen
1225
- lexer.cmdarg.stack.replace [false]
1339
+ lexer.cmdarg.push false
1340
+ lexer.cond.push false
1341
+
1342
+ self.comments.push self.lexer.comments
1226
1343
  }
1227
- f_arglist bodystmt k_end
1344
+ f_arglist bodystmt { result = lexer.lineno } k_end
1228
1345
  {
1229
- in_def, cmdarg = val[2]
1346
+ in_def = val[2]
1230
1347
 
1231
1348
  result = new_defn val
1232
1349
 
1233
- lexer.cmdarg.stack.replace cmdarg
1350
+ lexer.cond.pop # group = local_pop
1351
+ lexer.cmdarg.pop
1234
1352
  self.env.unextend
1235
1353
  self.in_def = in_def
1354
+
1236
1355
  self.lexer.comments # we don't care about comments in the body
1237
1356
  }
1238
1357
  | k_def singleton dot_or_colon
1239
1358
  {
1240
- self.comments.push self.lexer.comments
1241
1359
  lexer.lex_state = EXPR_FNAME
1242
1360
  }
1243
1361
  fname
1244
1362
  {
1245
- self.in_single += 1
1363
+ result = [self.in_def, lexer.lineno]
1364
+
1365
+ self.in_single += 1 # TODO: remove?
1366
+
1367
+ self.in_def = true # local_push
1246
1368
  self.env.extend
1247
- lexer.lex_state = EXPR_ENDFN # force for args
1248
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1249
- lexer.cmdarg.stack.replace [false]
1369
+ lexer.cmdarg.push false
1370
+ lexer.cond.push false
1371
+
1372
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1373
+ self.comments.push self.lexer.comments
1250
1374
  }
1251
1375
  f_arglist bodystmt k_end
1252
1376
  {
1253
- line, cmdarg = val[5]
1254
- result = new_defs val
1255
- result[3].line line
1377
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1256
1378
 
1257
- lexer.cmdarg.stack.replace cmdarg
1379
+ result = new_defs val
1258
1380
 
1381
+ lexer.cond.pop # group = local_pop
1382
+ lexer.cmdarg.pop
1259
1383
  self.env.unextend
1384
+ self.in_def = in_def
1385
+
1260
1386
  self.in_single -= 1
1387
+
1388
+ # TODO: restore cur_arg ? what's cur_arg?
1389
+
1261
1390
  self.lexer.comments # we don't care about comments in the body
1262
1391
  }
1263
1392
  | kBREAK
1264
1393
  {
1265
- result = s(:break)
1394
+ (_, line), = val
1395
+ result = s(:break).line line
1266
1396
  }
1267
1397
  | kNEXT
1268
1398
  {
1269
- result = s(:next)
1399
+ (_, line), = val
1400
+ result = s(:next).line line
1270
1401
  }
1271
1402
  | kREDO
1272
1403
  {
1273
- result = s(:redo)
1404
+ (_, line), = val
1405
+ result = s(:redo).line line
1274
1406
  }
1275
1407
  | kRETRY
1276
1408
  {
1277
- result = s(:retry)
1409
+ (_, line), = val
1410
+ result = s(:retry).line line
1278
1411
  }
1279
1412
 
1280
1413
  primary_value: primary
@@ -1313,7 +1446,9 @@ rule
1313
1446
  if_tail: opt_else
1314
1447
  | k_elsif expr_value then compstmt if_tail
1315
1448
  {
1316
- result = s(:if, val[1], val[3], val[4])
1449
+ (_, line), c, _, t, rest = val
1450
+
1451
+ result = s(:if, c, t, rest).line line
1317
1452
  }
1318
1453
 
1319
1454
  opt_else: none
@@ -1336,7 +1471,9 @@ rule
1336
1471
 
1337
1472
  f_marg_list: f_marg
1338
1473
  {
1339
- result = s(:array, val[0])
1474
+ sym, = val
1475
+
1476
+ result = s(:array, sym).line lexer.lineno
1340
1477
  }
1341
1478
  | f_marg_list tCOMMA f_marg
1342
1479
  {
@@ -1410,7 +1547,9 @@ rule
1410
1547
  }
1411
1548
  | f_block_arg
1412
1549
  {
1413
- result = call_args val
1550
+ line = lexer.lineno
1551
+ result = call_args val # TODO: push line down
1552
+ result.line line
1414
1553
  }
1415
1554
 
1416
1555
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1441,7 +1580,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1441
1580
  }
1442
1581
  | f_arg tCOMMA
1443
1582
  {
1444
- result = args val
1583
+ result = args(val) << nil
1445
1584
  }
1446
1585
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1447
1586
  {
@@ -1493,7 +1632,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1493
1632
  }
1494
1633
  | tOROP
1495
1634
  {
1496
- result = s(:args)
1635
+ result = s(:args).line lexer.lineno
1497
1636
  }
1498
1637
  | tPIPE block_param opt_bv_decl tPIPE
1499
1638
  {
@@ -1518,34 +1657,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1518
1657
 
1519
1658
  bvar: tIDENTIFIER
1520
1659
  {
1521
- result = s(:shadow, val[0].to_sym)
1660
+ id, = val
1661
+ line = lexer.lineno
1662
+ result = s(:shadow, id.to_sym).line line
1522
1663
  }
1523
1664
  | f_bad_arg
1524
1665
 
1525
1666
  lambda: {
1526
1667
  self.env.extend :dynamic
1527
- result = self.lexer.lineno
1528
-
1529
- result = lexer.lpar_beg
1668
+ result = [lexer.lineno, lexer.lpar_beg]
1530
1669
  lexer.paren_nest += 1
1531
1670
  lexer.lpar_beg = lexer.paren_nest
1532
1671
  }
1533
1672
  f_larglist
1534
1673
  {
1535
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1674
+ lexer.cmdarg.push false
1536
1675
  }
1537
1676
  lambda_body
1538
1677
  {
1539
- lpar, args, (cmdarg, lineno), body = val
1678
+ (line, lpar), args, _cmdarg, body = val
1540
1679
  lexer.lpar_beg = lpar
1541
1680
 
1542
- lexer.cmdarg.restore cmdarg
1543
- lexer.cmdarg.lexpop
1681
+ lexer.cmdarg.pop
1544
1682
 
1545
- call = new_call nil, :lambda
1683
+ call = s(:lambda).line line
1546
1684
  result = new_iter call, args, body
1547
- result.line = lineno
1548
- self.env.unextend
1685
+ result.line = line
1686
+ self.env.unextend # TODO: dynapush & dynapop
1549
1687
  }
1550
1688
 
1551
1689
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1569,8 +1707,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1569
1707
 
1570
1708
  do_block: k_do_block do_body kEND
1571
1709
  {
1572
- # TODO: maybe fix lineno to kDO's lineno?
1573
- result = val[1]
1710
+ (_, line), iter, _ = val
1711
+ result = iter.line line
1574
1712
  }
1575
1713
 
1576
1714
  block_call: command do_block
@@ -1584,8 +1722,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1584
1722
 
1585
1723
  val = invert_block_call val if inverted? val
1586
1724
 
1587
- result = val[1]
1588
- result.insert 1, val[0]
1725
+ cmd, blk = val
1726
+
1727
+ result = blk
1728
+ result.insert 1, cmd
1589
1729
  }
1590
1730
  | block_call call_op2 operation2 opt_paren_args
1591
1731
  {
@@ -1616,8 +1756,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1616
1756
  }
1617
1757
  paren_args
1618
1758
  {
1619
- args = self.call_args val[2..-1]
1620
- result = val[0].concat args.sexp_body
1759
+ call, lineno, args = val
1760
+
1761
+ result = call.concat args.sexp_body if args
1762
+ result.line lineno
1621
1763
  }
1622
1764
  | primary_value call_op operation2 opt_paren_args
1623
1765
  {
@@ -1645,7 +1787,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1645
1787
  }
1646
1788
  | kSUPER
1647
1789
  {
1648
- result = s(:zsuper)
1790
+ result = s(:zsuper).line lexer.lineno
1649
1791
  }
1650
1792
  | primary_value tLBRACK2 opt_call_args rbracket
1651
1793
  {
@@ -1694,15 +1836,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1694
1836
  }
1695
1837
 
1696
1838
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1697
- { result = lexer.cmdarg.store(false) }
1839
+ { lexer.cmdarg.push false }
1698
1840
  opt_block_param
1699
1841
  compstmt
1700
1842
  {
1701
- line, cmdarg, param, cmpstmt = val
1843
+ line, _cmdarg, param, cmpstmt = val
1702
1844
 
1703
1845
  result = new_do_body param, cmpstmt, line
1846
+ lexer.cmdarg.pop
1704
1847
  self.env.unextend
1705
- lexer.cmdarg.restore cmdarg
1706
1848
  }
1707
1849
 
1708
1850
  case_body: k_when
@@ -1723,7 +1865,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1723
1865
  (_, line), klasses, var, _, body, rest = val
1724
1866
 
1725
1867
  klasses ||= s(:array)
1726
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1868
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1727
1869
  klasses.line line
1728
1870
 
1729
1871
  result = new_resbody(klasses, body)
@@ -1736,7 +1878,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1736
1878
 
1737
1879
  exc_list: arg_value
1738
1880
  {
1739
- result = s(:array, val[0])
1881
+ arg, = val
1882
+ result = s(:array, arg).line arg.line
1740
1883
  }
1741
1884
  | mrhs
1742
1885
  | none
@@ -1749,26 +1892,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1749
1892
 
1750
1893
  opt_ensure: k_ensure compstmt
1751
1894
  {
1752
- _, body = val
1895
+ (_, line), body = val
1753
1896
 
1754
- result = body || s(:nil)
1897
+ result = body || s(:nil).line(line)
1755
1898
  }
1756
1899
  | none
1757
1900
 
1758
1901
  literal: numeric
1759
1902
  {
1903
+ line = lexer.lineno
1760
1904
  result = s(:lit, val[0])
1905
+ result.line = line
1761
1906
  }
1762
1907
  | symbol
1763
1908
  {
1909
+ line = lexer.lineno
1764
1910
  result = s(:lit, val[0])
1911
+ result.line = line
1765
1912
  }
1766
1913
  | dsym
1767
1914
 
1768
1915
  strings: string
1769
1916
  {
1770
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1771
- result = val[0]
1917
+ str, = val
1918
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1919
+ result = str
1772
1920
  }
1773
1921
 
1774
1922
  string: tCHAR
@@ -1783,7 +1931,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1783
1931
 
1784
1932
  string1: tSTRING_BEG string_contents tSTRING_END
1785
1933
  {
1786
- result = val[1]
1934
+ _, str, (_, func) = val
1935
+
1936
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1937
+
1938
+ result = str
1787
1939
  }
1788
1940
  | tSTRING
1789
1941
  {
@@ -1792,7 +1944,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1792
1944
 
1793
1945
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1794
1946
  {
1795
- result = new_xstring val[1]
1947
+ result = new_xstring val
1948
+ # TODO: dedent?!?! SERIOUSLY?!?
1796
1949
  }
1797
1950
 
1798
1951
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1802,7 +1955,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1955
 
1803
1956
  words: tWORDS_BEG tSPACE tSTRING_END
1804
1957
  {
1805
- result = s(:array)
1958
+ result = s(:array).line lexer.lineno
1806
1959
  }
1807
1960
  | tWORDS_BEG word_list tSTRING_END
1808
1961
  {
@@ -1826,25 +1979,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1979
 
1827
1980
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1828
1981
  {
1829
- result = s(:array)
1982
+ result = s(:array).line lexer.lineno
1830
1983
  }
1831
- | tSYMBOLS_BEG symbol_list tSTRING_END
1984
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1832
1985
  {
1833
- result = val[1]
1986
+ _, line, list, _, = val
1987
+ list.line = line
1988
+ result = list
1834
1989
  }
1835
1990
 
1836
1991
  symbol_list: none
1837
1992
  {
1838
- result = new_symbol_list
1993
+ result = new_symbol_list.line lexer.lineno
1839
1994
  }
1840
1995
  | symbol_list word tSPACE
1841
1996
  {
1842
- result = val[0].dup << new_symbol_list_entry(val)
1997
+ list, * = val
1998
+ result = list.dup << new_symbol_list_entry(val)
1843
1999
  }
1844
2000
 
1845
2001
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1846
2002
  {
1847
- result = s(:array)
2003
+ result = s(:array).line lexer.lineno
1848
2004
  }
1849
2005
  | tQWORDS_BEG qword_list tSTRING_END
1850
2006
  {
@@ -1853,7 +2009,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1853
2009
 
1854
2010
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1855
2011
  {
1856
- result = s(:array)
2012
+ result = s(:array).line lexer.lineno # FIX
1857
2013
  }
1858
2014
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1859
2015
  {
@@ -1880,11 +2036,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1880
2036
 
1881
2037
  string_contents: none
1882
2038
  {
1883
- result = s(:str, "")
2039
+ result = s(:str, "").line lexer.lineno
1884
2040
  }
1885
2041
  | string_contents string_content
1886
2042
  {
1887
- result = literal_concat(val[0], val[1])
2043
+ v1, v2 = val
2044
+ result = literal_concat v1, v2
1888
2045
  }
1889
2046
 
1890
2047
  xstring_contents: none
@@ -1893,7 +2050,8 @@ xstring_contents: none
1893
2050
  }
1894
2051
  | xstring_contents string_content
1895
2052
  {
1896
- result = literal_concat(val[0], val[1])
2053
+ v1, v2 = val
2054
+ result = literal_concat v1, v2
1897
2055
  }
1898
2056
 
1899
2057
  regexp_contents: none
@@ -1902,7 +2060,8 @@ regexp_contents: none
1902
2060
  }
1903
2061
  | regexp_contents string_content
1904
2062
  {
1905
- result = literal_concat(val[0], val[1])
2063
+ v1, v2 = val
2064
+ result = literal_concat v1, v2
1906
2065
  }
1907
2066
 
1908
2067
  string_content: tSTRING_CONTENT
@@ -1918,19 +2077,22 @@ regexp_contents: none
1918
2077
  }
1919
2078
  string_dvar
1920
2079
  {
1921
- lexer.lex_strterm = val[1]
1922
- result = s(:evstr, val[2])
2080
+ _, strterm, str = val
2081
+ lexer.lex_strterm = strterm
2082
+ result = s(:evstr, str).line str.line
1923
2083
  }
1924
2084
  | tSTRING_DBEG
1925
2085
  {
1926
2086
  result = [lexer.lex_strterm,
1927
2087
  lexer.brace_nest,
1928
2088
  lexer.string_nest, # TODO: remove
1929
- lexer.cond.store,
1930
- lexer.cmdarg.store,
1931
2089
  lexer.lex_state,
2090
+ lexer.lineno,
1932
2091
  ]
1933
2092
 
2093
+ lexer.cmdarg.push false
2094
+ lexer.cond.push false
2095
+
1934
2096
  lexer.lex_strterm = nil
1935
2097
  lexer.brace_nest = 0
1936
2098
  lexer.string_nest = 0
@@ -1942,14 +2104,15 @@ regexp_contents: none
1942
2104
  {
1943
2105
  _, memo, stmt, _ = val
1944
2106
 
1945
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2107
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2108
+ # TODO: heredoc_indent
1946
2109
 
1947
2110
  lexer.lex_strterm = lex_strterm
1948
2111
  lexer.brace_nest = brace_nest
1949
2112
  lexer.string_nest = string_nest
1950
2113
 
1951
- lexer.cond.restore oldcond
1952
- lexer.cmdarg.restore oldcmdarg
2114
+ lexer.cmdarg.pop
2115
+ lexer.cond.pop
1953
2116
 
1954
2117
  lexer.lex_state = oldlex_state
1955
2118
 
@@ -1959,19 +2122,19 @@ regexp_contents: none
1959
2122
  when :str, :dstr, :evstr then
1960
2123
  result = stmt
1961
2124
  else
1962
- result = s(:evstr, stmt)
2125
+ result = s(:evstr, stmt).line line
1963
2126
  end
1964
2127
  when nil then
1965
- result = s(:evstr)
2128
+ result = s(:evstr).line line
1966
2129
  else
1967
2130
  debug20 25
1968
2131
  raise "unknown string body: #{stmt.inspect}"
1969
2132
  end
1970
2133
  }
1971
2134
 
1972
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1973
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1974
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2135
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2136
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2137
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1975
2138
  | backref
1976
2139
 
1977
2140
  symbol: tSYMBEG sym
@@ -1988,18 +2151,19 @@ regexp_contents: none
1988
2151
 
1989
2152
  dsym: tSYMBEG xstring_contents tSTRING_END
1990
2153
  {
2154
+ _, result, _ = val
2155
+
1991
2156
  lexer.lex_state = EXPR_END
1992
- result = val[1]
1993
2157
 
1994
- result ||= s(:str, "")
2158
+ result ||= s(:str, "").line lexer.lineno
1995
2159
 
1996
2160
  case result.sexp_type
1997
2161
  when :dstr then
1998
2162
  result.sexp_type = :dsym
1999
2163
  when :str then
2000
- result = s(:lit, result.last.to_sym)
2164
+ result = s(:lit, result.last.to_sym).line result.line
2001
2165
  when :evstr then
2002
- result = s(:dsym, "", result)
2166
+ result = s(:dsym, "", result).line result.line
2003
2167
  else
2004
2168
  debug20 26, val, result
2005
2169
  end
@@ -2022,19 +2186,20 @@ regexp_contents: none
2022
2186
  | tCONSTANT
2023
2187
  | tCVAR
2024
2188
 
2025
- keyword_variable: kNIL { result = s(:nil) }
2026
- | kSELF { result = s(:self) }
2027
- | kTRUE { result = s(:true) }
2028
- | kFALSE { result = s(:false) }
2029
- | k__FILE__ { result = s(:str, self.file) }
2030
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2189
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2190
+ | kSELF { result = s(:self).line lexer.lineno }
2191
+ | kTRUE { result = s(:true).line lexer.lineno }
2192
+ | kFALSE { result = s(:false).line lexer.lineno }
2193
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2194
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2031
2195
  | k__ENCODING__
2032
2196
  {
2197
+ l = lexer.lineno
2033
2198
  result =
2034
2199
  if defined? Encoding then
2035
- s(:colon2, s(:const, :Encoding), :UTF_8)
2200
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2036
2201
  else
2037
- s(:str, "Unsupported!")
2202
+ s(:str, "Unsupported!").line l
2038
2203
  end
2039
2204
  }
2040
2205
 
@@ -2059,8 +2224,8 @@ keyword_variable: kNIL { result = s(:nil) }
2059
2224
  debug20 29, val, result
2060
2225
  }
2061
2226
 
2062
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2063
- | tBACK_REF { result = s(:back_ref, val[0]) }
2227
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2228
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2064
2229
 
2065
2230
  superclass: tLT
2066
2231
  {
@@ -2217,12 +2382,13 @@ keyword_variable: kNIL { result = s(:nil) }
2217
2382
 
2218
2383
  f_arg: f_arg_item
2219
2384
  {
2220
- case val[0]
2385
+ arg, = val
2386
+
2387
+ case arg
2221
2388
  when Symbol then
2222
- result = s(:args)
2223
- result << val[0]
2389
+ result = s(:args, arg).line lexer.lineno
2224
2390
  when Sexp then
2225
- result = val[0]
2391
+ result = arg
2226
2392
  else
2227
2393
  debug20 32
2228
2394
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2235,7 +2401,7 @@ keyword_variable: kNIL { result = s(:nil) }
2235
2401
  if list.sexp_type == :args then
2236
2402
  result = list
2237
2403
  else
2238
- result = s(:args, list)
2404
+ result = s(:args, list).line list.line
2239
2405
  end
2240
2406
 
2241
2407
  result << item
@@ -2245,38 +2411,42 @@ keyword_variable: kNIL { result = s(:nil) }
2245
2411
 
2246
2412
  f_kw: f_label arg_value
2247
2413
  {
2248
- # TODO: call_args
2249
- label, _ = val[0] # TODO: fix lineno?
2414
+ # TODO: new_kw_arg
2415
+ (label, line), arg = val
2416
+
2250
2417
  identifier = label.to_sym
2251
2418
  self.env[identifier] = :lvar
2252
2419
 
2253
- result = s(:array, s(:kwarg, identifier, val[1]))
2420
+ kwarg = s(:kwarg, identifier, arg).line line
2421
+ result = s(:array, kwarg).line line
2254
2422
  }
2255
2423
  | f_label
2256
2424
  {
2257
- label, _ = val[0] # TODO: fix lineno?
2258
- identifier = label.to_sym
2259
- self.env[identifier] = :lvar
2425
+ (label, line), = val
2260
2426
 
2261
- result = s(:array, s(:kwarg, identifier))
2427
+ id = label.to_sym
2428
+ self.env[id] = :lvar
2429
+
2430
+ result = s(:array, s(:kwarg, id).line(line)).line line
2262
2431
  }
2263
2432
 
2264
2433
  f_block_kw: f_label primary_value
2265
2434
  {
2266
- # TODO: call_args
2267
- label, _ = val[0] # TODO: fix lineno?
2268
- identifier = label.to_sym
2269
- self.env[identifier] = :lvar
2435
+ # TODO: new_kw_arg
2436
+ (label, line), expr = val
2437
+ id = label.to_sym
2438
+ self.env[id] = :lvar
2270
2439
 
2271
- result = s(:array, s(:kwarg, identifier, val[1]))
2440
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2272
2441
  }
2273
2442
  | f_label
2274
2443
  {
2275
- label, _ = val[0] # TODO: fix lineno?
2276
- identifier = label.to_sym
2277
- self.env[identifier] = :lvar
2444
+ # TODO: new_kw_arg
2445
+ (label, line), = val
2446
+ id = label.to_sym
2447
+ self.env[id] = :lvar
2278
2448
 
2279
- result = s(:array, s(:kwarg, identifier))
2449
+ result = s(:array, s(:kwarg, id).line(line)).line line
2280
2450
  }
2281
2451
 
2282
2452
  f_block_kwarg: f_block_kw
@@ -2319,17 +2489,20 @@ keyword_variable: kNIL { result = s(:nil) }
2319
2489
 
2320
2490
  f_block_optarg: f_block_opt
2321
2491
  {
2322
- result = s(:block, val[0])
2492
+ optblk, = val
2493
+ result = s(:block, optblk).line optblk.line
2323
2494
  }
2324
2495
  | f_block_optarg tCOMMA f_block_opt
2325
2496
  {
2326
- result = val[0]
2327
- result << val[2]
2497
+ optarg, _, optblk = val
2498
+ result = optarg
2499
+ result << optblk
2328
2500
  }
2329
2501
 
2330
2502
  f_optarg: f_opt
2331
2503
  {
2332
- result = s(:block, val[0])
2504
+ opt, = val
2505
+ result = s(:block, opt).line opt.line
2333
2506
  }
2334
2507
  | f_optarg tCOMMA f_opt
2335
2508
  {
@@ -2383,14 +2556,11 @@ keyword_variable: kNIL { result = s(:nil) }
2383
2556
  result.sexp_type == :lit
2384
2557
  }
2385
2558
 
2386
- assoc_list: none # [!nil]
2559
+ assoc_list: none
2387
2560
  {
2388
- result = s(:array)
2389
- }
2390
- | assocs trailer # [!nil]
2391
- {
2392
- result = val[0]
2561
+ result = s(:array).line lexer.lineno
2393
2562
  }
2563
+ | assocs trailer
2394
2564
 
2395
2565
  assocs: assoc
2396
2566
  | assocs tCOMMA assoc
@@ -2404,22 +2574,27 @@ keyword_variable: kNIL { result = s(:nil) }
2404
2574
 
2405
2575
  assoc: arg_value tASSOC arg_value
2406
2576
  {
2407
- result = s(:array, val[0], val[2])
2577
+ v1, _, v2 = val
2578
+ result = s(:array, v1, v2).line v1.line
2408
2579
  }
2409
2580
  | tLABEL arg_value
2410
2581
  {
2411
- (label, _), arg = val
2412
- result = s(:array, s(:lit, label.to_sym), arg)
2582
+ (label, line), arg = val
2583
+
2584
+ lit = s(:lit, label.to_sym).line line
2585
+ result = s(:array, lit, arg).line line
2413
2586
  }
2414
2587
  | tSTRING_BEG string_contents tLABEL_END arg_value
2415
2588
  {
2416
2589
  _, sym, _, value = val
2417
2590
  sym.sexp_type = :dsym
2418
- result = s(:array, sym, value)
2591
+ result = s(:array, sym, value).line sym.line
2419
2592
  }
2420
2593
  | tDSTAR arg_value
2421
2594
  {
2422
- result = s(:array, s(:kwsplat, val[1]))
2595
+ _, arg = val
2596
+ line = arg.line
2597
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2423
2598
  }
2424
2599
 
2425
2600
  operation: tIDENTIFIER | tCONSTANT | tFID