ruby_parser 3.13.1 → 3.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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