ruby_parser 3.17.0 → 3.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. metadata.gz.sig +0 -0
data/lib/ruby30_parser.y CHANGED
@@ -18,11 +18,11 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
- tLONELY
25
- tBDOT2 tBDOT3
24
+ tLONELY
25
+ tBDOT2 tBDOT3
26
26
 
27
27
  preclow
28
28
  nonassoc tLOWEST
@@ -80,7 +80,7 @@ rule
80
80
  | klBEGIN
81
81
  {
82
82
  if (self.in_def || self.in_single > 0) then
83
- debug20 1
83
+ debug 1
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -135,7 +135,7 @@ rule
135
135
  | error stmt
136
136
  {
137
137
  result = val[1]
138
- debug20 2, val, result
138
+ debug 2
139
139
  }
140
140
 
141
141
  stmt_or_begin: stmt
@@ -143,6 +143,10 @@ rule
143
143
  {
144
144
  yyerror "BEGIN is permitted only at toplevel"
145
145
  }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
146
150
 
147
151
  stmt: kALIAS fitem
148
152
  {
@@ -155,12 +159,12 @@ rule
155
159
  }
156
160
  | kALIAS tGVAR tGVAR
157
161
  {
158
- (_, line), lhs, rhs = val
162
+ (_, line), (lhs, _), (rhs, _) = val
159
163
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
164
  }
161
165
  | kALIAS tGVAR tBACK_REF
162
166
  {
163
- (_, line), lhs, rhs = val
167
+ (_, line), (lhs, _), (rhs, _) = val
164
168
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
169
  }
166
170
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +207,7 @@ rule
203
207
  (_, line), _, stmt, _ = val
204
208
 
205
209
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
210
+ debug 3
207
211
  yyerror "END in method; use at_exit"
208
212
  end
209
213
 
@@ -219,6 +223,15 @@ rule
219
223
  lhs, _, rhs = val
220
224
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
221
225
  }
226
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
227
+ {
228
+ # unwraps s(:to_ary, rhs)
229
+ lhs, _, (_, rhs), _, resbody = val
230
+
231
+ resbody = new_resbody s(:array).line(resbody.line), resbody
232
+
233
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
234
+ }
222
235
  | mlhs tEQL mrhs_arg
223
236
  {
224
237
  result = new_masgn val[0], val[2]
@@ -243,32 +256,31 @@ rule
243
256
  }
244
257
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
258
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- result.line = val[0].line
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
252
264
  }
253
265
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
266
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- result.line = val[0].line
267
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
268
+
269
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
270
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
271
+ result.line prim.line
260
272
  }
261
273
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
274
  {
263
- lhs1, _, lhs2, op, rhs = val
275
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
276
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
277
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
278
  }
267
279
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
280
  {
269
- lhs1, _, lhs2, op, rhs = val
281
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
282
 
271
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
283
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
272
284
  }
273
285
  | backref tOP_ASGN command_rhs
274
286
  {
@@ -314,7 +326,86 @@ rule
314
326
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
327
  # REFACTOR: call_uni_op -- see parse26.y
316
328
  }
329
+ | arg tASSOC
330
+ {
331
+ # value_expr($1);
332
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
333
+ self.lexer.command_start = false
334
+ result = self.in_kwarg
335
+ self.in_kwarg = true
336
+ self.env.extend
337
+ }
338
+ p_expr
339
+ {
340
+ lhs, _, in_kwarg, rhs = val
341
+
342
+ self.env.unextend
343
+ self.in_kwarg = in_kwarg
344
+
345
+ rhs = new_in rhs, nil, nil, rhs.line
346
+ result = new_case lhs, rhs, rhs.line
347
+ }
317
348
  | arg
349
+ kIN
350
+ {
351
+ # TODO? value_expr($1);
352
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
353
+ self.lexer.command_start = false
354
+ result = self.in_kwarg
355
+ self.in_kwarg = true
356
+ self.env.extend
357
+ }
358
+ p_expr
359
+ {
360
+ self.env.unextend
361
+
362
+ expr, _, old_kwarg, pat = val
363
+
364
+ expr = value_expr expr
365
+
366
+ self.in_kwarg = old_kwarg
367
+ pat_in = new_in pat, nil, nil, expr.line
368
+ result = new_case expr, pat_in, expr.line
369
+ }
370
+ | arg =tLBRACE_ARG
371
+
372
+ def_name: fname
373
+ {
374
+ # TODO: numparam_name(p, fname);
375
+
376
+ (id, line), = val
377
+ old_in_def = self.in_def
378
+
379
+ self.in_def = true # group = local_push
380
+ self.env.extend
381
+ lexer.cmdarg.push false
382
+ lexer.cond.push false
383
+
384
+ result = [id.to_sym, line, old_in_def]
385
+ }
386
+ defn_head: k_def def_name
387
+ {
388
+ _, name = val
389
+ result = name
390
+ }
391
+ defs_head: k_def singleton dot_or_colon
392
+ {
393
+ lexer.lex_state = EXPR_FNAME
394
+ }
395
+ def_name
396
+ {
397
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
398
+ self.in_single += 1 # TODO: remove?
399
+
400
+ # self.in_def = true # local_push
401
+ # self.env.extend
402
+ # lexer.cmdarg.push false
403
+ # lexer.cond.push false
404
+
405
+ _, recv, _, _, name = val
406
+
407
+ result = [recv, name]
408
+ }
318
409
 
319
410
  expr_value: expr
320
411
  {
@@ -339,7 +430,7 @@ rule
339
430
  block_command: block_call
340
431
  | block_call call_op2 operation2 command_args
341
432
  {
342
- blk, _, msg, args = val
433
+ blk, _, (msg, _line), args = val
343
434
  result = new_call(blk, msg.to_sym, args).line blk.line
344
435
  }
345
436
 
@@ -353,15 +444,15 @@ rule
353
444
  _, line, body, _ = val
354
445
 
355
446
  result = body
356
- result.line = line
447
+ result.line line
357
448
 
358
449
  # self.env.unextend
359
450
  }
360
451
 
361
452
  fcall: operation
362
453
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
454
+ (msg, line), = val
455
+ result = new_call(nil, msg.to_sym).line line
365
456
  }
366
457
 
367
458
  command: fcall command_args =tLOWEST
@@ -384,12 +475,14 @@ rule
384
475
  }
385
476
  | primary_value call_op operation2 command_args =tLOWEST
386
477
  {
387
- lhs, callop, op, args = val
478
+ lhs, callop, (op, _), args = val
479
+
388
480
  result = new_call lhs, op.to_sym, args, callop
481
+ result.line lhs.line
389
482
  }
390
483
  | primary_value call_op operation2 command_args cmd_brace_block
391
484
  {
392
- recv, _, msg, args, block = val
485
+ recv, _, (msg, _line), args, block = val
393
486
  call = new_call recv, msg.to_sym, args, val[1]
394
487
 
395
488
  block_dup_check call, block
@@ -399,11 +492,14 @@ rule
399
492
  }
400
493
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
494
  {
402
- result = new_call val[0], val[2].to_sym, val[3]
495
+ lhs, _, (id, line), args = val
496
+
497
+ result = new_call lhs, id.to_sym, args
498
+ result.line line
403
499
  }
404
500
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
501
  {
406
- recv, _, msg, args, block = val
502
+ recv, _, (msg, _line), args, block = val
407
503
  call = new_call recv, msg.to_sym, args
408
504
 
409
505
  block_dup_check call, block
@@ -561,25 +657,29 @@ rule
561
657
  }
562
658
  | primary_value call_op tIDENTIFIER
563
659
  {
564
- result = new_attrasgn val[0], val[2], val[1]
660
+ lhs, call_op, (id, _line) = val
661
+
662
+ result = new_attrasgn lhs, id, call_op
565
663
  }
566
664
  | primary_value tCOLON2 tIDENTIFIER
567
665
  {
568
- recv, _, id = val
666
+ recv, _, (id, _line) = val
569
667
  result = new_attrasgn recv, id
570
668
  }
571
669
  | primary_value call_op tCONSTANT
572
670
  {
573
- result = new_attrasgn val[0], val[2], val[1]
671
+ lhs, call_op, (id, _line) = val
672
+
673
+ result = new_attrasgn lhs, id, call_op
574
674
  }
575
675
  | primary_value tCOLON2 tCONSTANT
576
676
  {
577
677
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
678
+ debug 4
579
679
  yyerror "dynamic constant assignment"
580
680
  end
581
681
 
582
- expr, _, id = val
682
+ expr, _, (id, _line) = val
583
683
  l = expr.line
584
684
 
585
685
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +687,65 @@ rule
587
687
  | tCOLON3 tCONSTANT
588
688
  {
589
689
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
690
+ debug 5
591
691
  yyerror "dynamic constant assignment"
592
692
  end
593
693
 
594
- _, id = val
595
- l = lexer.lineno
694
+ _, (id, l) = val
596
695
 
597
696
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
697
  }
599
698
  | backref
600
699
  {
601
- self.backref_assign_error val[0]
700
+ ref, = val
701
+
702
+ self.backref_assign_error ref
602
703
  }
603
704
 
604
705
  lhs: user_variable
605
706
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
707
+ var, = val
708
+
709
+ result = self.assignable var
609
710
  }
610
711
  | keyword_variable
611
712
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
713
+ var, = val
714
+
715
+ result = self.assignable var
716
+
717
+ debug 6
616
718
  }
617
719
  | primary_value tLBRACK2 opt_call_args rbracket
618
720
  {
619
721
  lhs, _, args, _ = val
722
+
620
723
  result = self.aryset lhs, args
621
724
  }
622
725
  | primary_value call_op tIDENTIFIER # REFACTOR
623
726
  {
624
- lhs, op, id = val
727
+ lhs, op, (id, _line) = val
728
+
625
729
  result = new_attrasgn lhs, id, op
626
730
  }
627
731
  | primary_value tCOLON2 tIDENTIFIER
628
732
  {
629
- lhs, _, id = val
733
+ lhs, _, (id, _line) = val
734
+
630
735
  result = new_attrasgn lhs, id
631
736
  }
632
737
  | primary_value call_op tCONSTANT # REFACTOR?
633
738
  {
634
- result = new_attrasgn val[0], val[2], val[1]
739
+ lhs, call_op, (id, _line) = val
740
+
741
+ result = new_attrasgn lhs, id, call_op
635
742
  }
636
743
  | primary_value tCOLON2 tCONSTANT
637
744
  {
638
- expr, _, id = val
745
+ expr, _, (id, _line) = val
639
746
 
640
747
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
748
+ debug 7
642
749
  yyerror "dynamic constant assignment"
643
750
  end
644
751
 
@@ -647,14 +754,13 @@ rule
647
754
  }
648
755
  | tCOLON3 tCONSTANT
649
756
  {
650
- _, id = val
757
+ _, (id, l) = val
651
758
 
652
759
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
760
+ debug 8
654
761
  yyerror "dynamic constant assignment"
655
762
  end
656
763
 
657
- l = lexer.lineno
658
764
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
765
  }
660
766
  | backref
@@ -670,16 +776,16 @@ rule
670
776
 
671
777
  cpath: tCOLON3 cname
672
778
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
779
+ result = wrap :colon3, val[1]
675
780
  }
676
781
  | cname
677
782
  {
678
- result = val[0].to_sym
783
+ (id, line), = val
784
+ result = [id.to_sym, line] # TODO: sexp?
679
785
  }
680
786
  | primary_value tCOLON2 cname
681
787
  {
682
- pval, _, name = val
788
+ pval, _, (name, _line) = val
683
789
 
684
790
  result = s(:colon2, pval, name.to_sym)
685
791
  result.line pval.line
@@ -689,24 +795,15 @@ rule
689
795
  | op
690
796
  {
691
797
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
798
  }
694
799
 
695
800
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
801
 
704
- fitem: fsym
802
+ fitem: fname
705
803
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
804
+ result = wrap :lit, val[0]
708
805
  }
709
- | dsym
806
+ | symbol
710
807
 
711
808
  undef_list: fitem
712
809
  {
@@ -727,8 +824,6 @@ rule
727
824
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
825
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
826
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
827
 
733
828
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
829
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,26 +857,22 @@ rule
762
857
  }
763
858
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
859
  {
765
- lhs, _, id, op, rhs = val
860
+ lhs, _, (id, _line), (op, _), rhs = val
766
861
 
767
862
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
863
  }
769
864
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
865
  {
771
- lhs1, _, lhs2, op, rhs = val
866
+ lhs1, _, (lhs2, _line), op, rhs = val
772
867
 
773
868
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
869
  result = new_const_op_asgn [lhs, op, rhs]
775
870
  }
776
- | tCOLON3 tCONSTANT
777
- {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
871
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
781
872
  {
782
- _, lhs, line, op, rhs = val
873
+ _, lhs, op, rhs = val
783
874
 
784
- lhs = s(:colon3, lhs.to_sym).line line
875
+ lhs = wrap :colon3, lhs
785
876
  result = new_const_op_asgn [lhs, op, rhs]
786
877
  }
787
878
  | backref tOP_ASGN arg_rhs
@@ -793,7 +884,7 @@ rule
793
884
  | arg tDOT2 arg
794
885
  {
795
886
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
887
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
888
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
889
  else
799
890
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +893,7 @@ rule
802
893
  | arg tDOT3 arg
803
894
  {
804
895
  v1, v2 = val[0], val[2]
805
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
896
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
806
897
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
898
  else
808
899
  result = s(:dot3, v1, v2).line v1.line
@@ -864,8 +955,9 @@ rule
864
955
  }
865
956
  | tUMINUS_NUM simple_numeric tPOW arg
866
957
  {
867
- lit = s(:lit, val[1]).line lexer.lineno
868
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
958
+ _, num, _, arg = val
959
+ lit = wrap :lit, num
960
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
869
961
 
870
962
  }
871
963
  | tUPLUS arg
@@ -955,6 +1047,22 @@ rule
955
1047
  c, _, t, _, _, f = val
956
1048
  result = s(:if, c, t, f).line c.line
957
1049
  }
1050
+ | defn_head f_opt_paren_args tEQL arg
1051
+ {
1052
+ result = new_endless_defn val
1053
+ }
1054
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1055
+ {
1056
+ result = new_endless_defn val
1057
+ }
1058
+ | defs_head f_opt_paren_args tEQL arg
1059
+ {
1060
+ result = new_endless_defs val
1061
+ }
1062
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1063
+ {
1064
+ result = new_endless_defs val
1065
+ }
958
1066
  | primary
959
1067
 
960
1068
  relop: tGT
@@ -964,12 +1072,12 @@ rule
964
1072
 
965
1073
  rel_expr: arg relop arg =tGT
966
1074
  {
967
- lhs, op, rhs = val
1075
+ lhs, (op, _), rhs = val
968
1076
  result = new_call lhs, op.to_sym, argl(rhs)
969
1077
  }
970
1078
  | rel_expr relop arg =tGT
971
1079
  {
972
- lhs, op, rhs = val
1080
+ lhs, (op, _), rhs = val
973
1081
  warn "comparison '%s' after comparison", op
974
1082
  result = new_call lhs, op.to_sym, argl(rhs)
975
1083
  }
@@ -1178,8 +1286,9 @@ rule
1178
1286
  | backref
1179
1287
  | tFID
1180
1288
  {
1181
- msg, = val
1289
+ (msg, line), = val
1182
1290
  result = new_call nil, msg.to_sym
1291
+ result.line line
1183
1292
  }
1184
1293
  | k_begin
1185
1294
  {
@@ -1221,15 +1330,13 @@ rule
1221
1330
  }
1222
1331
  | primary_value tCOLON2 tCONSTANT
1223
1332
  {
1224
- expr, _, id = val
1333
+ expr, _, (id, _line) = val
1225
1334
 
1226
1335
  result = s(:colon2, expr, id.to_sym).line expr.line
1227
1336
  }
1228
1337
  | tCOLON3 tCONSTANT
1229
1338
  {
1230
- _, id = val
1231
-
1232
- result = s(:colon3, id.to_sym).line lexer.lineno
1339
+ result = wrap :colon3, val[1]
1233
1340
  }
1234
1341
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1235
1342
  {
@@ -1253,15 +1360,21 @@ rule
1253
1360
  }
1254
1361
  | kYIELD tLPAREN2 call_args rparen
1255
1362
  {
1256
- result = new_yield val[2]
1363
+ (_, line), _, args, _ = val
1364
+
1365
+ result = new_yield(args).line line
1257
1366
  }
1258
1367
  | kYIELD tLPAREN2 rparen
1259
1368
  {
1260
- result = new_yield
1369
+ (_, line), _, _ = val
1370
+
1371
+ result = new_yield.line line
1261
1372
  }
1262
1373
  | kYIELD
1263
1374
  {
1264
- result = new_yield
1375
+ (_, line), = val
1376
+
1377
+ result = new_yield.line line
1265
1378
  }
1266
1379
  | kDEFINED opt_nl tLPAREN2 expr rparen
1267
1380
  {
@@ -1276,7 +1389,7 @@ rule
1276
1389
  }
1277
1390
  | kNOT tLPAREN2 rparen
1278
1391
  {
1279
- debug20 14, val, result
1392
+ debug 9
1280
1393
  }
1281
1394
  | fcall brace_block
1282
1395
  {
@@ -1294,9 +1407,10 @@ rule
1294
1407
  iter.insert 1, call # FIX
1295
1408
  result = iter
1296
1409
  }
1297
- | tLAMBDA lambda
1410
+ | lambda
1298
1411
  {
1299
- result = val[1] # TODO: fix lineno
1412
+ expr, = val
1413
+ result = expr
1300
1414
  }
1301
1415
  | k_if expr_value then compstmt if_tail k_end
1302
1416
  {
@@ -1328,6 +1442,12 @@ rule
1328
1442
  (_, line), _, body, _ = val
1329
1443
  result = new_case nil, body, line
1330
1444
  }
1445
+ | k_case expr_value opt_terms p_case_body k_end
1446
+ {
1447
+ (_, line), expr, _, body, _ = val
1448
+
1449
+ result = new_case expr, body, line
1450
+ }
1331
1451
  | k_for for_var kIN expr_value_do compstmt k_end
1332
1452
  {
1333
1453
  _, var, _, iter, body, _ = val
@@ -1339,7 +1459,6 @@ rule
1339
1459
  }
1340
1460
  cpath superclass
1341
1461
  {
1342
- self.comments.push self.lexer.comments
1343
1462
  if (self.in_def || self.in_single > 0) then
1344
1463
  yyerror "class definition in method body"
1345
1464
  end
@@ -1349,7 +1468,7 @@ rule
1349
1468
  {
1350
1469
  result = new_class val
1351
1470
  self.env.unextend
1352
- self.lexer.comments # we don't care about comments in the body
1471
+ self.lexer.ignore_body_comments
1353
1472
  }
1354
1473
  | k_class tLSHFT
1355
1474
  {
@@ -1370,7 +1489,7 @@ rule
1370
1489
  {
1371
1490
  result = new_sclass val
1372
1491
  self.env.unextend
1373
- self.lexer.comments # we don't care about comments in the body
1492
+ self.lexer.ignore_body_comments
1374
1493
  }
1375
1494
  | k_module
1376
1495
  {
@@ -1378,7 +1497,6 @@ rule
1378
1497
  }
1379
1498
  cpath
1380
1499
  {
1381
- self.comments.push self.lexer.comments
1382
1500
  yyerror "module definition in method body" if
1383
1501
  self.in_def or self.in_single > 0
1384
1502
 
@@ -1388,55 +1506,40 @@ rule
1388
1506
  {
1389
1507
  result = new_module val
1390
1508
  self.env.unextend
1391
- self.lexer.comments # we don't care about comments in the body
1392
- }
1393
- | k_def fname
1394
- {
1395
- result = self.in_def
1396
-
1397
- self.in_def = true # group = local_push
1398
- self.env.extend
1399
- lexer.cmdarg.push false
1400
- lexer.cond.push false
1401
-
1402
- self.comments.push self.lexer.comments
1509
+ self.lexer.ignore_body_comments
1403
1510
  }
1404
- f_arglist bodystmt { result = lexer.lineno } k_end
1511
+ | defn_head f_arglist bodystmt k_end
1405
1512
  {
1406
- in_def = val[2]
1513
+ # [ [:f, 1, false], s(:args)...]
1514
+ # =>
1515
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1516
+ val.insert 1, val.first.pop
1517
+ val.insert 0, [:k_def, 666]
1407
1518
 
1408
- result = new_defn val
1519
+ result, in_def = new_defn val
1409
1520
 
1410
1521
  lexer.cond.pop # group = local_pop
1411
1522
  lexer.cmdarg.pop
1412
1523
  self.env.unextend
1413
1524
  self.in_def = in_def
1414
1525
 
1415
- self.lexer.comments # we don't care about comments in the body
1416
- }
1417
- | k_def singleton dot_or_colon
1418
- {
1419
- lexer.lex_state = EXPR_FNAME
1526
+ self.lexer.ignore_body_comments
1420
1527
  }
1421
- fname
1528
+ | defs_head f_arglist bodystmt k_end
1422
1529
  {
1423
- result = [self.in_def, lexer.lineno]
1424
-
1425
- self.in_single += 1 # TODO: remove?
1530
+ # [ [recv, [:name, 1, false]], s(:args...]
1531
+ # =>
1532
+ # [ recv, [:name, 1, false], s(:args...]
1533
+ # =>
1534
+ # [ recv, [:name, 1], false, s(:args...]
1535
+ # =>
1536
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1426
1537
 
1427
- self.in_def = true # local_push
1428
- self.env.extend
1429
- lexer.cmdarg.push false
1430
- lexer.cond.push false
1431
-
1432
- lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1433
- self.comments.push self.lexer.comments
1434
- }
1435
- f_arglist bodystmt k_end
1436
- {
1437
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1538
+ val.prepend(*val.shift)
1539
+ val.insert 2, val[1].pop
1540
+ val.insert 0, [:k_def, 666]
1438
1541
 
1439
- result = new_defs val
1542
+ result, in_def = new_defs val
1440
1543
 
1441
1544
  lexer.cond.pop # group = local_pop
1442
1545
  lexer.cmdarg.pop
@@ -1447,7 +1550,7 @@ rule
1447
1550
 
1448
1551
  # TODO: restore cur_arg ? what's cur_arg?
1449
1552
 
1450
- self.lexer.comments # we don't care about comments in the body
1553
+ self.lexer.ignore_body_comments
1451
1554
  }
1452
1555
  | kBREAK
1453
1556
  {
@@ -1484,8 +1587,17 @@ rule
1484
1587
  k_case: kCASE
1485
1588
  k_for: kFOR
1486
1589
  k_class: kCLASS
1590
+ {
1591
+ self.comments.push self.lexer.comments
1592
+ }
1487
1593
  k_module: kMODULE
1594
+ {
1595
+ self.comments.push self.lexer.comments
1596
+ }
1488
1597
  k_def: kDEF
1598
+ {
1599
+ self.comments.push self.lexer.comments
1600
+ }
1489
1601
  k_do: kDO
1490
1602
  k_do_block: kDO_BLOCK
1491
1603
  k_rescue: kRESCUE
@@ -1546,52 +1658,47 @@ rule
1546
1658
 
1547
1659
  result = block_var args
1548
1660
  }
1549
- | f_marg_list tCOMMA tSTAR f_norm_arg
1661
+ | f_marg_list tCOMMA f_rest_marg
1550
1662
  {
1551
- args, _, _, splat = val
1663
+ args, _, rest = val
1552
1664
 
1553
- result = block_var args, "*#{splat}".to_sym
1665
+ result = block_var args, rest
1554
1666
  }
1555
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1667
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1556
1668
  {
1557
- args, _, _, splat, _, args2 = val
1669
+ lhs, _, splat, _, rhs = val
1558
1670
 
1559
- result = block_var args, "*#{splat}".to_sym, args2
1671
+ result = block_var lhs, splat, rhs
1560
1672
  }
1561
- | f_marg_list tCOMMA tSTAR
1673
+ | f_rest_marg
1562
1674
  {
1563
- args, _, _ = val
1675
+ rest, = val
1564
1676
 
1565
- result = block_var args, :*
1677
+ result = block_var rest
1566
1678
  }
1567
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1679
+ | f_rest_marg tCOMMA f_marg_list
1568
1680
  {
1569
- args, _, _, _, args2 = val
1681
+ splat, _, rest = val
1570
1682
 
1571
- result = block_var args, :*, args2
1683
+ result = block_var splat, rest
1572
1684
  }
1573
- | tSTAR f_norm_arg
1574
- {
1575
- _, splat = val
1576
1685
 
1577
- result = block_var :"*#{splat}"
1578
- }
1579
- | tSTAR f_norm_arg tCOMMA f_marg_list
1686
+ f_rest_marg: tSTAR f_norm_arg
1580
1687
  {
1581
- _, splat, _, args = val
1688
+ _, (id, line) = val
1582
1689
 
1583
- result = block_var :"*#{splat}", args
1690
+ result = args ["*#{id}".to_sym]
1691
+ result.line line
1584
1692
  }
1585
1693
  | tSTAR
1586
1694
  {
1587
- result = block_var :*
1695
+ result = args [:*]
1696
+ result.line lexer.lineno # FIX: tSTAR -> line
1588
1697
  }
1589
- | tSTAR tCOMMA f_marg_list
1590
- {
1591
- _, _, args = val
1592
1698
 
1593
- result = block_var :*, args
1594
- }
1699
+ f_any_kwrest: f_kwrest
1700
+ | f_no_kwarg
1701
+
1595
1702
 
1596
1703
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1597
1704
  {
@@ -1601,14 +1708,14 @@ rule
1601
1708
  {
1602
1709
  result = call_args val
1603
1710
  }
1604
- | f_kwrest opt_f_block_arg
1711
+ | f_any_kwrest opt_f_block_arg
1605
1712
  {
1606
1713
  result = call_args val
1607
1714
  }
1608
1715
  | f_block_arg
1609
1716
  {
1610
- line = lexer.lineno
1611
- result = call_args val # TODO: push line down
1717
+ (id, line), = val
1718
+ result = call_args [id]
1612
1719
  result.line line
1613
1720
  }
1614
1721
 
@@ -1618,6 +1725,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1618
1725
  }
1619
1726
  | none
1620
1727
 
1728
+ excessed_comma: tCOMMA
1729
+ {
1730
+ result = s(:WTF_COMMA!)
1731
+ }
1732
+
1621
1733
  block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1622
1734
  {
1623
1735
  result = args val
@@ -1638,9 +1750,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1638
1750
  {
1639
1751
  result = args val
1640
1752
  }
1641
- | f_arg tCOMMA
1753
+ | f_arg excessed_comma
1642
1754
  {
1643
- result = args(val) << nil
1755
+ arg, _ = val
1756
+ result = arg << nil
1644
1757
  }
1645
1758
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1646
1759
  {
@@ -1717,13 +1830,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1830
 
1718
1831
  bvar: tIDENTIFIER
1719
1832
  {
1720
- id, = val
1721
- line = lexer.lineno
1722
- result = s(:shadow, id.to_sym).line line
1833
+ result = wrap :shadow, val[0]
1723
1834
  }
1724
1835
  | f_bad_arg
1725
1836
 
1726
- lambda: {
1837
+ lambda: tLAMBDA
1838
+ {
1727
1839
  self.env.extend :dynamic
1728
1840
  result = [lexer.lineno, lexer.lpar_beg]
1729
1841
  lexer.paren_nest += 1
@@ -1735,14 +1847,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1735
1847
  }
1736
1848
  lambda_body
1737
1849
  {
1738
- (line, lpar), args, _cmdarg, body = val
1850
+ _, (line, lpar), args, _cmdarg, body = val
1739
1851
  lexer.lpar_beg = lpar
1740
1852
 
1741
1853
  lexer.cmdarg.pop
1742
1854
 
1743
1855
  call = s(:lambda).line line
1744
1856
  result = new_iter call, args, body
1745
- result.line = line
1857
+ result.line line
1746
1858
  self.env.unextend # TODO: dynapush & dynapop
1747
1859
  }
1748
1860
 
@@ -1777,23 +1889,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1777
1889
  ## if (nd_type($1) == NODE_YIELD) {
1778
1890
  ## compile_error(PARSER_ARG "block given to yield");
1779
1891
 
1780
- syntax_error "Both block arg and actual block given." if
1781
- val[0].block_pass?
1892
+ cmd, blk = val
1782
1893
 
1783
- val = invert_block_call val if inverted? val
1894
+ syntax_error "Both block arg and actual block given." if
1895
+ cmd.block_pass?
1784
1896
 
1785
- cmd, blk = val
1897
+ if inverted? val then
1898
+ val = invert_block_call val
1899
+ cmd, blk = val
1900
+ end
1786
1901
 
1787
1902
  result = blk
1788
1903
  result.insert 1, cmd
1789
1904
  }
1790
1905
  | block_call call_op2 operation2 opt_paren_args
1791
1906
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1907
+ lhs, _, (id, _line), args = val
1908
+
1909
+ result = new_call lhs, id.to_sym, args
1793
1910
  }
1794
1911
  | block_call call_op2 operation2 opt_paren_args brace_block
1795
1912
  {
1796
- iter1, _, name, args, iter2 = val
1913
+ iter1, _, (name, _line), args, iter2 = val
1797
1914
 
1798
1915
  call = new_call iter1, name.to_sym, args
1799
1916
  iter2.insert 1, call
@@ -1802,7 +1919,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1919
  }
1803
1920
  | block_call call_op2 operation2 command_args do_block
1804
1921
  {
1805
- iter1, _, name, args, iter2 = val
1922
+ iter1, _, (name, _line), args, iter2 = val
1806
1923
 
1807
1924
  call = new_call iter1, name.to_sym, args
1808
1925
  iter2.insert 1, call
@@ -1810,28 +1927,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
1927
  result = iter2
1811
1928
  }
1812
1929
 
1813
- method_call: fcall
1930
+ method_call: fcall paren_args
1814
1931
  {
1815
- result = self.lexer.lineno
1816
- }
1817
- paren_args
1818
- {
1819
- call, lineno, args = val
1932
+ call, args = val
1820
1933
 
1821
1934
  result = call.concat args.sexp_body if args
1822
- result.line lineno
1823
1935
  }
1824
1936
  | primary_value call_op operation2 opt_paren_args
1825
1937
  {
1826
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1938
+ recv, call_op, (op, _line), args = val
1939
+
1940
+ result = new_call recv, op.to_sym, args, call_op
1827
1941
  }
1828
1942
  | primary_value tCOLON2 operation2 paren_args
1829
1943
  {
1830
- result = new_call val[0], val[2].to_sym, val[3]
1944
+ recv, _, (op, _line), args = val
1945
+
1946
+ result = new_call recv, op.to_sym, args
1831
1947
  }
1832
1948
  | primary_value tCOLON2 operation3
1833
1949
  {
1834
- result = new_call val[0], val[2].to_sym
1950
+ lhs, _, (id, _line) = val
1951
+
1952
+ result = new_call lhs, id.to_sym
1835
1953
  }
1836
1954
  | primary_value call_op paren_args
1837
1955
  {
@@ -1864,7 +1982,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
1982
  _, line, body, _ = val
1865
1983
 
1866
1984
  result = body
1867
- result.line = line
1985
+ result.line line
1868
1986
 
1869
1987
  self.env.unextend
1870
1988
  }
@@ -1878,7 +1996,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1878
1996
  _, line, body, _ = val
1879
1997
 
1880
1998
  result = body
1881
- result.line = line
1999
+ result.line line
1882
2000
 
1883
2001
  self.env.unextend
1884
2002
  }
@@ -1907,102 +2025,635 @@ opt_block_args_tail: tCOMMA block_args_tail
1907
2025
  self.env.unextend
1908
2026
  }
1909
2027
 
2028
+ case_args: arg_value
2029
+ {
2030
+ arg, = val
2031
+
2032
+ result = s(:array, arg).line arg.line
2033
+ }
2034
+ | tSTAR arg_value
2035
+ {
2036
+ _, arg = val
2037
+
2038
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2039
+ }
2040
+ | case_args tCOMMA arg_value
2041
+ {
2042
+ args, _, id = val
2043
+
2044
+ result = self.list_append args, id
2045
+ }
2046
+ | case_args tCOMMA tSTAR arg_value
2047
+ {
2048
+ args, _, _, id = val
2049
+
2050
+ result = self.list_append args, s(:splat, id).line(id.line)
2051
+ }
2052
+
1910
2053
  case_body: k_when
1911
2054
  {
1912
2055
  result = self.lexer.lineno
1913
2056
  }
1914
- args then compstmt cases
2057
+ case_args then compstmt cases
1915
2058
  {
1916
2059
  result = new_when(val[2], val[4])
1917
- result.line = val[1]
2060
+ result.line val[1]
1918
2061
  result << val[5] if val[5]
1919
2062
  }
1920
2063
 
1921
2064
  cases: opt_else | case_body
2065
+ ######################################################################
1922
2066
 
1923
- opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2067
+ p_case_body: kIN
1924
2068
  {
1925
- (_, line), klasses, var, _, body, rest = val
1926
-
1927
- klasses ||= s(:array)
1928
- klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1929
- klasses.line line
1930
-
1931
- result = new_resbody(klasses, body)
1932
- result << rest if rest # UGH, rewritten above
2069
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2070
+ self.lexer.command_start = false
2071
+ result = self.in_kwarg
2072
+ self.in_kwarg = true
2073
+ push_pvtbl
2074
+ push_pktbl
1933
2075
  }
1934
- |
2076
+ p_top_expr then
1935
2077
  {
1936
- result = nil
2078
+ pop_pktbl
2079
+ pop_pvtbl
2080
+ old_kwargs = _values[-3]
2081
+ self.in_kwarg = old_kwargs
1937
2082
  }
1938
-
1939
- exc_list: arg_value
2083
+ compstmt
2084
+ p_cases
1940
2085
  {
1941
- arg, = val
1942
- result = s(:array, arg).line arg.line
2086
+ (_, line), _, pat, _, _, body, cases = val
2087
+
2088
+ result = new_in pat, body, cases, line
1943
2089
  }
1944
- | mrhs
1945
- | none
1946
2090
 
1947
- exc_var: tASSOC lhs
2091
+ p_cases: opt_else
2092
+ | p_case_body
2093
+
2094
+ p_top_expr: p_top_expr_body
2095
+ | p_top_expr_body kIF_MOD expr_value
1948
2096
  {
1949
- result = val[1]
1950
- }
1951
- | none
2097
+ body, _, cond = val
2098
+ body = remove_begin body
1952
2099
 
1953
- opt_ensure: k_ensure compstmt
2100
+ result = s(:if, cond, body, nil).line body.line
2101
+ }
2102
+ | p_top_expr_body kUNLESS_MOD expr_value
1954
2103
  {
1955
- (_, line), body = val
2104
+ body, _, cond = val
2105
+ body = remove_begin body
1956
2106
 
1957
- result = body || s(:nil).line(line)
2107
+ result = s(:if, cond, nil, body).line body.line
1958
2108
  }
1959
- | none
1960
2109
 
1961
- literal: numeric
2110
+ p_top_expr_body: p_expr
2111
+ | p_expr tCOMMA
1962
2112
  {
1963
- line = lexer.lineno
1964
- result = s(:lit, val[0])
1965
- result.line = line
2113
+ expr, _ = val
2114
+
2115
+ tail = new_array_pattern_tail nil, true, nil, nil
2116
+ result = new_array_pattern nil, expr, tail, expr.line
1966
2117
  }
1967
- | symbol
2118
+ | p_expr tCOMMA p_args
1968
2119
  {
1969
- line = lexer.lineno
1970
- result = s(:lit, val[0])
1971
- result.line = line
1972
- }
1973
- | dsym
2120
+ expr, _, args = val
1974
2121
 
1975
- strings: string
1976
- {
1977
- str, = val
1978
- str = s(:dstr, str.value) if str.sexp_type == :evstr
1979
- result = str
2122
+ result = new_array_pattern nil, expr, args, expr.line
1980
2123
  }
2124
+ | p_find
2125
+ {
2126
+ find, = val
1981
2127
 
1982
- string: tCHAR
2128
+ result = new_find_pattern nil, find
2129
+ }
2130
+ | p_args_tail
1983
2131
  {
1984
- debug20 23, val, result
2132
+ args, = val
2133
+ result = new_array_pattern nil, nil, args, args.line
1985
2134
  }
1986
- | string1
1987
- | string string1
2135
+ | p_kwargs
1988
2136
  {
1989
- result = self.literal_concat val[0], val[1]
2137
+ kwargs, = val
2138
+ result = new_hash_pattern nil, kwargs, kwargs.line
1990
2139
  }
1991
2140
 
1992
- string1: tSTRING_BEG string_contents tSTRING_END
2141
+ p_expr: p_as
2142
+
2143
+ p_as: p_expr tASSOC p_variable
1993
2144
  {
1994
- _, str, (_, func) = val
2145
+ # NODE *n = NEW_LIST($1, &@$);
2146
+ # n = list_append(p, n, $3);
2147
+ # $$ = new_hash(p, n, &@$);
1995
2148
 
1996
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2149
+ expr, _, var = val
1997
2150
 
1998
- result = str
2151
+ id = var.last
2152
+
2153
+ self.env[id] = :lvar # HACK: need to extend env
2154
+ lhs = s(:lasgn, id).line var.line
2155
+
2156
+ result = new_assign lhs, expr
1999
2157
  }
2000
- | tSTRING
2158
+ | p_alt
2159
+
2160
+ p_alt: p_alt tPIPE p_expr_basic
2001
2161
  {
2002
- result = new_string val
2162
+ lhs, _, rhs = val
2163
+
2164
+ result = s(:or, lhs, rhs).line lhs.line
2003
2165
  }
2166
+ | p_expr_basic
2004
2167
 
2005
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
2168
+ p_lparen: tLPAREN2 { push_pktbl }
2169
+ p_lbracket: tLBRACK2 { push_pktbl }
2170
+
2171
+ p_expr_basic: p_value
2172
+ | p_const p_lparen p_args tRPAREN
2173
+ {
2174
+ lhs, _, args, _ = val
2175
+
2176
+ pop_pktbl
2177
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2178
+ }
2179
+ | p_const p_lparen p_find tRPAREN
2180
+ {
2181
+ const, _, find, _ = val
2182
+
2183
+ pop_pktbl
2184
+ result = new_find_pattern(const, find).line const.line
2185
+ }
2186
+ | p_const p_lparen p_kwargs tRPAREN
2187
+ {
2188
+ lhs, _, kwargs, _ = val
2189
+
2190
+ pop_pktbl
2191
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2192
+ }
2193
+ | p_const tLPAREN2 tRPAREN
2194
+ {
2195
+ const, _, _ = val
2196
+
2197
+ tail = new_array_pattern_tail nil, nil, nil, nil
2198
+ result = new_array_pattern const, nil, tail, const.line
2199
+ }
2200
+ | p_const p_lbracket p_args rbracket
2201
+ {
2202
+ const, _, pre_arg, _ = val
2203
+
2204
+ pop_pktbl
2205
+ result = new_array_pattern const, nil, pre_arg, const.line
2206
+ }
2207
+ | p_const p_lbracket p_find rbracket
2208
+ {
2209
+ const, _, find, _ = val
2210
+
2211
+ pop_pktbl
2212
+ result = new_find_pattern(const, find).line const.line
2213
+ }
2214
+ | p_const p_lbracket p_kwargs rbracket
2215
+ {
2216
+ const, _, kwargs, _ = val
2217
+
2218
+ result = new_hash_pattern const, kwargs, const.line
2219
+ }
2220
+ | p_const tLBRACK2 rbracket
2221
+ {
2222
+ const, _, _ = val
2223
+
2224
+ tail = new_array_pattern_tail nil, nil, nil, nil
2225
+ result = new_array_pattern const, nil, tail, const.line
2226
+ }
2227
+ | tLBRACK p_args rbracket
2228
+ {
2229
+ _, pat, _ = val
2230
+
2231
+ result = new_array_pattern nil, nil, pat, pat.line
2232
+ }
2233
+ | tLBRACK p_find rbracket
2234
+ {
2235
+ _, find, _ = val
2236
+
2237
+ result = new_find_pattern nil, find
2238
+ }
2239
+ | tLBRACK rbracket
2240
+ {
2241
+ (_, line), _ = val
2242
+
2243
+ result = s(:array_pat).line line
2244
+ }
2245
+ | tLBRACE
2246
+ {
2247
+ push_pktbl
2248
+ result = self.in_kwarg
2249
+ self.in_kwarg = false
2250
+ }
2251
+ p_kwargs rbrace
2252
+ {
2253
+ _, in_kwarg, kwargs, _ = val
2254
+
2255
+ pop_pktbl
2256
+ self.in_kwarg = in_kwarg
2257
+
2258
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2259
+ }
2260
+ | tLBRACE rbrace
2261
+ {
2262
+ (_, line), _ = val
2263
+
2264
+ tail = new_hash_pattern_tail nil, nil, line
2265
+ result = new_hash_pattern nil, tail, line
2266
+ }
2267
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2268
+ {
2269
+ _, _, expr, _ = val
2270
+
2271
+ pop_pktbl
2272
+ result = expr
2273
+ }
2274
+
2275
+ p_args: p_expr
2276
+ {
2277
+ expr, = val
2278
+
2279
+ ary = s(:array_TAIL, expr).line expr.line
2280
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2281
+ }
2282
+ | p_args_head
2283
+ {
2284
+ head, = val
2285
+
2286
+ result = new_array_pattern_tail head, true, nil, nil
2287
+ }
2288
+ | p_args_head p_arg
2289
+ {
2290
+ head, tail = val
2291
+
2292
+ both = array_pat_concat head, tail
2293
+
2294
+ result = new_array_pattern_tail both, nil, nil, nil
2295
+ result.line head.line
2296
+ }
2297
+ | p_args_head tSTAR tIDENTIFIER
2298
+ {
2299
+ head, _, (id, _line) = val
2300
+
2301
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2302
+ result.line head.line
2303
+ }
2304
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2305
+ {
2306
+ head, _, (id, _line), _, post = val
2307
+
2308
+ result = new_array_pattern_tail head, true, id.to_sym, post
2309
+ result.line head.line
2310
+ }
2311
+ | p_args_head tSTAR
2312
+ {
2313
+ expr, _ = val
2314
+
2315
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2316
+ }
2317
+ | p_args_head tSTAR tCOMMA p_args_post
2318
+ {
2319
+ head, _, _, post = val
2320
+
2321
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2322
+ }
2323
+ | p_args_tail
2324
+
2325
+ p_args_head: p_arg tCOMMA
2326
+ {
2327
+ arg, _ = val
2328
+ result = arg
2329
+ }
2330
+ | p_args_head p_arg tCOMMA
2331
+ {
2332
+ head, tail, _ = val
2333
+
2334
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2335
+ result.line head.line
2336
+ }
2337
+
2338
+ p_args_tail: p_rest
2339
+ {
2340
+ (id, line), = val
2341
+
2342
+ result = new_array_pattern_tail nil, true, id, nil
2343
+ result.line line
2344
+ }
2345
+ | p_rest tCOMMA p_args_post
2346
+ {
2347
+ (id, line), _, rhs = val
2348
+
2349
+ result = new_array_pattern_tail nil, true, id, rhs
2350
+ result.line line
2351
+ }
2352
+
2353
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2354
+ {
2355
+ lhs, _, mid, _, rhs = val
2356
+
2357
+ result = new_find_pattern_tail lhs, mid, rhs
2358
+ }
2359
+
2360
+ p_rest: tSTAR tIDENTIFIER
2361
+ {
2362
+ _, (id, line) = val
2363
+
2364
+ result = [id.to_sym, line]
2365
+ }
2366
+ | tSTAR
2367
+ {
2368
+ (_id, line), = val
2369
+
2370
+ result = [nil, line]
2371
+ }
2372
+
2373
+ p_args_post: p_arg
2374
+ | p_args_post tCOMMA p_arg
2375
+ {
2376
+ lhs, _, rhs = val
2377
+
2378
+ result = array_pat_concat lhs, rhs
2379
+ }
2380
+
2381
+ p_arg: p_expr
2382
+ {
2383
+ expr, = val
2384
+ expr = s(:array_TAIL, expr).line expr.line unless
2385
+ expr.sexp_type == :array_TAIL
2386
+ result = expr
2387
+ }
2388
+
2389
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2390
+ {
2391
+ kw_arg, _, rest = val
2392
+ # TODO? new_unique_key_hash(p, $1, &@$)
2393
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2394
+ }
2395
+ | p_kwarg
2396
+ {
2397
+ kwarg, = val
2398
+ # TODO? new_unique_key_hash(p, $1, &@$)
2399
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2400
+ }
2401
+ | p_kwarg tCOMMA
2402
+ {
2403
+ kwarg, _ = val
2404
+ # TODO? new_unique_key_hash(p, $1, &@$)
2405
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2406
+ }
2407
+ | p_any_kwrest
2408
+ {
2409
+ rest, = val
2410
+
2411
+ result = new_hash_pattern_tail nil, rest, rest.line
2412
+ }
2413
+
2414
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2415
+ | p_kwarg tCOMMA p_kw
2416
+ {
2417
+ kwarg, _, kw = val
2418
+ kwarg.concat kw.sexp_body
2419
+ result = kwarg
2420
+ }
2421
+
2422
+ p_kw: p_kw_label p_expr
2423
+ {
2424
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2425
+ lhs, rhs = val
2426
+
2427
+ result = s(:PAIR, lhs, rhs).line lhs.line
2428
+ }
2429
+ | p_kw_label
2430
+ {
2431
+ lhs, = val
2432
+
2433
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2434
+
2435
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2436
+ # yyerror1(&@1, "key must be valid as local variables");
2437
+ # }
2438
+
2439
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2440
+ # assignable(p, $1, 0, &@$));
2441
+
2442
+ case lhs.sexp_type
2443
+ when :lit then
2444
+ assignable [lhs.value, lhs.line]
2445
+ else
2446
+ # TODO or done?
2447
+ debug 10
2448
+ end
2449
+
2450
+ # TODO PAIR -> LIST ?
2451
+ result = s(:PAIR, lhs, nil).line lhs.line
2452
+ }
2453
+
2454
+ p_kw_label: tLABEL
2455
+ {
2456
+ result = wrap :lit, val[0]
2457
+ }
2458
+
2459
+ p_kwrest: kwrest_mark tIDENTIFIER
2460
+ {
2461
+ _, (id, line) = val
2462
+
2463
+ name = id.to_sym
2464
+ self.assignable [name, line]
2465
+ result = s(:kwrest, :"**#{name}").line line
2466
+ }
2467
+ | kwrest_mark
2468
+ {
2469
+ (_, line), = val
2470
+
2471
+ result = s(:kwrest, :"**").line line
2472
+ }
2473
+
2474
+ p_kwnorest: kwrest_mark kNIL
2475
+ {
2476
+ (_, line), _ = val
2477
+
2478
+ # TODO: or s(:norest)? s(:**nil)?
2479
+ result = s(:kwrest, :"**nil").line line
2480
+ }
2481
+
2482
+ p_any_kwrest: p_kwrest
2483
+ | p_kwnorest
2484
+
2485
+ p_value: p_primitive
2486
+ | p_primitive tDOT2 p_primitive
2487
+ {
2488
+ lhs, _, rhs = val
2489
+
2490
+ lhs = value_expr lhs
2491
+ rhs = value_expr rhs
2492
+
2493
+ result = s(:dot2, lhs, rhs).line lhs.line
2494
+ }
2495
+ | p_primitive tDOT3 p_primitive
2496
+ {
2497
+ lhs, _, rhs = val
2498
+
2499
+ lhs = value_expr lhs
2500
+ rhs = value_expr rhs
2501
+
2502
+ result = s(:dot3, lhs, rhs).line lhs.line
2503
+ }
2504
+ | p_primitive tDOT2
2505
+ {
2506
+ v1, _ = val
2507
+
2508
+ result = s(:dot2, v1, nil).line v1.line
2509
+ }
2510
+ | p_primitive tDOT3
2511
+ {
2512
+ v1, _ = val
2513
+
2514
+ result = s(:dot3, v1, nil).line v1.line
2515
+ }
2516
+ | p_variable
2517
+ | p_var_ref
2518
+ | p_const
2519
+ | tBDOT2 p_primitive
2520
+ {
2521
+ _, v1 = val
2522
+
2523
+ result = s(:dot2, nil, v1).line v1.line
2524
+ }
2525
+ | tBDOT3 p_primitive
2526
+ {
2527
+ _, v1 = val
2528
+
2529
+ result = s(:dot3, nil, v1).line v1.line
2530
+ }
2531
+
2532
+ p_primitive: literal
2533
+ | strings
2534
+ | xstring
2535
+ | regexp
2536
+ | words
2537
+ | qwords
2538
+ | symbols
2539
+ | qsymbols
2540
+ | keyword_variable
2541
+ {
2542
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2543
+ var, = val
2544
+
2545
+ result = var
2546
+ }
2547
+ | lambda
2548
+
2549
+ p_variable: tIDENTIFIER
2550
+ {
2551
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2552
+ # TODO: assignable(p, $1, 0, &@$);
2553
+ result = wrap :lvar, val[0]
2554
+ }
2555
+
2556
+ p_var_ref: tCARET tIDENTIFIER
2557
+ {
2558
+ # TODO: check id against env for lvar or dvar
2559
+ result = wrap :lvar, val[1]
2560
+ }
2561
+
2562
+
2563
+ p_const: tCOLON3 cname
2564
+ {
2565
+ result = wrap :colon3, val[1]
2566
+ }
2567
+ | p_const tCOLON2 cname
2568
+ {
2569
+ lhs, _, (id, _line) = val
2570
+
2571
+ l = lhs.line
2572
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2573
+ }
2574
+ | tCONSTANT
2575
+ {
2576
+ # TODO $$ = gettable(p, $1, &@$);
2577
+ result = wrap :const, val[0]
2578
+ }
2579
+ ######################################################################
2580
+
2581
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2582
+ {
2583
+ (_, line), klasses, var, _, body, rest = val
2584
+
2585
+ klasses ||= s(:array)
2586
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2587
+ klasses.line line
2588
+
2589
+ result = new_resbody(klasses, body)
2590
+ result << rest if rest # UGH, rewritten above
2591
+ }
2592
+ |
2593
+ {
2594
+ result = nil
2595
+ }
2596
+
2597
+ exc_list: arg_value
2598
+ {
2599
+ arg, = val
2600
+ result = s(:array, arg).line arg.line
2601
+ }
2602
+ | mrhs
2603
+ | none
2604
+
2605
+ exc_var: tASSOC lhs
2606
+ {
2607
+ result = val[1]
2608
+ }
2609
+ | none
2610
+
2611
+ opt_ensure: k_ensure compstmt
2612
+ {
2613
+ (_, line), body = val
2614
+
2615
+ result = body || s(:nil).line(line)
2616
+ }
2617
+ | none
2618
+
2619
+ literal: numeric
2620
+ {
2621
+ (lit, line), = val
2622
+ result = s(:lit, lit).line line
2623
+ }
2624
+ | symbol
2625
+
2626
+ strings: string
2627
+ {
2628
+ str, = val
2629
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2630
+ result = str
2631
+ }
2632
+
2633
+ string: tCHAR
2634
+ {
2635
+ debug 12
2636
+ }
2637
+ | string1
2638
+ | string string1
2639
+ {
2640
+ result = self.literal_concat val[0], val[1]
2641
+ }
2642
+
2643
+ string1: tSTRING_BEG string_contents tSTRING_END
2644
+ {
2645
+ (_, line), str, (_, func) = val
2646
+
2647
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2648
+
2649
+ result = str.line line
2650
+ }
2651
+ | tSTRING
2652
+ {
2653
+ result = new_string val
2654
+ }
2655
+
2656
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2006
2657
  {
2007
2658
  result = new_xstring val
2008
2659
  # TODO: dedent?!?! SERIOUSLY?!?
@@ -2015,11 +2666,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2015
2666
 
2016
2667
  words: tWORDS_BEG tSPACE tSTRING_END
2017
2668
  {
2018
- result = s(:array).line lexer.lineno
2669
+ (_, line), _, _ = val
2670
+
2671
+ result = s(:array).line line
2019
2672
  }
2020
2673
  | tWORDS_BEG word_list tSTRING_END
2021
2674
  {
2022
- result = val[1]
2675
+ (_, line), list, _ = val
2676
+
2677
+ result = list.line line
2023
2678
  }
2024
2679
 
2025
2680
  word_list: none
@@ -2039,18 +2694,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2039
2694
 
2040
2695
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2041
2696
  {
2042
- result = s(:array).line lexer.lineno
2697
+ (_, line), _, _ = val
2698
+
2699
+ result = s(:array).line line
2043
2700
  }
2044
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2701
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2045
2702
  {
2046
- _, line, list, _, = val
2047
- list.line = line
2703
+ (_, line), list, _, = val
2704
+ list.line line
2048
2705
  result = list
2049
2706
  }
2050
2707
 
2051
2708
  symbol_list: none
2052
2709
  {
2053
- result = new_symbol_list.line lexer.lineno
2710
+ result = new_symbol_list
2054
2711
  }
2055
2712
  | symbol_list word tSPACE
2056
2713
  {
@@ -2060,20 +2717,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2060
2717
 
2061
2718
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2062
2719
  {
2063
- result = s(:array).line lexer.lineno
2720
+ (_, line), _, _ = val
2721
+
2722
+ result = s(:array).line line
2064
2723
  }
2065
2724
  | tQWORDS_BEG qword_list tSTRING_END
2066
2725
  {
2067
- result = val[1]
2726
+ (_, line), list, _ = val
2727
+
2728
+ result = list.line line
2068
2729
  }
2069
2730
 
2070
2731
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2071
2732
  {
2072
- result = s(:array).line lexer.lineno # FIX
2733
+ (_, line), _, _ = val
2734
+
2735
+ result = s(:array).line line
2073
2736
  }
2074
2737
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2075
2738
  {
2076
- result = val[1]
2739
+ (_, line), list, _ = val
2740
+
2741
+ result = list.line line
2077
2742
  }
2078
2743
 
2079
2744
  qword_list: none
@@ -2096,7 +2761,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2096
2761
 
2097
2762
  string_contents: none
2098
2763
  {
2099
- result = s(:str, "").line lexer.lineno
2764
+ line = prev_value_to_lineno _values.last
2765
+ result = s(:str, +"").line line
2100
2766
  }
2101
2767
  | string_contents string_content
2102
2768
  {
@@ -2171,8 +2837,8 @@ regexp_contents: none
2171
2837
  lexer.brace_nest = brace_nest
2172
2838
  lexer.string_nest = string_nest
2173
2839
 
2174
- lexer.cmdarg.pop
2175
2840
  lexer.cond.pop
2841
+ lexer.cmdarg.pop
2176
2842
 
2177
2843
  lexer.lex_state = oldlex_state
2178
2844
 
@@ -2187,29 +2853,42 @@ regexp_contents: none
2187
2853
  when nil then
2188
2854
  result = s(:evstr).line line
2189
2855
  else
2190
- debug20 25
2856
+ debug 13
2191
2857
  raise "unknown string body: #{stmt.inspect}"
2192
2858
  end
2193
2859
  }
2194
2860
 
2195
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2196
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2197
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2861
+ string_dvar: tGVAR
2862
+ {
2863
+ result = wrap :gvar, val[0]
2864
+ }
2865
+ | tIVAR
2866
+ {
2867
+ result = wrap :ivar, val[0]
2868
+ }
2869
+ | tCVAR
2870
+ {
2871
+ result = wrap :cvar, val[0]
2872
+ }
2198
2873
  | backref
2199
2874
 
2200
- symbol: tSYMBEG sym
2875
+ symbol: ssym
2876
+ | dsym
2877
+
2878
+ ssym: tSYMBEG sym
2201
2879
  {
2202
2880
  lexer.lex_state = EXPR_END
2203
- result = val[1].to_sym
2881
+ result = wrap :lit, val[1]
2204
2882
  }
2205
2883
  | tSYMBOL
2206
2884
  {
2207
- result = val[0].to_sym
2885
+ lexer.lex_state = EXPR_END
2886
+ result = wrap :lit, val[0]
2208
2887
  }
2209
2888
 
2210
2889
  sym: fname | tIVAR | tGVAR | tCVAR
2211
2890
 
2212
- dsym: tSYMBEG xstring_contents tSTRING_END
2891
+ dsym: tSYMBEG string_contents tSTRING_END
2213
2892
  {
2214
2893
  _, result, _ = val
2215
2894
 
@@ -2225,14 +2904,15 @@ regexp_contents: none
2225
2904
  when :evstr then
2226
2905
  result = s(:dsym, "", result).line result.line
2227
2906
  else
2228
- debug20 26, val, result
2907
+ debug 14
2229
2908
  end
2230
2909
  }
2231
2910
 
2232
2911
  numeric: simple_numeric
2233
- | tUMINUS_NUM simple_numeric
2912
+ | tUMINUS_NUM simple_numeric =tLOWEST
2234
2913
  {
2235
- result = -val[1] # TODO: pt_testcase
2914
+ _, (num, line) = val
2915
+ result = [-num, line]
2236
2916
  }
2237
2917
 
2238
2918
  simple_numeric: tINTEGER
@@ -2240,6 +2920,7 @@ regexp_contents: none
2240
2920
  | tRATIONAL
2241
2921
  | tIMAGINARY
2242
2922
 
2923
+
2243
2924
  user_variable: tIDENTIFIER
2244
2925
  | tIVAR
2245
2926
  | tGVAR
@@ -2265,8 +2946,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2946
 
2266
2947
  var_ref: user_variable
2267
2948
  {
2268
- var = val[0]
2949
+ raise "NO: #{val.inspect}" if Sexp === val.first
2950
+ (var, line), = val
2269
2951
  result = Sexp === var ? var : self.gettable(var)
2952
+
2953
+ result.line line
2270
2954
  }
2271
2955
  | keyword_variable
2272
2956
  {
@@ -2281,11 +2965,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2281
2965
  | keyword_variable
2282
2966
  {
2283
2967
  result = self.assignable val[0]
2284
- debug20 29, val, result
2968
+ debug 15
2285
2969
  }
2286
2970
 
2287
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2288
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2971
+ backref: tNTH_REF
2972
+ {
2973
+ (ref, line), = val
2974
+ result = s(:nth_ref, ref).line line
2975
+ }
2976
+ | tBACK_REF
2977
+ {
2978
+ (ref, line), = val
2979
+ result = s(:back_ref, ref).line line
2980
+ }
2289
2981
 
2290
2982
  superclass: tLT
2291
2983
  {
@@ -2301,26 +2993,26 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2301
2993
  result = nil
2302
2994
  }
2303
2995
 
2304
- f_arglist: tLPAREN2 f_args rparen
2996
+ f_opt_paren_args: f_paren_args
2997
+ | none
2305
2998
  {
2306
- result = val[1]
2307
- self.lexer.lex_state = EXPR_BEG
2308
- self.lexer.command_start = true
2999
+ result = end_args val
3000
+ }
3001
+
3002
+ f_paren_args: tLPAREN2 f_args rparen
3003
+ {
3004
+ result = end_args val
2309
3005
  }
2310
3006
  | tLPAREN2 f_arg tCOMMA args_forward rparen
2311
3007
  {
2312
- result = args val
2313
-
2314
- self.lexer.lex_state = EXPR_BEG
2315
- self.lexer.command_start = true
3008
+ result = end_args val
2316
3009
  }
2317
3010
  | tLPAREN2 args_forward rparen
2318
3011
  {
2319
- result = args val
2320
-
2321
- self.lexer.lex_state = EXPR_BEG
2322
- self.lexer.command_start = true
3012
+ result = end_args val
2323
3013
  }
3014
+
3015
+ f_arglist: f_paren_args
2324
3016
  | {
2325
3017
  result = self.in_kwarg
2326
3018
  self.in_kwarg = true
@@ -2328,12 +3020,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2328
3020
  }
2329
3021
  f_args term
2330
3022
  {
2331
- kwarg, args, _ = val
2332
-
2333
- self.in_kwarg = kwarg
2334
- result = args
2335
- lexer.lex_state = EXPR_BEG
2336
- lexer.command_start = true
3023
+ result = end_args val
2337
3024
  }
2338
3025
 
2339
3026
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,7 +3031,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
3031
  {
2345
3032
  result = args val
2346
3033
  }
2347
- | f_kwrest opt_f_block_arg
3034
+ | f_any_kwrest opt_f_block_arg
2348
3035
  {
2349
3036
  result = args val
2350
3037
  }
@@ -2418,6 +3105,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2418
3105
  |
2419
3106
  {
2420
3107
  result = args val
3108
+ # result.line lexer.lineno
2421
3109
  }
2422
3110
 
2423
3111
  args_forward: tBDOT3
@@ -2445,10 +3133,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2445
3133
  f_norm_arg: f_bad_arg
2446
3134
  | tIDENTIFIER
2447
3135
  {
2448
- identifier = val[0].to_sym
3136
+ (id, line), = val
3137
+ identifier = id.to_sym
2449
3138
  self.env[identifier] = :lvar
2450
3139
 
2451
- result = identifier
3140
+ result = [identifier, line]
2452
3141
  }
2453
3142
 
2454
3143
  f_arg_asgn: f_norm_arg
@@ -2456,22 +3145,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2456
3145
  f_arg_item: f_arg_asgn
2457
3146
  | tLPAREN f_margs rparen
2458
3147
  {
2459
- result = val[1]
3148
+ _, margs, _ = val
3149
+
3150
+ result = margs
2460
3151
  }
2461
3152
 
2462
3153
  f_arg: f_arg_item
2463
3154
  {
2464
- arg, = val
2465
-
2466
- case arg
2467
- when Symbol then
2468
- result = s(:args, arg).line lexer.lineno
2469
- when Sexp then
2470
- result = arg
2471
- else
2472
- debug20 32
2473
- raise "Unknown f_arg type: #{val.inspect}"
2474
- end
3155
+ result = new_arg val
2475
3156
  }
2476
3157
  | f_arg tCOMMA f_arg_item
2477
3158
  {
@@ -2483,7 +3164,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2483
3164
  result = s(:args, list).line list.line
2484
3165
  end
2485
3166
 
2486
- result << item
3167
+ result << (Sexp === item ? item : item.first)
2487
3168
  }
2488
3169
 
2489
3170
  f_label: tLABEL
@@ -2544,27 +3225,46 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
3225
  kwrest_mark: tPOW
2545
3226
  | tDSTAR
2546
3227
 
3228
+ f_no_kwarg: kwrest_mark kNIL
3229
+ {
3230
+ (_, line), _ = val
3231
+ result = [:"**nil", line]
3232
+ }
3233
+
2547
3234
  f_kwrest: kwrest_mark tIDENTIFIER
2548
3235
  {
2549
- name = val[1].to_sym
2550
- self.assignable name
2551
- result = :"**#{name}"
3236
+ _, (id, line) = val
3237
+
3238
+ name = id.to_sym
3239
+ self.assignable [name, line]
3240
+ result = [:"**#{name}", line]
2552
3241
  }
2553
3242
  | kwrest_mark
2554
3243
  {
2555
- result = :"**"
2556
- self.env[result] = :lvar
3244
+ id = :"**"
3245
+ self.env[id] = :lvar # TODO: needed?!?
3246
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2557
3247
  }
2558
3248
 
2559
- f_opt: f_arg_asgn tEQL arg_value
3249
+ f_opt: f_arg_asgn
3250
+ tEQL
3251
+ arg_value
2560
3252
  {
2561
- result = self.assignable val[0], val[2]
3253
+ lhs, _, rhs = val
3254
+ result = self.assignable lhs, rhs
2562
3255
  # TODO: detect duplicate names
3256
+ # TODO? p->cur_arg = 0;
3257
+ # TODO? p->ctxt.in_argdef = 1;
2563
3258
  }
2564
3259
 
2565
- f_block_opt: f_arg_asgn tEQL primary_value
3260
+ f_block_opt: f_arg_asgn
3261
+ tEQL
3262
+ primary_value
2566
3263
  {
2567
- result = self.assignable val[0], val[2]
3264
+ lhs, _, rhs = val
3265
+ result = self.assignable lhs, rhs
3266
+ # TODO? p->cur_arg = 0;
3267
+ # TODO? p->ctxt.in_argdef = 1;
2568
3268
  }
2569
3269
 
2570
3270
  f_block_optarg: f_block_opt
@@ -2594,30 +3294,39 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
3294
  f_rest_arg: restarg_mark tIDENTIFIER
2595
3295
  {
2596
3296
  # TODO: differs from parse.y - needs tests
2597
- name = val[1].to_sym
2598
- self.assignable name
2599
- result = :"*#{name}"
3297
+ _, (id, line) = val
3298
+ name = id.to_sym
3299
+ self.assignable [name, line]
3300
+ result = [:"*#{name}", line]
2600
3301
  }
2601
3302
  | restarg_mark
2602
3303
  {
2603
3304
  name = :"*"
2604
3305
  self.env[name] = :lvar
2605
- result = name
3306
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2606
3307
  }
2607
3308
 
2608
3309
  blkarg_mark: tAMPER2 | tAMPER
2609
3310
 
2610
3311
  f_block_arg: blkarg_mark tIDENTIFIER
2611
3312
  {
2612
- identifier = val[1].to_sym
3313
+ _, (id, line) = val
3314
+ identifier = id.to_sym
2613
3315
 
2614
3316
  self.env[identifier] = :lvar
2615
- result = "&#{identifier}".to_sym
3317
+ result = ["&#{identifier}".to_sym, line]
3318
+ }
3319
+ | blkarg_mark
3320
+ {
3321
+ (_, line), = val
3322
+
3323
+ result = [:&, line]
2616
3324
  }
2617
3325
 
2618
3326
  opt_f_block_arg: tCOMMA f_block_arg
2619
3327
  {
2620
- result = val[1]
3328
+ _, arg = val
3329
+ result = arg
2621
3330
  }
2622
3331
  |
2623
3332
  {
@@ -2659,16 +3368,25 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2659
3368
  }
2660
3369
  | tLABEL arg_value
2661
3370
  {
2662
- (label, line), arg = val
3371
+ label, arg = val
3372
+
3373
+ lit = wrap :lit, label
3374
+ result = s(:array, lit, arg).line lit.line
3375
+ }
3376
+ | tLABEL
3377
+ {
3378
+ lit = wrap :lit, val[0]
3379
+ arg = nil
2663
3380
 
2664
- lit = s(:lit, label.to_sym).line line
2665
- result = s(:array, lit, arg).line line
3381
+ result = s(:array, lit, arg).line lit.line
2666
3382
  }
2667
3383
  | tSTRING_BEG string_contents tLABEL_END arg_value
2668
3384
  {
2669
- _, sym, _, value = val
3385
+ (_, line), sym, _, value = val
3386
+
2670
3387
  sym.sexp_type = :dsym
2671
- result = s(:array, sym, value).line sym.line
3388
+
3389
+ result = s(:array, sym, value).line line
2672
3390
  }
2673
3391
  | tDSTAR arg_value
2674
3392
  {
@@ -2690,7 +3408,21 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2690
3408
  opt_terms: | terms
2691
3409
  opt_nl: | tNL
2692
3410
  rparen: opt_nl tRPAREN
3411
+ # TODO:
3412
+ # {
3413
+ # _, close = val
3414
+ # result = [close, lexer.lineno]
3415
+ # }
2693
3416
  rbracket: opt_nl tRBRACK
3417
+ {
3418
+ _, close = val
3419
+ result = [close, lexer.lineno]
3420
+ }
3421
+ rbrace: opt_nl tRCURLY
3422
+ {
3423
+ _, close = val
3424
+ result = [close, lexer.lineno]
3425
+ }
2694
3426
  trailer: | tNL | tCOMMA
2695
3427
 
2696
3428
  term: tSEMI { yyerrok }