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