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