ruby_parser 3.13.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,6 +14,8 @@ class Ruby24Parser
14
14
  class Ruby25Parser
15
15
  #elif V == 26
16
16
  class Ruby26Parser
17
+ #elif V == 27
18
+ class Ruby27Parser
17
19
  #else
18
20
  fail "version not specified or supported on code generation"
19
21
  #endif
@@ -45,35 +47,35 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
45
47
  tLONELY
46
48
  #endif
47
49
 
48
- prechigh
49
- right tBANG tTILDE tUPLUS
50
- right tPOW
51
- right tUMINUS_NUM tUMINUS
52
- left tSTAR2 tDIVIDE tPERCENT
53
- left tPLUS tMINUS
54
- left tLSHFT tRSHFT
55
- left tAMPER2
56
- left tPIPE tCARET
57
- left tGT tGEQ tLT tLEQ
58
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
59
- left tANDOP
60
- left tOROP
61
- nonassoc tDOT2 tDOT3
62
- right tEH tCOLON
63
- left kRESCUE_MOD
64
- right tEQL tOP_ASGN
65
- nonassoc kDEFINED
66
- right kNOT
67
- left kOR kAND
68
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
69
- nonassoc tLBRACE_ARG
70
- nonassoc tLOWEST
71
50
  preclow
51
+ nonassoc tLOWEST
52
+ nonassoc tLBRACE_ARG
53
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
54
+ left kOR kAND
55
+ right kNOT
56
+ nonassoc kDEFINED
57
+ right tEQL tOP_ASGN
58
+ left kRESCUE_MOD
59
+ right tEH tCOLON
60
+ nonassoc tDOT2 tDOT3
61
+ left tOROP
62
+ left tANDOP
63
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
64
+ left tGT tGEQ tLT tLEQ
65
+ left tPIPE tCARET
66
+ left tAMPER2
67
+ left tLSHFT tRSHFT
68
+ left tPLUS tMINUS
69
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
70
+ right tUMINUS_NUM tUMINUS
71
+ right tPOW
72
+ right tBANG tTILDE tUPLUS
73
+ prechigh
72
74
 
73
75
  rule
74
76
 
75
77
  program: {
76
- self.lexer.lex_state = :expr_beg
78
+ self.lexer.lex_state = EXPR_BEG
77
79
  }
78
80
  top_compstmt
79
81
  {
@@ -82,7 +84,8 @@ rule
82
84
 
83
85
  top_compstmt: top_stmts opt_terms
84
86
  {
85
- result = val[0]
87
+ stmt, _ = val
88
+ result = stmt
86
89
  }
87
90
 
88
91
  top_stmts: none
@@ -94,14 +97,6 @@ rule
94
97
  | error top_stmt
95
98
 
96
99
  top_stmt: stmt
97
- {
98
- result = val[0]
99
-
100
- # TODO: remove once I have more confidence this is fixed
101
- # result.each_of_type :call_args do |s|
102
- # debug20 666, s, result
103
- # end
104
- }
105
100
  | klBEGIN
106
101
  {
107
102
  if (self.in_def || self.in_single > 0) then
@@ -112,14 +107,19 @@ rule
112
107
  }
113
108
  begin_block
114
109
  {
115
- _, _, block = val
116
- result = block
110
+ (_, lineno), _, iter = val
111
+ iter.line lineno
112
+
113
+ (_, preexe,) = iter
114
+ preexe.line lineno
115
+
116
+ result = iter
117
117
  }
118
118
 
119
- begin_block: tLCURLY top_compstmt tRCURLY
119
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
120
120
  {
121
- _, stmt, _ = val
122
- result = new_iter s(:preexe), 0, stmt
121
+ _, line, stmt, _ = val
122
+ result = new_iter s(:preexe).line(line), 0, stmt
123
123
  }
124
124
 
125
125
  bodystmt: compstmt opt_rescue k_else
@@ -161,34 +161,27 @@ rule
161
161
  stmt_or_begin: stmt
162
162
  | klBEGIN
163
163
  {
164
- if (self.in_def || self.in_single > 0) then
165
- debug20 1
166
- yyerror "BEGIN in method"
167
- end
168
- self.env.extend
169
- }
170
- begin_block
171
- {
172
- _, _, stmt = val
173
- result = stmt
164
+ yyerror "BEGIN is permitted only at toplevel"
174
165
  }
175
166
 
176
167
  stmt: kALIAS fitem
177
168
  {
178
- lexer.lex_state = :expr_fname
179
- result = self.lexer.lineno
169
+ lexer.lex_state = EXPR_FNAME
180
170
  }
181
171
  fitem
182
172
  {
183
- result = s(:alias, val[1], val[3]).line(val[2])
173
+ (_, line), lhs, _, rhs = val
174
+ result = s(:alias, lhs, rhs).line(line).line line
184
175
  }
185
176
  | kALIAS tGVAR tGVAR
186
177
  {
187
- result = s(:valias, val[1].to_sym, val[2].to_sym)
178
+ (_, line), lhs, rhs = val
179
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
188
180
  }
189
181
  | kALIAS tGVAR tBACK_REF
190
182
  {
191
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
183
+ (_, line), lhs, rhs = val
184
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
192
185
  }
193
186
  | kALIAS tGVAR tNTH_REF
194
187
  {
@@ -200,32 +193,41 @@ rule
200
193
  }
201
194
  | stmt kIF_MOD expr_value
202
195
  {
203
- result = new_if val[2], val[0], nil
196
+ t, _, c = val
197
+ result = new_if c, t, nil
204
198
  }
205
199
  | stmt kUNLESS_MOD expr_value
206
200
  {
207
- result = new_if val[2], nil, val[0]
201
+ f, _, c = val
202
+ result = new_if c, nil, f
208
203
  }
209
204
  | stmt kWHILE_MOD expr_value
210
205
  {
211
- result = new_while val[0], val[2], true
206
+ e, _, c = val
207
+ result = new_while e, c, true
212
208
  }
213
209
  | stmt kUNTIL_MOD expr_value
214
210
  {
215
- result = new_until val[0], val[2], true
211
+ e, _, c = val
212
+ result = new_until e, c, true
216
213
  }
217
214
  | stmt kRESCUE_MOD stmt
218
215
  {
219
216
  body, _, resbody = val
220
- result = new_rescue body, new_resbody(s(:array), resbody)
217
+
218
+ resbody = new_resbody s(:array).line(resbody.line), resbody
219
+ result = new_rescue body, resbody
221
220
  }
222
221
  | klEND tLCURLY compstmt tRCURLY
223
222
  {
223
+ (_, line), _, stmt, _ = val
224
+
224
225
  if (self.in_def || self.in_single > 0) then
225
226
  debug20 3
226
227
  yyerror "END in method; use at_exit"
227
228
  end
228
- result = new_iter s(:postexe), 0, val[2]
229
+
230
+ result = new_iter s(:postexe).line(line), 0, stmt
229
231
  }
230
232
  | command_asgn
231
233
  | mlhs tEQL command_call
@@ -234,7 +236,8 @@ rule
234
236
  }
235
237
  | lhs tEQL mrhs
236
238
  {
237
- result = new_assign val[0], s(:svalue, val[2])
239
+ lhs, _, rhs = val
240
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
238
241
  }
239
242
  #if V == 20
240
243
  | mlhs tEQL arg_value
@@ -264,11 +267,12 @@ rule
264
267
  }
265
268
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
266
269
  {
267
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
270
+ result = new_op_asgn1 val
268
271
  }
269
272
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
270
273
  {
271
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
274
+ prim, _, id, opasgn, rhs = val
275
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
272
276
  if val[1] == '&.'
273
277
  result.sexp_type = :safe_op_asgn
274
278
  end
@@ -284,13 +288,15 @@ rule
284
288
  }
285
289
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
286
290
  {
287
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
288
- debug20 4, val, result
291
+ lhs1, _, lhs2, op, rhs = val
292
+
293
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
289
294
  }
290
295
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
291
296
  {
292
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
293
- debug20 5, val, result
297
+ lhs1, _, lhs2, op, rhs = val
298
+
299
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
294
300
  }
295
301
  | backref tOP_ASGN command_rhs
296
302
  {
@@ -302,30 +308,41 @@ rule
302
308
  expr, = val
303
309
  result = value_expr expr
304
310
  }
311
+ #if V >= 24
305
312
  | command_call kRESCUE_MOD stmt
306
313
  {
307
- expr, _, resbody = val
314
+ expr, (_, line), resbody = val
315
+
308
316
  expr = value_expr expr
309
- result = new_rescue(expr, new_resbody(s(:array), resbody))
317
+ ary = s(:array).line line
318
+ result = new_rescue(expr, new_resbody(ary, resbody))
310
319
  }
320
+ #endif
311
321
  | command_asgn
312
322
 
313
323
  expr: command_call
314
324
  | expr kAND expr
315
325
  {
316
- result = logical_op :and, val[0], val[2]
326
+ lhs, _, rhs = val
327
+ result = logical_op :and, lhs, rhs
317
328
  }
318
329
  | expr kOR expr
319
330
  {
320
- result = logical_op :or, val[0], val[2]
331
+ lhs, _, rhs = val
332
+ result = logical_op :or, lhs, rhs
321
333
  }
322
334
  | kNOT opt_nl expr
323
335
  {
324
- result = s(:call, val[2], :"!")
336
+ (_, line), _, expr = val
337
+ result = new_call(expr, :"!").line line
338
+ # REFACTOR: call_uni_op
325
339
  }
326
340
  | tBANG command_call
327
341
  {
328
- result = s(:call, val[1], :"!")
342
+ _, cmd = val
343
+ result = new_call(cmd, :"!").line cmd.line
344
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
345
+ # REFACTOR: call_uni_op -- see parse26.y
329
346
  }
330
347
  | arg
331
348
 
@@ -352,7 +369,8 @@ rule
352
369
  block_command: block_call
353
370
  | block_call call_op2 operation2 command_args
354
371
  {
355
- result = new_call val[0], val[2].to_sym, val[3]
372
+ blk, _, msg, args = val
373
+ result = new_call(blk, msg.to_sym, args).line blk.line
356
374
  }
357
375
 
358
376
  cmd_brace_block: tLBRACE_ARG
@@ -372,26 +390,32 @@ rule
372
390
 
373
391
  fcall: operation
374
392
  {
375
- result = new_call nil, val[0].to_sym
393
+ msg, = val
394
+ result = new_call(nil, msg.to_sym).line lexer.lineno
376
395
  }
377
396
 
378
397
  command: fcall command_args =tLOWEST
379
398
  {
380
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
399
+ call, args = val
400
+ result = call.concat args.sexp_body
381
401
  }
382
402
  | fcall command_args cmd_brace_block
383
403
  {
384
- result = val[0].concat val[1].sexp_body
385
- if val[2] then
386
- block_dup_check result, val[2]
404
+ call, args, block = val
405
+
406
+ result = call.concat args.sexp_body
407
+
408
+ if block then
409
+ block_dup_check result, block
387
410
 
388
- result, operation = val[2], result
411
+ result, operation = block, result
389
412
  result.insert 1, operation
390
413
  end
391
414
  }
392
415
  | primary_value call_op operation2 command_args =tLOWEST
393
416
  {
394
- result = new_call val[0], val[2].to_sym, val[3], val[1]
417
+ lhs, callop, op, args = val
418
+ result = new_call lhs, op.to_sym, args, callop
395
419
  }
396
420
  | primary_value call_op operation2 command_args cmd_brace_block
397
421
  {
@@ -423,7 +447,9 @@ rule
423
447
  }
424
448
  | kYIELD command_args
425
449
  {
426
- result = new_yield val[1]
450
+ (_, line), args = val
451
+ result = new_yield args
452
+ result.line line # TODO: push to new_yield
427
453
  }
428
454
  | k_return call_args
429
455
  {
@@ -432,8 +458,8 @@ rule
432
458
  }
433
459
  | kBREAK call_args
434
460
  {
435
- line = val[0].last
436
- result = s(:break, ret_args(val[1])).line(line)
461
+ (_, line), args = val
462
+ result = s(:break, ret_args(args)).line line
437
463
  }
438
464
  | kNEXT call_args
439
465
  {
@@ -450,56 +476,79 @@ rule
450
476
  mlhs_inner: mlhs_basic
451
477
  | tLPAREN mlhs_inner rparen
452
478
  {
453
- result = s(:masgn, s(:array, val[1]))
479
+ _, arg, _ = val
480
+ l = arg.line
481
+
482
+ result = s(:masgn, s(:array, arg).line(l)).line l
454
483
  }
455
484
 
456
485
  mlhs_basic: mlhs_head
457
486
  {
458
- result = s(:masgn, val[0])
487
+ head, = val
488
+ result = s(:masgn, head).line head.line
459
489
  }
460
490
  | mlhs_head mlhs_item
461
491
  {
462
- result = s(:masgn, val[0] << val[1].compact)
492
+ lhs, rhs = val
493
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
463
494
  }
464
495
  | mlhs_head tSTAR mlhs_node
465
496
  {
466
- result = s(:masgn, val[0] << s(:splat, val[2]))
497
+ head, _, tail = val
498
+ head << s(:splat, tail).line(tail.line)
499
+ result = s(:masgn, head).line head.line
467
500
  }
468
501
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
469
502
  {
470
503
  ary1, _, splat, _, ary2 = val
471
504
 
472
- result = list_append ary1, s(:splat, splat)
505
+ result = list_append ary1, s(:splat, splat).line(splat.line)
473
506
  result.concat ary2.sexp_body
474
- result = s(:masgn, result)
507
+ result = s(:masgn, result).line result.line
475
508
  }
476
509
  | mlhs_head tSTAR
477
510
  {
478
- result = s(:masgn, val[0] << s(:splat))
511
+ head, _ = val
512
+ l = head.line
513
+ result = s(:masgn, head << s(:splat).line(l)).line l
479
514
  }
480
515
  | mlhs_head tSTAR tCOMMA mlhs_post
481
516
  {
482
- ary = list_append val[0], s(:splat)
483
- ary.concat val[3].sexp_body
484
- result = s(:masgn, ary)
517
+ head, _, _, post = val
518
+ ary = list_append head, s(:splat).line(head.line)
519
+ ary.concat post.sexp_body
520
+ result = s(:masgn, ary).line ary.line
485
521
  }
486
522
  | tSTAR mlhs_node
487
523
  {
488
- result = s(:masgn, s(:array, s(:splat, val[1])))
524
+ _, node = val
525
+ l = node.line
526
+ splat = s(:splat, node).line l
527
+ ary = s(:array, splat).line l
528
+ result = s(:masgn, ary).line l
489
529
  }
490
530
  | tSTAR mlhs_node tCOMMA mlhs_post
491
531
  {
492
- ary = s(:array, s(:splat, val[1]))
493
- ary.concat val[3].sexp_body
494
- result = s(:masgn, ary)
532
+ _, node, _, post = val
533
+
534
+ splat = s(:splat, node).line node.line
535
+ ary = s(:array, splat).line splat.line
536
+ ary.concat post.sexp_body
537
+ result = s(:masgn, ary).line ary.line
495
538
  }
496
539
  | tSTAR
497
540
  {
498
- result = s(:masgn, s(:array, s(:splat)))
541
+ l = lexer.lineno
542
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
499
543
  }
500
544
  | tSTAR tCOMMA mlhs_post
501
545
  {
502
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
546
+ _, _, post = val
547
+ l = post.line
548
+
549
+ splat = s(:splat).line l
550
+ ary = s(:array, splat, *post.sexp_body).line l
551
+ result = s(:masgn, ary).line l
503
552
  }
504
553
 
505
554
  mlhs_item: mlhs_node
@@ -510,7 +559,8 @@ rule
510
559
 
511
560
  mlhs_head: mlhs_item tCOMMA
512
561
  {
513
- result = s(:array, val[0])
562
+ lhs, _ = val
563
+ result = s(:array, lhs).line lhs.line
514
564
  }
515
565
  | mlhs_head mlhs_item tCOMMA
516
566
  {
@@ -519,7 +569,8 @@ rule
519
569
 
520
570
  mlhs_post: mlhs_item
521
571
  {
522
- result = s(:array, val[0])
572
+ item, = val
573
+ result = s(:array, item).line item.line
523
574
  }
524
575
  | mlhs_post tCOMMA mlhs_item
525
576
  {
@@ -544,7 +595,8 @@ rule
544
595
  }
545
596
  | primary_value tCOLON2 tIDENTIFIER
546
597
  {
547
- result = s(:attrasgn, val[0], :"#{val[2]}=")
598
+ recv, _, id = val
599
+ result = new_attrasgn recv, id
548
600
  }
549
601
  | primary_value call_op tCONSTANT
550
602
  {
@@ -557,7 +609,10 @@ rule
557
609
  yyerror "dynamic constant assignment"
558
610
  end
559
611
 
560
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
612
+ expr, _, id = val
613
+ l = expr.line
614
+
615
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
561
616
  }
562
617
  | tCOLON3 tCONSTANT
563
618
  {
@@ -566,7 +621,10 @@ rule
566
621
  yyerror "dynamic constant assignment"
567
622
  end
568
623
 
569
- result = s(:const, nil, s(:colon3, val[1].to_sym))
624
+ _, id = val
625
+ l = lexer.lineno
626
+
627
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
570
628
  }
571
629
  | backref
572
630
  {
@@ -575,24 +633,31 @@ rule
575
633
 
576
634
  lhs: user_variable
577
635
  {
636
+ line = lexer.lineno
578
637
  result = self.assignable val[0]
638
+ result.line = line
579
639
  }
580
640
  | keyword_variable
581
641
  {
642
+ line = lexer.lineno
582
643
  result = self.assignable val[0]
644
+ result.line = line
583
645
  debug20 9, val, result
584
646
  }
585
647
  | primary_value tLBRACK2 opt_call_args rbracket
586
648
  {
587
- result = self.aryset val[0], val[2]
649
+ lhs, _, args, _ = val
650
+ result = self.aryset lhs, args
588
651
  }
589
652
  | primary_value call_op tIDENTIFIER # REFACTOR
590
653
  {
591
- result = new_attrasgn val[0], val[2], val[1]
654
+ lhs, op, id = val
655
+ result = new_attrasgn lhs, id, op
592
656
  }
593
657
  | primary_value tCOLON2 tIDENTIFIER
594
658
  {
595
- result = s(:attrasgn, val[0], :"#{val[2]}=")
659
+ lhs, _, id = val
660
+ result = new_attrasgn lhs, id
596
661
  }
597
662
  | primary_value call_op tCONSTANT # REFACTOR?
598
663
  {
@@ -600,21 +665,27 @@ rule
600
665
  }
601
666
  | primary_value tCOLON2 tCONSTANT
602
667
  {
668
+ expr, _, id = val
669
+
603
670
  if (self.in_def || self.in_single > 0) then
604
671
  debug20 10
605
672
  yyerror "dynamic constant assignment"
606
673
  end
607
674
 
608
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
675
+ l = expr.line
676
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
609
677
  }
610
678
  | tCOLON3 tCONSTANT
611
679
  {
680
+ _, id = val
681
+
612
682
  if (self.in_def || self.in_single > 0) then
613
683
  debug20 11
614
684
  yyerror "dynamic constant assignment"
615
685
  end
616
686
 
617
- result = s(:const, s(:colon3, val[1].to_sym))
687
+ l = lexer.lineno
688
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
618
689
  }
619
690
  | backref
620
691
  {
@@ -629,7 +700,8 @@ rule
629
700
 
630
701
  cpath: tCOLON3 cname
631
702
  {
632
- result = s(:colon3, val[1].to_sym)
703
+ _, name = val
704
+ result = s(:colon3, name.to_sym).line lexer.lineno
633
705
  }
634
706
  | cname
635
707
  {
@@ -637,20 +709,23 @@ rule
637
709
  }
638
710
  | primary_value tCOLON2 cname
639
711
  {
640
- result = s(:colon2, val[0], val[2].to_sym)
712
+ pval, _, name = val
713
+
714
+ result = s(:colon2, pval, name.to_sym)
715
+ result.line pval.line
641
716
  }
642
717
 
643
718
  fname: tIDENTIFIER | tCONSTANT | tFID
644
719
  | op
645
720
  {
646
- lexer.lex_state = :expr_end
721
+ lexer.lex_state = EXPR_END
647
722
  result = val[0]
648
723
  }
649
724
 
650
725
  | reswords
651
726
  {
652
727
  (sym, _line), = val
653
- lexer.lex_state = :expr_end
728
+ lexer.lex_state = EXPR_END
654
729
  result = sym
655
730
  }
656
731
 
@@ -658,7 +733,8 @@ rule
658
733
 
659
734
  fitem: fsym
660
735
  {
661
- result = s(:lit, val[0].to_sym)
736
+ id, = val
737
+ result = s(:lit, id.to_sym).line lexer.lineno
662
738
  }
663
739
  | dsym
664
740
 
@@ -669,7 +745,7 @@ rule
669
745
  |
670
746
  undef_list tCOMMA
671
747
  {
672
- lexer.lex_state = :expr_fname
748
+ lexer.lex_state = EXPR_FNAME
673
749
  }
674
750
  fitem
675
751
  {
@@ -682,6 +758,7 @@ rule
682
758
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
683
759
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
684
760
  #if V >= 20
761
+ # TODO: tUBANG dead?
685
762
  | tUBANG
686
763
  #endif
687
764
 
@@ -705,8 +782,7 @@ rule
705
782
  }
706
783
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
707
784
  {
708
- val[2].sexp_type = :arglist if val[2]
709
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
785
+ result = new_op_asgn1 val
710
786
  }
711
787
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
712
788
  {
@@ -718,17 +794,27 @@ rule
718
794
  }
719
795
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
720
796
  {
721
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
797
+ lhs, _, id, op, rhs = val
798
+
799
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
722
800
  }
723
801
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
724
802
  {
725
- # TODO: assignment
726
- raise "not yet: %p" % [val]
803
+ lhs1, _, lhs2, op, rhs = val
804
+
805
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
806
+ result = new_const_op_asgn [lhs, op, rhs]
807
+ }
808
+ | tCOLON3 tCONSTANT
809
+ {
810
+ result = self.lexer.lineno
727
811
  }
728
- | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
812
+ tOP_ASGN arg_rhs
729
813
  {
730
- # TODO: assignment
731
- raise "not yet: %p" % [val]
814
+ _, lhs, line, op, rhs = val
815
+
816
+ lhs = s(:colon3, lhs.to_sym).line line
817
+ result = new_const_op_asgn [lhs, op, rhs]
732
818
  }
733
819
  | backref tOP_ASGN arg_rhs
734
820
  {
@@ -740,32 +826,34 @@ rule
740
826
  {
741
827
  v1, v2 = val[0], val[2]
742
828
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
743
- result = s(:lit, (v1.last)..(v2.last))
829
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
744
830
  else
745
- result = s(:dot2, v1, v2)
831
+ result = s(:dot2, v1, v2).line v1.line
746
832
  end
747
833
  }
748
834
  | arg tDOT3 arg
749
835
  {
750
836
  v1, v2 = val[0], val[2]
751
837
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
752
- result = s(:lit, (v1.last)...(v2.last))
838
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
753
839
  else
754
- result = s(:dot3, v1, v2)
840
+ result = s(:dot3, v1, v2).line v1.line
755
841
  end
756
842
  }
757
843
  #if V >= 26
758
844
  | arg tDOT2
759
845
  {
760
- v1, v2 = val[0], nil
846
+ v1, _ = val
847
+ v2 = nil
761
848
 
762
- result = s(:dot2, v1, v2)
849
+ result = s(:dot2, v1, v2).line v1.line
763
850
  }
764
851
  | arg tDOT3
765
852
  {
766
- v1, v2 = val[0], nil
853
+ v1, _ = val
854
+ v2 = nil
767
855
 
768
- result = s(:dot3, v1, v2)
856
+ result = s(:dot3, v1, v2).line v1.line
769
857
  }
770
858
  #endif
771
859
  | arg tPLUS arg
@@ -795,14 +883,17 @@ rule
795
883
  #if V == 20
796
884
  | tUMINUS_NUM tINTEGER tPOW arg
797
885
  {
798
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
886
+ lit = s(:lit, val[1]).line lexer.lineno
887
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
799
888
  }
800
889
  | tUMINUS_NUM tFLOAT tPOW arg
801
890
  #else
802
891
  | tUMINUS_NUM simple_numeric tPOW arg
803
892
  #endif
804
893
  {
805
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
894
+ lit = s(:lit, val[1]).line lexer.lineno
895
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
896
+
806
897
  #if V == 20
807
898
  ## TODO: why is this 2.0 only?
808
899
  debug20 12, val, result
@@ -847,15 +938,19 @@ rule
847
938
  }
848
939
  | arg tMATCH arg
849
940
  {
850
- result = new_match val[0], val[2]
941
+ lhs, _, rhs = val
942
+ result = new_match lhs, rhs
851
943
  }
852
944
  | arg tNMATCH arg
853
945
  {
854
- result = s(:not, new_match(val[0], val[2]))
946
+ lhs, _, rhs = val
947
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
855
948
  }
856
949
  | tBANG arg
857
950
  {
858
- result = new_call val[1], :"!"
951
+ _, arg = val
952
+ result = new_call arg, :"!"
953
+ result.line arg.line
859
954
  }
860
955
  | tTILDE arg
861
956
  {
@@ -883,11 +978,13 @@ rule
883
978
  }
884
979
  | kDEFINED opt_nl arg
885
980
  {
886
- result = s(:defined, val[2])
981
+ (_, line), _, arg = val
982
+ result = s(:defined, arg).line line
887
983
  }
888
984
  | arg tEH arg opt_nl tCOLON arg
889
985
  {
890
- result = s(:if, val[0], val[2], val[5])
986
+ c, _, t, _, _, f = val
987
+ result = s(:if, c, t, f).line c.line
891
988
  }
892
989
  | primary
893
990
 
@@ -930,28 +1027,25 @@ rule
930
1027
  arg_rhs: arg =tOP_ASGN
931
1028
  | arg kRESCUE_MOD arg
932
1029
  {
933
- body, _, resbody = val
1030
+ body, (_, line), resbody = val
934
1031
  body = value_expr body
935
1032
  resbody = remove_begin resbody
936
- result = new_rescue(body, new_resbody(s(:array), resbody))
1033
+
1034
+ ary = s(:array).line line
1035
+ result = new_rescue(body, new_resbody(ary, resbody))
937
1036
  }
938
1037
 
939
1038
  paren_args: tLPAREN2 opt_call_args rparen
940
1039
  {
941
- result = val[1]
1040
+ _, args, _ = val
1041
+ result = args
942
1042
  }
943
1043
 
944
1044
  opt_paren_args: none
945
1045
  | paren_args
946
1046
 
947
1047
  opt_call_args: none
948
- {
949
- result = val[0]
950
- }
951
1048
  | call_args
952
- {
953
- result = val[0]
954
- }
955
1049
  | args tCOMMA
956
1050
  {
957
1051
  result = args val
@@ -973,17 +1067,14 @@ rule
973
1067
  | args opt_block_arg
974
1068
  {
975
1069
  result = call_args val
976
- result = self.arg_blk_pass val[0], val[1]
977
1070
  }
978
1071
  | assocs opt_block_arg
979
1072
  {
980
- result = call_args [array_to_hash(val[0])]
981
- result = self.arg_blk_pass result, val[1]
1073
+ result = call_args [array_to_hash(val[0]), val[1]]
982
1074
  }
983
1075
  | args tCOMMA assocs opt_block_arg
984
1076
  {
985
- result = call_args [val[0], array_to_hash(val[2])]
986
- result = self.arg_blk_pass result, val[3]
1077
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
987
1078
  }
988
1079
  | block_arg
989
1080
  {
@@ -991,17 +1082,45 @@ rule
991
1082
  }
992
1083
 
993
1084
  command_args: {
994
- result = lexer.cmdarg.store true
1085
+ # parse26.y line 2200
1086
+
1087
+ # If call_args starts with a open paren '(' or
1088
+ # '[', look-ahead reading of the letters calls
1089
+ # CMDARG_PUSH(0), but the push must be done
1090
+ # after CMDARG_PUSH(1). So this code makes them
1091
+ # consistent by first cancelling the premature
1092
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1093
+ # finally redoing CMDARG_PUSH(0).
1094
+
1095
+ result = yychar = self.last_token_type.first
1096
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1097
+ lexer.cmdarg.pop if lookahead
1098
+ lexer.cmdarg.push true
1099
+ lexer.cmdarg.push false if lookahead
995
1100
  }
996
1101
  call_args
997
1102
  {
998
- lexer.cmdarg.restore val[0]
999
- result = val[1]
1103
+ yychar, args = val
1104
+
1105
+ # call_args can be followed by tLBRACE_ARG (that
1106
+ # does CMDARG_PUSH(0) in the lexer) but the push
1107
+ # must be done after CMDARG_POP() in the parser.
1108
+ # So this code does CMDARG_POP() to pop 0 pushed
1109
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1110
+ # by command_args, and CMDARG_PUSH(0) to restore
1111
+ # back the flag set by tLBRACE_ARG.
1112
+
1113
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1114
+ lexer.cmdarg.pop if lookahead
1115
+ lexer.cmdarg.pop
1116
+ lexer.cmdarg.push false if lookahead
1117
+ result = args
1000
1118
  }
1001
1119
 
1002
1120
  block_arg: tAMPER arg_value
1003
1121
  {
1004
- result = s(:block_pass, val[1])
1122
+ _, arg = val
1123
+ result = s(:block_pass, arg).line arg.line
1005
1124
  }
1006
1125
 
1007
1126
  opt_block_arg: tCOMMA block_arg
@@ -1012,19 +1131,27 @@ rule
1012
1131
 
1013
1132
  args: arg_value
1014
1133
  {
1015
- result = s(:array, val[0])
1134
+ arg, = val
1135
+ lineno = arg.line || lexer.lineno # HACK
1136
+
1137
+ result = s(:array, arg).line lineno
1016
1138
  }
1017
1139
  | tSTAR arg_value
1018
1140
  {
1019
- result = s(:array, s(:splat, val[1]))
1141
+ _, arg = val
1142
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1020
1143
  }
1021
1144
  | args tCOMMA arg_value
1022
1145
  {
1023
- result = self.list_append val[0], val[2]
1146
+ args, _, id = val
1147
+ result = self.list_append args, id
1024
1148
  }
1025
1149
  | args tCOMMA tSTAR arg_value
1026
1150
  {
1027
- result = self.list_append val[0], s(:splat, val[3])
1151
+ # TODO: the line number from tSTAR has been dropped
1152
+ args, _, _, id = val
1153
+ line = lexer.lineno
1154
+ result = self.list_append args, s(:splat, id).line(line)
1028
1155
  }
1029
1156
 
1030
1157
  #if V >= 21
@@ -1044,11 +1171,14 @@ rule
1044
1171
  }
1045
1172
  | args tCOMMA tSTAR arg_value
1046
1173
  {
1047
- result = self.arg_concat val[0], val[3]
1174
+ # TODO: make all tXXXX terminals include lexer.lineno
1175
+ arg, _, _, splat = val
1176
+ result = self.arg_concat arg, splat
1048
1177
  }
1049
1178
  | tSTAR arg_value
1050
1179
  {
1051
- result = s(:splat, val[1])
1180
+ _, arg = val
1181
+ result = s(:splat, arg).line arg.line
1052
1182
  }
1053
1183
 
1054
1184
  primary: literal
@@ -1063,65 +1193,65 @@ rule
1063
1193
  | backref
1064
1194
  | tFID
1065
1195
  {
1066
- result = new_call nil, val[0].to_sym
1196
+ msg, = val
1197
+ result = new_call nil, msg.to_sym
1067
1198
  }
1068
1199
  | k_begin
1069
1200
  {
1201
+ lexer.cmdarg.push false
1070
1202
  result = self.lexer.lineno
1071
- # TODO:
1072
- # $<val>1 = cmdarg_stack;
1073
- # CMDARG_SET(0);
1074
1203
  }
1075
1204
  bodystmt k_end
1076
1205
  {
1077
- # TODO: CMDARG_SET($<val>1);
1078
- unless val[2] then
1079
- result = s(:nil)
1080
- else
1081
- result = s(:begin, val[2])
1082
- end
1083
-
1084
- result.line = val[1]
1206
+ lexer.cmdarg.pop
1207
+ result = new_begin val
1085
1208
  }
1086
- | tLPAREN_ARG rparen
1209
+ | tLPAREN_ARG
1087
1210
  {
1088
- # TODO: lex_state = :expr_endarg in between
1089
- debug20 13, val, result
1211
+ lexer.lex_state = EXPR_ENDARG
1212
+ result = lexer.lineno
1090
1213
  }
1091
- | tLPAREN_ARG
1214
+ rparen
1092
1215
  {
1093
- result = lexer.cmdarg.store false
1094
- # result = self.lexer.cmdarg.stack.dup
1095
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1216
+ _, line, _ = val
1217
+ result = s(:begin).line line
1096
1218
  }
1219
+ | tLPAREN_ARG
1097
1220
  stmt
1098
1221
  {
1099
- lexer.lex_state = :expr_endarg
1222
+ lexer.lex_state = EXPR_ENDARG
1100
1223
  }
1101
1224
  rparen
1102
1225
  {
1103
- _, cmdarg, stmt, _, _, = val
1104
- warning "(...) interpreted as grouped expression"
1105
- lexer.cmdarg.restore cmdarg
1226
+ _, stmt, _, _, = val
1227
+ # warning "(...) interpreted as grouped expression"
1106
1228
  result = stmt
1107
1229
  }
1108
1230
  | tLPAREN compstmt tRPAREN
1109
1231
  {
1110
- result = val[1] || s(:nil)
1232
+ _, stmt, _ = val
1233
+ result = stmt
1234
+ result ||= s(:nil).line lexer.lineno
1111
1235
  result.paren = true
1112
1236
  }
1113
1237
  | primary_value tCOLON2 tCONSTANT
1114
1238
  {
1115
- result = s(:colon2, val[0], val[2].to_sym)
1239
+ expr, _, id = val
1240
+
1241
+ result = s(:colon2, expr, id.to_sym).line expr.line
1116
1242
  }
1117
1243
  | tCOLON3 tCONSTANT
1118
1244
  {
1119
- result = s(:colon3, val[1].to_sym)
1245
+ _, id = val
1246
+
1247
+ result = s(:colon3, id.to_sym).line lexer.lineno
1120
1248
  }
1121
- | tLBRACK aref_args tRBRACK
1249
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1122
1250
  {
1123
- result = val[1] || s(:array)
1251
+ _, line, args, _ = val
1252
+ result = args || s(:array)
1124
1253
  result.sexp_type = :array # aref_args is :args
1254
+ result.line line
1125
1255
  }
1126
1256
  | tLBRACE
1127
1257
  {
@@ -1133,7 +1263,8 @@ rule
1133
1263
  }
1134
1264
  | k_return
1135
1265
  {
1136
- result = s(:return)
1266
+ (_, line), = val
1267
+ result = s(:return).line line
1137
1268
  }
1138
1269
  | kYIELD tLPAREN2 call_args rparen
1139
1270
  {
@@ -1149,11 +1280,14 @@ rule
1149
1280
  }
1150
1281
  | kDEFINED opt_nl tLPAREN2 expr rparen
1151
1282
  {
1152
- result = s(:defined, val[3])
1283
+ (_, line), _, _, arg, _ = val
1284
+
1285
+ result = s(:defined, arg).line line
1153
1286
  }
1154
1287
  | kNOT tLPAREN2 expr rparen
1155
1288
  {
1156
- result = s(:call, val[2], :"!")
1289
+ _, _, lhs, _ = val
1290
+ result = new_call lhs, :"!"
1157
1291
  }
1158
1292
  | kNOT tLPAREN2 rparen
1159
1293
  {
@@ -1161,11 +1295,11 @@ rule
1161
1295
  }
1162
1296
  | fcall brace_block
1163
1297
  {
1164
- oper, iter = val[0], val[1]
1165
- call = oper # FIX
1298
+ call, iter = val
1299
+
1166
1300
  iter.insert 1, call
1167
1301
  result = iter
1168
- call.line = iter.line
1302
+ # FIX: probably not: call.line = iter.line
1169
1303
  }
1170
1304
  | method_call
1171
1305
  | method_call brace_block
@@ -1273,66 +1407,82 @@ rule
1273
1407
  }
1274
1408
  | k_def fname
1275
1409
  {
1276
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1410
+ result = self.in_def
1277
1411
 
1278
- self.comments.push self.lexer.comments
1279
- self.in_def = true
1412
+ self.in_def = true # group = local_push
1280
1413
  self.env.extend
1281
- # TODO: local->cmdargs = cmdarg_stack;
1282
- # TODO: port local_push_gen and local_pop_gen
1283
- lexer.cmdarg.stack.replace [false]
1414
+ lexer.cmdarg.push false
1415
+ lexer.cond.push false
1416
+
1417
+ self.comments.push self.lexer.comments
1284
1418
  }
1285
- f_arglist bodystmt k_end
1419
+ f_arglist bodystmt { result = lexer.lineno } k_end
1286
1420
  {
1287
- in_def, cmdarg = val[2]
1421
+ in_def = val[2]
1288
1422
 
1289
1423
  result = new_defn val
1290
1424
 
1291
- lexer.cmdarg.stack.replace cmdarg
1425
+ lexer.cond.pop # group = local_pop
1426
+ lexer.cmdarg.pop
1292
1427
  self.env.unextend
1293
1428
  self.in_def = in_def
1429
+
1294
1430
  self.lexer.comments # we don't care about comments in the body
1295
1431
  }
1296
1432
  | k_def singleton dot_or_colon
1297
1433
  {
1298
- self.comments.push self.lexer.comments
1299
- lexer.lex_state = :expr_fname
1434
+ lexer.lex_state = EXPR_FNAME
1300
1435
  }
1301
1436
  fname
1302
1437
  {
1303
- self.in_single += 1
1438
+ result = [self.in_def, lexer.lineno]
1439
+
1440
+ self.in_single += 1 # TODO: remove?
1441
+
1442
+ self.in_def = true # local_push
1304
1443
  self.env.extend
1305
- lexer.lex_state = :expr_endfn # force for args
1306
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1307
- lexer.cmdarg.stack.replace [false]
1444
+ lexer.cmdarg.push false
1445
+ lexer.cond.push false
1446
+
1447
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1448
+ self.comments.push self.lexer.comments
1308
1449
  }
1309
1450
  f_arglist bodystmt k_end
1310
1451
  {
1311
- line, cmdarg = val[5]
1312
- result = new_defs val
1313
- result[3].line line
1452
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1314
1453
 
1315
- lexer.cmdarg.stack.replace cmdarg
1454
+ result = new_defs val
1316
1455
 
1456
+ lexer.cond.pop # group = local_pop
1457
+ lexer.cmdarg.pop
1317
1458
  self.env.unextend
1459
+ self.in_def = in_def
1460
+
1318
1461
  self.in_single -= 1
1462
+
1463
+ # TODO: restore cur_arg ? what's cur_arg?
1464
+
1319
1465
  self.lexer.comments # we don't care about comments in the body
1320
1466
  }
1321
1467
  | kBREAK
1322
1468
  {
1323
- result = s(:break)
1469
+ (_, line), = val
1470
+ result = s(:break).line line
1324
1471
  }
1325
1472
  | kNEXT
1326
1473
  {
1327
- result = s(:next)
1474
+ (_, line), = val
1475
+ result = s(:next).line line
1328
1476
  }
1329
1477
  | kREDO
1330
1478
  {
1331
- result = s(:redo)
1479
+ (_, line), = val
1480
+ result = s(:redo).line line
1332
1481
  }
1333
1482
  | kRETRY
1334
1483
  {
1335
- result = s(:retry)
1484
+ (_, line), = val
1485
+ result = s(:retry).line line
1336
1486
  }
1337
1487
 
1338
1488
  primary_value: primary
@@ -1371,7 +1521,9 @@ rule
1371
1521
  if_tail: opt_else
1372
1522
  | k_elsif expr_value then compstmt if_tail
1373
1523
  {
1374
- result = s(:if, val[1], val[3], val[4])
1524
+ (_, line), c, _, t, rest = val
1525
+
1526
+ result = s(:if, c, t, rest).line line
1375
1527
  }
1376
1528
 
1377
1529
  opt_else: none
@@ -1394,7 +1546,9 @@ rule
1394
1546
 
1395
1547
  f_marg_list: f_marg
1396
1548
  {
1397
- result = s(:array, val[0])
1549
+ sym, = val
1550
+
1551
+ result = s(:array, sym).line lexer.lineno
1398
1552
  }
1399
1553
  | f_marg_list tCOMMA f_marg
1400
1554
  {
@@ -1468,7 +1622,9 @@ rule
1468
1622
  }
1469
1623
  | f_block_arg
1470
1624
  {
1471
- result = call_args val
1625
+ line = lexer.lineno
1626
+ result = call_args val # TODO: push line down
1627
+ result.line line
1472
1628
  }
1473
1629
 
1474
1630
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1499,7 +1655,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1499
1655
  }
1500
1656
  | f_arg tCOMMA
1501
1657
  {
1502
- result = args val
1658
+ result = args(val) << nil
1503
1659
  }
1504
1660
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1505
1661
  {
@@ -1551,7 +1707,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1551
1707
  }
1552
1708
  | tOROP
1553
1709
  {
1554
- result = s(:args)
1710
+ result = s(:args).line lexer.lineno
1555
1711
  }
1556
1712
  | tPIPE block_param opt_bv_decl tPIPE
1557
1713
  {
@@ -1576,34 +1732,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1576
1732
 
1577
1733
  bvar: tIDENTIFIER
1578
1734
  {
1579
- result = s(:shadow, val[0].to_sym)
1735
+ id, = val
1736
+ line = lexer.lineno
1737
+ result = s(:shadow, id.to_sym).line line
1580
1738
  }
1581
1739
  | f_bad_arg
1582
1740
 
1583
1741
  lambda: {
1584
1742
  self.env.extend :dynamic
1585
- result = self.lexer.lineno
1586
-
1587
- result = lexer.lpar_beg
1743
+ result = [lexer.lineno, lexer.lpar_beg]
1588
1744
  lexer.paren_nest += 1
1589
1745
  lexer.lpar_beg = lexer.paren_nest
1590
1746
  }
1591
1747
  f_larglist
1592
1748
  {
1593
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1749
+ lexer.cmdarg.push false
1594
1750
  }
1595
1751
  lambda_body
1596
1752
  {
1597
- lpar, args, (cmdarg, lineno), body = val
1753
+ (line, lpar), args, _cmdarg, body = val
1598
1754
  lexer.lpar_beg = lpar
1599
1755
 
1600
- lexer.cmdarg.restore cmdarg
1601
- lexer.cmdarg.lexpop
1756
+ lexer.cmdarg.pop
1602
1757
 
1603
- call = new_call nil, :lambda
1758
+ call = s(:lambda).line line
1604
1759
  result = new_iter call, args, body
1605
- result.line = lineno
1606
- self.env.unextend
1760
+ result.line = line
1761
+ self.env.unextend # TODO: dynapush & dynapop
1607
1762
  }
1608
1763
 
1609
1764
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1627,8 +1782,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1627
1782
 
1628
1783
  do_block: k_do_block do_body kEND
1629
1784
  {
1630
- # TODO: maybe fix lineno to kDO's lineno?
1631
- result = val[1]
1785
+ (_, line), iter, _ = val
1786
+ result = iter.line line
1632
1787
  }
1633
1788
 
1634
1789
  block_call: command do_block
@@ -1642,8 +1797,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1642
1797
 
1643
1798
  val = invert_block_call val if inverted? val
1644
1799
 
1645
- result = val[1]
1646
- result.insert 1, val[0]
1800
+ cmd, blk = val
1801
+
1802
+ result = blk
1803
+ result.insert 1, cmd
1647
1804
  }
1648
1805
  | block_call call_op2 operation2 opt_paren_args
1649
1806
  {
@@ -1674,8 +1831,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1674
1831
  }
1675
1832
  paren_args
1676
1833
  {
1677
- args = self.call_args val[2..-1]
1678
- result = val[0].concat args.sexp_body
1834
+ call, lineno, args = val
1835
+
1836
+ result = call.concat args.sexp_body if args
1837
+ result.line lineno
1679
1838
  }
1680
1839
  | primary_value call_op operation2 opt_paren_args
1681
1840
  {
@@ -1703,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1703
1862
  }
1704
1863
  | kSUPER
1705
1864
  {
1706
- result = s(:zsuper)
1865
+ result = s(:zsuper).line lexer.lineno
1707
1866
  }
1708
1867
  | primary_value tLBRACK2 opt_call_args rbracket
1709
1868
  {
@@ -1752,7 +1911,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1752
1911
  }
1753
1912
 
1754
1913
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1755
- { result = lexer.cmdarg.store(false) }
1914
+ { lexer.cmdarg.push false }
1756
1915
  opt_block_param
1757
1916
  #if V >= 25
1758
1917
  bodystmt
@@ -1760,11 +1919,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1760
1919
  compstmt
1761
1920
  #endif
1762
1921
  {
1763
- line, cmdarg, param, cmpstmt = val
1922
+ line, _cmdarg, param, cmpstmt = val
1764
1923
 
1765
1924
  result = new_do_body param, cmpstmt, line
1925
+ lexer.cmdarg.pop
1766
1926
  self.env.unextend
1767
- lexer.cmdarg.restore cmdarg
1768
1927
  }
1769
1928
 
1770
1929
  case_body: k_when
@@ -1785,7 +1944,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1785
1944
  (_, line), klasses, var, _, body, rest = val
1786
1945
 
1787
1946
  klasses ||= s(:array)
1788
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1947
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1789
1948
  klasses.line line
1790
1949
 
1791
1950
  result = new_resbody(klasses, body)
@@ -1798,7 +1957,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1798
1957
 
1799
1958
  exc_list: arg_value
1800
1959
  {
1801
- result = s(:array, val[0])
1960
+ arg, = val
1961
+ result = s(:array, arg).line arg.line
1802
1962
  }
1803
1963
  | mrhs
1804
1964
  | none
@@ -1811,26 +1971,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1811
1971
 
1812
1972
  opt_ensure: k_ensure compstmt
1813
1973
  {
1814
- _, body = val
1974
+ (_, line), body = val
1815
1975
 
1816
- result = body || s(:nil)
1976
+ result = body || s(:nil).line(line)
1817
1977
  }
1818
1978
  | none
1819
1979
 
1820
1980
  literal: numeric
1821
1981
  {
1982
+ line = lexer.lineno
1822
1983
  result = s(:lit, val[0])
1984
+ result.line = line
1823
1985
  }
1824
1986
  | symbol
1825
1987
  {
1988
+ line = lexer.lineno
1826
1989
  result = s(:lit, val[0])
1990
+ result.line = line
1827
1991
  }
1828
1992
  | dsym
1829
1993
 
1830
1994
  strings: string
1831
1995
  {
1832
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1833
- result = val[0]
1996
+ str, = val
1997
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1998
+ result = str
1834
1999
  }
1835
2000
 
1836
2001
  string: tCHAR
@@ -1845,7 +2010,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1845
2010
 
1846
2011
  string1: tSTRING_BEG string_contents tSTRING_END
1847
2012
  {
1848
- result = val[1]
2013
+ _, str, (_, func) = val
2014
+
2015
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2016
+
2017
+ result = str
1849
2018
  }
1850
2019
  | tSTRING
1851
2020
  {
@@ -1854,7 +2023,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1854
2023
 
1855
2024
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1856
2025
  {
1857
- result = new_xstring val[1]
2026
+ result = new_xstring val
2027
+ # TODO: dedent?!?! SERIOUSLY?!?
1858
2028
  }
1859
2029
 
1860
2030
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1864,7 +2034,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
2034
 
1865
2035
  words: tWORDS_BEG tSPACE tSTRING_END
1866
2036
  {
1867
- result = s(:array)
2037
+ result = s(:array).line lexer.lineno
1868
2038
  }
1869
2039
  | tWORDS_BEG word_list tSTRING_END
1870
2040
  {
@@ -1888,25 +2058,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1888
2058
 
1889
2059
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1890
2060
  {
1891
- result = s(:array)
2061
+ result = s(:array).line lexer.lineno
1892
2062
  }
1893
- | tSYMBOLS_BEG symbol_list tSTRING_END
2063
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1894
2064
  {
1895
- result = val[1]
2065
+ _, line, list, _, = val
2066
+ list.line = line
2067
+ result = list
1896
2068
  }
1897
2069
 
1898
2070
  symbol_list: none
1899
2071
  {
1900
- result = new_symbol_list
2072
+ result = new_symbol_list.line lexer.lineno
1901
2073
  }
1902
2074
  | symbol_list word tSPACE
1903
2075
  {
1904
- result = val[0].dup << new_symbol_list_entry(val)
2076
+ list, * = val
2077
+ result = list.dup << new_symbol_list_entry(val)
1905
2078
  }
1906
2079
 
1907
2080
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1908
2081
  {
1909
- result = s(:array)
2082
+ result = s(:array).line lexer.lineno
1910
2083
  }
1911
2084
  | tQWORDS_BEG qword_list tSTRING_END
1912
2085
  {
@@ -1915,7 +2088,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1915
2088
 
1916
2089
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1917
2090
  {
1918
- result = s(:array)
2091
+ result = s(:array).line lexer.lineno # FIX
1919
2092
  }
1920
2093
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1921
2094
  {
@@ -1942,11 +2115,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1942
2115
 
1943
2116
  string_contents: none
1944
2117
  {
1945
- result = s(:str, "")
2118
+ result = s(:str, "").line lexer.lineno
1946
2119
  }
1947
2120
  | string_contents string_content
1948
2121
  {
1949
- result = literal_concat(val[0], val[1])
2122
+ v1, v2 = val
2123
+ result = literal_concat v1, v2
1950
2124
  }
1951
2125
 
1952
2126
  xstring_contents: none
@@ -1955,7 +2129,8 @@ xstring_contents: none
1955
2129
  }
1956
2130
  | xstring_contents string_content
1957
2131
  {
1958
- result = literal_concat(val[0], val[1])
2132
+ v1, v2 = val
2133
+ result = literal_concat v1, v2
1959
2134
  }
1960
2135
 
1961
2136
  regexp_contents: none
@@ -1964,7 +2139,8 @@ regexp_contents: none
1964
2139
  }
1965
2140
  | regexp_contents string_content
1966
2141
  {
1967
- result = literal_concat(val[0], val[1])
2142
+ v1, v2 = val
2143
+ result = literal_concat v1, v2
1968
2144
  }
1969
2145
 
1970
2146
  string_content: tSTRING_CONTENT
@@ -1976,42 +2152,46 @@ regexp_contents: none
1976
2152
  result = lexer.lex_strterm
1977
2153
 
1978
2154
  lexer.lex_strterm = nil
1979
- lexer.lex_state = :expr_beg
2155
+ lexer.lex_state = EXPR_BEG
1980
2156
  }
1981
2157
  string_dvar
1982
2158
  {
1983
- lexer.lex_strterm = val[1]
1984
- result = s(:evstr, val[2])
2159
+ _, strterm, str = val
2160
+ lexer.lex_strterm = strterm
2161
+ result = s(:evstr, str).line str.line
1985
2162
  }
1986
2163
  | tSTRING_DBEG
1987
2164
  {
1988
2165
  result = [lexer.lex_strterm,
1989
2166
  lexer.brace_nest,
1990
2167
  lexer.string_nest, # TODO: remove
1991
- lexer.cond.store,
1992
- lexer.cmdarg.store,
1993
2168
  lexer.lex_state,
2169
+ lexer.lineno,
1994
2170
  ]
1995
2171
 
2172
+ lexer.cmdarg.push false
2173
+ lexer.cond.push false
2174
+
1996
2175
  lexer.lex_strterm = nil
1997
2176
  lexer.brace_nest = 0
1998
2177
  lexer.string_nest = 0
1999
2178
 
2000
- lexer.lex_state = :expr_beg
2179
+ lexer.lex_state = EXPR_BEG
2001
2180
  }
2002
2181
  compstmt
2003
2182
  tSTRING_DEND
2004
2183
  {
2005
2184
  _, memo, stmt, _ = val
2006
2185
 
2007
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2186
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2187
+ # TODO: heredoc_indent
2008
2188
 
2009
2189
  lexer.lex_strterm = lex_strterm
2010
2190
  lexer.brace_nest = brace_nest
2011
2191
  lexer.string_nest = string_nest
2012
2192
 
2013
- lexer.cond.restore oldcond
2014
- lexer.cmdarg.restore oldcmdarg
2193
+ lexer.cmdarg.pop
2194
+ lexer.cond.pop
2015
2195
 
2016
2196
  lexer.lex_state = oldlex_state
2017
2197
 
@@ -2021,24 +2201,24 @@ regexp_contents: none
2021
2201
  when :str, :dstr, :evstr then
2022
2202
  result = stmt
2023
2203
  else
2024
- result = s(:evstr, stmt)
2204
+ result = s(:evstr, stmt).line line
2025
2205
  end
2026
2206
  when nil then
2027
- result = s(:evstr)
2207
+ result = s(:evstr).line line
2028
2208
  else
2029
2209
  debug20 25
2030
2210
  raise "unknown string body: #{stmt.inspect}"
2031
2211
  end
2032
2212
  }
2033
2213
 
2034
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
2035
- | tIVAR { result = s(:ivar, val[0].to_sym) }
2036
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2214
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2215
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2216
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2037
2217
  | backref
2038
2218
 
2039
2219
  symbol: tSYMBEG sym
2040
2220
  {
2041
- lexer.lex_state = :expr_end
2221
+ lexer.lex_state = EXPR_END
2042
2222
  result = val[1].to_sym
2043
2223
  }
2044
2224
  | tSYMBOL
@@ -2050,18 +2230,19 @@ regexp_contents: none
2050
2230
 
2051
2231
  dsym: tSYMBEG xstring_contents tSTRING_END
2052
2232
  {
2053
- lexer.lex_state = :expr_end
2054
- result = val[1]
2233
+ _, result, _ = val
2234
+
2235
+ lexer.lex_state = EXPR_END
2055
2236
 
2056
- result ||= s(:str, "")
2237
+ result ||= s(:str, "").line lexer.lineno
2057
2238
 
2058
2239
  case result.sexp_type
2059
2240
  when :dstr then
2060
2241
  result.sexp_type = :dsym
2061
2242
  when :str then
2062
- result = s(:lit, result.last.to_sym)
2243
+ result = s(:lit, result.last.to_sym).line result.line
2063
2244
  when :evstr then
2064
- result = s(:dsym, "", result)
2245
+ result = s(:dsym, "", result).line result.line
2065
2246
  else
2066
2247
  debug20 26, val, result
2067
2248
  end
@@ -2098,19 +2279,20 @@ regexp_contents: none
2098
2279
  | tCONSTANT
2099
2280
  | tCVAR
2100
2281
 
2101
- keyword_variable: kNIL { result = s(:nil) }
2102
- | kSELF { result = s(:self) }
2103
- | kTRUE { result = s(:true) }
2104
- | kFALSE { result = s(:false) }
2105
- | k__FILE__ { result = s(:str, self.file) }
2106
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2282
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2283
+ | kSELF { result = s(:self).line lexer.lineno }
2284
+ | kTRUE { result = s(:true).line lexer.lineno }
2285
+ | kFALSE { result = s(:false).line lexer.lineno }
2286
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2287
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2107
2288
  | k__ENCODING__
2108
2289
  {
2290
+ l = lexer.lineno
2109
2291
  result =
2110
2292
  if defined? Encoding then
2111
- s(:colon2, s(:const, :Encoding), :UTF_8)
2293
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2112
2294
  else
2113
- s(:str, "Unsupported!")
2295
+ s(:str, "Unsupported!").line l
2114
2296
  end
2115
2297
  }
2116
2298
 
@@ -2135,12 +2317,12 @@ keyword_variable: kNIL { result = s(:nil) }
2135
2317
  debug20 29, val, result
2136
2318
  }
2137
2319
 
2138
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2139
- | tBACK_REF { result = s(:back_ref, val[0]) }
2320
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2321
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2140
2322
 
2141
2323
  superclass: tLT
2142
2324
  {
2143
- lexer.lex_state = :expr_beg
2325
+ lexer.lex_state = EXPR_BEG
2144
2326
  lexer.command_start = true
2145
2327
  }
2146
2328
  expr_value term
@@ -2155,13 +2337,13 @@ keyword_variable: kNIL { result = s(:nil) }
2155
2337
  f_arglist: tLPAREN2 f_args rparen
2156
2338
  {
2157
2339
  result = val[1]
2158
- self.lexer.lex_state = :expr_beg
2340
+ self.lexer.lex_state = EXPR_BEG
2159
2341
  self.lexer.command_start = true
2160
2342
  }
2161
2343
  | {
2162
2344
  result = self.in_kwarg
2163
2345
  self.in_kwarg = true
2164
- # TODO: self.lexer.lex_state |= :expr_label
2346
+ self.lexer.lex_state |= EXPR_LABEL
2165
2347
  }
2166
2348
  f_args term
2167
2349
  {
@@ -2169,7 +2351,7 @@ keyword_variable: kNIL { result = s(:nil) }
2169
2351
 
2170
2352
  self.in_kwarg = kwarg
2171
2353
  result = args
2172
- lexer.lex_state = :expr_beg
2354
+ lexer.lex_state = EXPR_BEG
2173
2355
  lexer.command_start = true
2174
2356
  }
2175
2357
 
@@ -2301,12 +2483,13 @@ keyword_variable: kNIL { result = s(:nil) }
2301
2483
 
2302
2484
  f_arg: f_arg_item
2303
2485
  {
2304
- case val[0]
2486
+ arg, = val
2487
+
2488
+ case arg
2305
2489
  when Symbol then
2306
- result = s(:args)
2307
- result << val[0]
2490
+ result = s(:args, arg).line lexer.lineno
2308
2491
  when Sexp then
2309
- result = val[0]
2492
+ result = arg
2310
2493
  else
2311
2494
  debug20 32
2312
2495
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2319,7 +2502,7 @@ keyword_variable: kNIL { result = s(:nil) }
2319
2502
  if list.sexp_type == :args then
2320
2503
  result = list
2321
2504
  else
2322
- result = s(:args, list)
2505
+ result = s(:args, list).line list.line
2323
2506
  end
2324
2507
 
2325
2508
  result << item
@@ -2333,21 +2516,24 @@ keyword_variable: kNIL { result = s(:nil) }
2333
2516
  f_kw: f_label arg_value
2334
2517
  #endif
2335
2518
  {
2336
- # TODO: call_args
2337
- label, _ = val[0] # TODO: fix lineno?
2519
+ # TODO: new_kw_arg
2520
+ (label, line), arg = val
2521
+
2338
2522
  identifier = label.to_sym
2339
2523
  self.env[identifier] = :lvar
2340
2524
 
2341
- result = s(:array, s(:kwarg, identifier, val[1]))
2525
+ kwarg = s(:kwarg, identifier, arg).line line
2526
+ result = s(:array, kwarg).line line
2342
2527
  }
2343
2528
  #if V >= 21
2344
2529
  | f_label
2345
2530
  {
2346
- label, _ = val[0] # TODO: fix lineno?
2347
- identifier = label.to_sym
2348
- self.env[identifier] = :lvar
2531
+ (label, line), = val
2532
+
2533
+ id = label.to_sym
2534
+ self.env[id] = :lvar
2349
2535
 
2350
- result = s(:array, s(:kwarg, identifier))
2536
+ result = s(:array, s(:kwarg, id).line(line)).line line
2351
2537
  }
2352
2538
  #endif
2353
2539
 
@@ -2357,21 +2543,22 @@ keyword_variable: kNIL { result = s(:nil) }
2357
2543
  f_block_kw: f_label primary_value
2358
2544
  #endif
2359
2545
  {
2360
- # TODO: call_args
2361
- label, _ = val[0] # TODO: fix lineno?
2362
- identifier = label.to_sym
2363
- self.env[identifier] = :lvar
2546
+ # TODO: new_kw_arg
2547
+ (label, line), expr = val
2548
+ id = label.to_sym
2549
+ self.env[id] = :lvar
2364
2550
 
2365
- result = s(:array, s(:kwarg, identifier, val[1]))
2551
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2366
2552
  }
2367
2553
  #if V >= 21
2368
2554
  | f_label
2369
2555
  {
2370
- label, _ = val[0] # TODO: fix lineno?
2371
- identifier = label.to_sym
2372
- self.env[identifier] = :lvar
2556
+ # TODO: new_kw_arg
2557
+ (label, line), = val
2558
+ id = label.to_sym
2559
+ self.env[id] = :lvar
2373
2560
 
2374
- result = s(:array, s(:kwarg, identifier))
2561
+ result = s(:array, s(:kwarg, id).line(line)).line line
2375
2562
  }
2376
2563
  #endif
2377
2564
 
@@ -2427,17 +2614,20 @@ keyword_variable: kNIL { result = s(:nil) }
2427
2614
 
2428
2615
  f_block_optarg: f_block_opt
2429
2616
  {
2430
- result = s(:block, val[0])
2617
+ optblk, = val
2618
+ result = s(:block, optblk).line optblk.line
2431
2619
  }
2432
2620
  | f_block_optarg tCOMMA f_block_opt
2433
2621
  {
2434
- result = val[0]
2435
- result << val[2]
2622
+ optarg, _, optblk = val
2623
+ result = optarg
2624
+ result << optblk
2436
2625
  }
2437
2626
 
2438
2627
  f_optarg: f_opt
2439
2628
  {
2440
- result = s(:block, val[0])
2629
+ opt, = val
2630
+ result = s(:block, opt).line opt.line
2441
2631
  }
2442
2632
  | f_optarg tCOMMA f_opt
2443
2633
  {
@@ -2482,7 +2672,7 @@ keyword_variable: kNIL { result = s(:nil) }
2482
2672
  singleton: var_ref
2483
2673
  | tLPAREN2
2484
2674
  {
2485
- lexer.lex_state = :expr_beg
2675
+ lexer.lex_state = EXPR_BEG
2486
2676
  }
2487
2677
  expr rparen
2488
2678
  {
@@ -2491,14 +2681,11 @@ keyword_variable: kNIL { result = s(:nil) }
2491
2681
  result.sexp_type == :lit
2492
2682
  }
2493
2683
 
2494
- assoc_list: none # [!nil]
2495
- {
2496
- result = s(:array)
2497
- }
2498
- | assocs trailer # [!nil]
2684
+ assoc_list: none
2499
2685
  {
2500
- result = val[0]
2686
+ result = s(:array).line lexer.lineno
2501
2687
  }
2688
+ | assocs trailer
2502
2689
 
2503
2690
  assocs: assoc
2504
2691
  | assocs tCOMMA assoc
@@ -2512,24 +2699,29 @@ keyword_variable: kNIL { result = s(:nil) }
2512
2699
 
2513
2700
  assoc: arg_value tASSOC arg_value
2514
2701
  {
2515
- result = s(:array, val[0], val[2])
2702
+ v1, _, v2 = val
2703
+ result = s(:array, v1, v2).line v1.line
2516
2704
  }
2517
2705
  | tLABEL arg_value
2518
2706
  {
2519
- (label, _), arg = val
2520
- result = s(:array, s(:lit, label.to_sym), arg)
2707
+ (label, line), arg = val
2708
+
2709
+ lit = s(:lit, label.to_sym).line line
2710
+ result = s(:array, lit, arg).line line
2521
2711
  }
2522
2712
  #if V >= 22
2523
2713
  | tSTRING_BEG string_contents tLABEL_END arg_value
2524
2714
  {
2525
2715
  _, sym, _, value = val
2526
2716
  sym.sexp_type = :dsym
2527
- result = s(:array, sym, value)
2717
+ result = s(:array, sym, value).line sym.line
2528
2718
  }
2529
2719
  #endif
2530
2720
  | tDSTAR arg_value
2531
2721
  {
2532
- result = s(:array, s(:kwsplat, val[1]))
2722
+ _, arg = val
2723
+ line = arg.line
2724
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2533
2725
  }
2534
2726
 
2535
2727
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2563,6 +2755,7 @@ end
2563
2755
 
2564
2756
  require "ruby_lexer"
2565
2757
  require "ruby_parser_extras"
2758
+ include RubyLexer::State::Values
2566
2759
 
2567
2760
  # :stopdoc:
2568
2761