ruby_parser 3.12.0 → 3.13.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.
@@ -27,9 +27,9 @@ start
27
27
 
28
28
  return process_string if lex_strterm
29
29
 
30
- self.command_state = self.command_start
30
+ self.cmd_state = self.command_start
31
31
  self.command_start = false
32
- self.space_seen = false
32
+ self.space_seen = false # TODO: rename token_seen?
33
33
  self.last_state = lex_state
34
34
 
35
35
  rule
@@ -41,7 +41,7 @@ rule
41
41
 
42
42
  /\n|\#/ process_newline_or_comment
43
43
 
44
- /[\]\)\}]/ process_bracing
44
+ /[\]\)\}]/ process_brace_close
45
45
 
46
46
  : /\!/
47
47
  | in_arg_state? /\!\@/ { result :expr_arg, :tUBANG, "!@" }
@@ -50,10 +50,11 @@ rule
50
50
  : /\./
51
51
  | /\.\.\.?/ { result :expr_beg, TOKENS[text], text }
52
52
  | /\.\d/ { rb_compile_error "no .<digit> floating literal anymore put 0 before dot" }
53
- | /\./ { result :expr_dot, :tDOT, "." }
53
+ | /\./ { self.lex_state = :expr_beg; result :expr_dot, :tDOT, "." }
54
54
 
55
55
  /\(/ process_paren
56
56
 
57
+ # TODO: :expr_beg|:expr_label
57
58
  /\,/ { result :expr_beg, TOKENS[text], text }
58
59
 
59
60
  : /=/
@@ -101,7 +102,7 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
101
102
  | /\|\=/ { result :expr_beg, :tOP_ASGN, "|" }
102
103
  | /\|/ { result :arg_state, :tPIPE, "|" }
103
104
 
104
- /\{/ process_curly_brace
105
+ /\{/ process_brace_open
105
106
 
106
107
  : /\*/
107
108
  | /\*\*=/ { result :expr_beg, :tOP_ASGN, "**" }
@@ -109,22 +110,23 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
109
110
  | /\*\=/ { result(:expr_beg, :tOP_ASGN, "*") }
110
111
  | /\*/ { result(:arg_state, space_vs_beginning(:tSTAR, :tSTAR, :tSTAR2), "*") }
111
112
 
113
+ # TODO: fix result+process_lchevron to set command_start = true
112
114
  : /</
113
115
  | /\<\=\>/ { result :arg_state, :tCMP, "<=>" }
114
116
  | /\<\=/ { result :arg_state, :tLEQ, "<=" }
115
- | /\<\<\=/ { result :arg_state, :tOP_ASGN, "<<" }
117
+ | /\<\<\=/ { result :expr_beg, :tOP_ASGN, "<<" }
116
118
  | /\<\</ process_lchevron
117
119
  | /\</ { result :arg_state, :tLT, "<" }
118
120
 
119
121
  : />/
120
122
  | /\>\=/ { result :arg_state, :tGEQ, ">=" }
121
- | /\>\>=/ { result :arg_state, :tOP_ASGN, ">>" }
123
+ | /\>\>=/ { result :expr_beg, :tOP_ASGN, ">>" }
122
124
  | /\>\>/ { result :arg_state, :tRSHFT, ">>" }
123
125
  | /\>/ { result :arg_state, :tGT, ">" }
124
126
 
125
127
  : /\`/
126
128
  | expr_fname? /\`/ { result(:expr_end, :tBACK_REF2, "`") }
127
- | expr_dot? /\`/ { result((command_state ? :expr_cmdarg : :expr_arg), :tBACK_REF2, "`") }
129
+ | expr_dot? /\`/ { result((cmd_state ? :expr_cmdarg : :expr_arg), :tBACK_REF2, "`") }
128
130
  | /\`/ { string STR_XQUOTE, '`'; result(nil, :tXSTRING_BEG, "`") }
129
131
 
130
132
  /\?/ process_questionmark
@@ -70,9 +70,9 @@ class RubyLexer
70
70
 
71
71
  def next_token
72
72
  return process_string if lex_strterm
73
- self.command_state = self.command_start
73
+ self.cmd_state = self.command_start
74
74
  self.command_start = false
75
- self.space_seen = false
75
+ self.space_seen = false # TODO: rename token_seen?
76
76
  self.last_state = lex_state
77
77
 
78
78
  token = nil
@@ -87,7 +87,7 @@ class RubyLexer
87
87
  when text = ss.scan(/\n|\#/) then
88
88
  process_newline_or_comment text
89
89
  when text = ss.scan(/[\]\)\}]/) then
90
- process_bracing text
90
+ process_brace_close text
91
91
  when ss.match?(/\!/) then
92
92
  case
93
93
  when in_arg_state? && (ss.skip(/\!\@/)) then
@@ -102,7 +102,7 @@ class RubyLexer
102
102
  when ss.skip(/\.\d/) then
103
103
  action { rb_compile_error "no .<digit> floating literal anymore put 0 before dot" }
104
104
  when ss.skip(/\./) then
105
- action { result :expr_dot, :tDOT, "." }
105
+ action { self.lex_state = :expr_beg; result :expr_dot, :tDOT, "." }
106
106
  end # group /\./
107
107
  when text = ss.scan(/\(/) then
108
108
  process_paren text
@@ -183,7 +183,7 @@ class RubyLexer
183
183
  action { result :arg_state, :tPIPE, "|" }
184
184
  end # group /\|/
185
185
  when text = ss.scan(/\{/) then
186
- process_curly_brace text
186
+ process_brace_open text
187
187
  when ss.match?(/\*/) then
188
188
  case
189
189
  when ss.skip(/\*\*=/) then
@@ -202,7 +202,7 @@ class RubyLexer
202
202
  when ss.skip(/\<\=/) then
203
203
  action { result :arg_state, :tLEQ, "<=" }
204
204
  when ss.skip(/\<\<\=/) then
205
- action { result :arg_state, :tOP_ASGN, "<<" }
205
+ action { result :expr_beg, :tOP_ASGN, "<<" }
206
206
  when text = ss.scan(/\<\</) then
207
207
  process_lchevron text
208
208
  when ss.skip(/\</) then
@@ -213,7 +213,7 @@ class RubyLexer
213
213
  when ss.skip(/\>\=/) then
214
214
  action { result :arg_state, :tGEQ, ">=" }
215
215
  when ss.skip(/\>\>=/) then
216
- action { result :arg_state, :tOP_ASGN, ">>" }
216
+ action { result :expr_beg, :tOP_ASGN, ">>" }
217
217
  when ss.skip(/\>\>/) then
218
218
  action { result :arg_state, :tRSHFT, ">>" }
219
219
  when ss.skip(/\>/) then
@@ -224,7 +224,7 @@ class RubyLexer
224
224
  when expr_fname? && (ss.skip(/\`/)) then
225
225
  action { result(:expr_end, :tBACK_REF2, "`") }
226
226
  when expr_dot? && (ss.skip(/\`/)) then
227
- action { result((command_state ? :expr_cmdarg : :expr_arg), :tBACK_REF2, "`") }
227
+ action { result((cmd_state ? :expr_cmdarg : :expr_arg), :tBACK_REF2, "`") }
228
228
  when ss.skip(/\`/) then
229
229
  action { string STR_XQUOTE, '`'; result(nil, :tXSTRING_BEG, "`") }
230
230
  end # group /\`/
@@ -34,7 +34,7 @@ class RubyParser
34
34
  begin
35
35
  return parser.process s, f, t
36
36
  rescue Racc::ParseError, RubyParser::SyntaxError => exc
37
- e = exc
37
+ e ||= exc
38
38
  end
39
39
  end
40
40
  raise e
@@ -66,27 +66,25 @@ end
66
66
 
67
67
  ##
68
68
  # Unfortunately a problem with racc is that it won't let me namespace
69
- # properly, so instead of RubyParser::V18, I still have to generate
70
- # the old Ruby23Parser and shove it in as V23.
69
+ # properly, so instead of RubyParser::V25, I still have to generate
70
+ # the old Ruby25Parser and shove it in as V25.
71
71
 
72
- require "ruby18_parser"
73
- require "ruby19_parser"
74
72
  require "ruby20_parser"
75
73
  require "ruby21_parser"
76
74
  require "ruby22_parser"
77
75
  require "ruby23_parser"
78
76
  require "ruby24_parser"
79
77
  require "ruby25_parser"
78
+ require "ruby26_parser"
80
79
 
81
80
  class RubyParser # HACK
82
81
  VERSIONS.clear # also a HACK caused by racc namespace issues
83
82
 
83
+ class V26 < ::Ruby26Parser; end
84
84
  class V25 < ::Ruby25Parser; end
85
85
  class V24 < ::Ruby24Parser; end
86
86
  class V23 < ::Ruby23Parser; end
87
87
  class V22 < ::Ruby22Parser; end
88
88
  class V21 < ::Ruby21Parser; end
89
89
  class V20 < ::Ruby20Parser; end
90
- class V19 < ::Ruby19Parser; end
91
- class V18 < ::Ruby18Parser; end
92
90
  end
@@ -12,6 +12,8 @@ class Ruby23Parser
12
12
  class Ruby24Parser
13
13
  #elif V == 25
14
14
  class Ruby25Parser
15
+ #elif V == 26
16
+ class Ruby26Parser
15
17
  #else
16
18
  fail "version not specified or supported on code generation"
17
19
  #endif
@@ -108,14 +110,35 @@ rule
108
110
  end
109
111
  self.env.extend
110
112
  }
111
- tLCURLY top_compstmt tRCURLY
113
+ begin_block
112
114
  {
113
- result = new_iter s(:preexe), nil, val[3]
115
+ _, _, block = val
116
+ result = block
117
+ }
118
+
119
+ begin_block: tLCURLY top_compstmt tRCURLY
120
+ {
121
+ _, stmt, _ = val
122
+ result = new_iter s(:preexe), 0, stmt
123
+ }
124
+
125
+ bodystmt: compstmt opt_rescue k_else
126
+ {
127
+ res = _values[-2]
128
+ yyerror "else without rescue is useless" unless res
114
129
  }
130
+ compstmt
131
+ opt_ensure
132
+ {
133
+ body, resc, _, _, els, ens = val
115
134
 
116
- bodystmt: compstmt opt_rescue opt_else opt_ensure
135
+ result = new_body [body, resc, els, ens]
136
+ }
137
+ | compstmt opt_rescue opt_ensure
117
138
  {
118
- result = new_body val
139
+ body, resc, ens = val
140
+
141
+ result = new_body [body, resc, nil, ens]
119
142
  }
120
143
 
121
144
  compstmt: stmts opt_terms
@@ -124,8 +147,8 @@ rule
124
147
  }
125
148
 
126
149
  stmts: none
127
- | stmt
128
- | stmts terms stmt
150
+ | stmt_or_begin # TODO: newline_node ?
151
+ | stmts terms stmt_or_begin
129
152
  {
130
153
  result = self.block_append val[0], val[2]
131
154
  }
@@ -135,6 +158,21 @@ rule
135
158
  debug20 2, val, result
136
159
  }
137
160
 
161
+ stmt_or_begin: stmt
162
+ | klBEGIN
163
+ {
164
+ if (self.in_def || self.in_single > 0) then
165
+ debug20 1
166
+ yyerror "BEGIN in method"
167
+ end
168
+ self.env.extend
169
+ }
170
+ begin_block
171
+ {
172
+ _, _, stmt = val
173
+ result = stmt
174
+ }
175
+
138
176
  stmt: kALIAS fitem
139
177
  {
140
178
  lexer.lex_state = :expr_fname
@@ -178,7 +216,8 @@ rule
178
216
  }
179
217
  | stmt kRESCUE_MOD stmt
180
218
  {
181
- result = s(:rescue, val[0], new_resbody(s(:array), val[2]))
219
+ body, _, resbody = val
220
+ result = new_rescue body, new_resbody(s(:array), resbody)
182
221
  }
183
222
  | klEND tLCURLY compstmt tRCURLY
184
223
  {
@@ -193,15 +232,41 @@ rule
193
232
  {
194
233
  result = new_masgn val[0], val[2], :wrap
195
234
  }
196
- | var_lhs tOP_ASGN command_call
235
+ | lhs tEQL mrhs
236
+ {
237
+ result = new_assign val[0], s(:svalue, val[2])
238
+ }
239
+ #if V == 20
240
+ | mlhs tEQL arg_value
241
+ {
242
+ result = new_masgn val[0], val[2], :wrap
243
+ }
244
+ | mlhs tEQL mrhs
245
+ #else
246
+ | mlhs tEQL mrhs_arg
247
+ #endif
248
+ {
249
+ result = new_masgn val[0], val[2]
250
+ }
251
+ | expr
252
+
253
+ command_asgn: lhs tEQL command_rhs
254
+ {
255
+ result = new_assign val[0], val[2]
256
+ }
257
+ # | lhs tEQL command_asgn
258
+ # {
259
+ # result = new_assign val[0], val[2]
260
+ # }
261
+ | var_lhs tOP_ASGN command_rhs
197
262
  {
198
263
  result = new_op_asgn val
199
264
  }
200
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
265
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
201
266
  {
202
267
  result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
203
268
  }
204
- | primary_value call_op tIDENTIFIER tOP_ASGN command_call
269
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
205
270
  {
206
271
  result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
207
272
  if val[1] == '&.'
@@ -209,7 +274,7 @@ rule
209
274
  end
210
275
  result.line = val[0].line
211
276
  }
212
- | primary_value call_op tCONSTANT tOP_ASGN command_call
277
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
213
278
  {
214
279
  result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
215
280
  if val[1] == '&.'
@@ -217,46 +282,33 @@ rule
217
282
  end
218
283
  result.line = val[0].line
219
284
  }
220
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
285
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
221
286
  {
222
287
  result = s(:op_asgn, val[0], val[4], val[2], val[3])
223
288
  debug20 4, val, result
224
289
  }
225
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
290
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
226
291
  {
227
292
  result = s(:op_asgn, val[0], val[4], val[2], val[3])
228
293
  debug20 5, val, result
229
294
  }
230
- | backref tOP_ASGN command_call
295
+ | backref tOP_ASGN command_rhs
231
296
  {
232
297
  self.backref_assign_error val[0]
233
298
  }
234
- | lhs tEQL mrhs
235
- {
236
- result = new_assign val[0], s(:svalue, val[2])
237
- }
238
- #if V == 20
239
- | mlhs tEQL arg_value
240
- {
241
- result = new_masgn val[0], val[2], :wrap
242
- }
243
- | mlhs tEQL mrhs
244
- #else
245
- | mlhs tEQL mrhs_arg
246
- #endif
247
- {
248
- result = new_masgn val[0], val[2]
249
- }
250
- | expr
251
299
 
252
- command_asgn: lhs tEQL command_call
300
+ command_rhs: command_call =tOP_ASGN
253
301
  {
254
- result = new_assign val[0], val[2]
302
+ expr, = val
303
+ result = value_expr expr
255
304
  }
256
- | lhs tEQL command_asgn
305
+ | command_call kRESCUE_MOD stmt
257
306
  {
258
- result = new_assign val[0], val[2]
307
+ expr, _, resbody = val
308
+ expr = value_expr expr
309
+ result = new_rescue(expr, new_resbody(s(:array), resbody))
259
310
  }
311
+ | command_asgn
260
312
 
261
313
  expr: command_call
262
314
  | expr kAND expr
@@ -282,30 +334,40 @@ rule
282
334
  result = value_expr(val[0])
283
335
  }
284
336
 
337
+ expr_value_do: {
338
+ lexer.cond.push true
339
+ }
340
+ expr_value do
341
+ {
342
+ lexer.cond.pop
343
+ }
344
+ {
345
+ _, expr, _, _ = val
346
+ result = expr
347
+ }
348
+
285
349
  command_call: command
286
350
  | block_command
287
351
 
288
352
  block_command: block_call
289
- | block_call dot_or_colon operation2 command_args
353
+ | block_call call_op2 operation2 command_args
290
354
  {
291
355
  result = new_call val[0], val[2].to_sym, val[3]
292
356
  }
293
357
 
294
358
  cmd_brace_block: tLBRACE_ARG
295
359
  {
296
- self.env.extend(:dynamic)
360
+ # self.env.extend(:dynamic)
297
361
  result = self.lexer.lineno
298
362
  }
299
- opt_block_param
300
- {
301
- result = nil # self.env.dynamic.keys
302
- }
303
- compstmt tRCURLY
363
+ brace_body tRCURLY
304
364
  {
305
- result = new_iter nil, val[2], val[4]
306
- result.line = val[1]
365
+ _, line, body, _ = val
307
366
 
308
- self.env.unextend
367
+ result = body
368
+ result.line = line
369
+
370
+ # self.env.unextend
309
371
  }
310
372
 
311
373
  fcall: operation
@@ -363,7 +425,7 @@ rule
363
425
  {
364
426
  result = new_yield val[1]
365
427
  }
366
- | kRETURN call_args
428
+ | k_return call_args
367
429
  {
368
430
  line = val[0].last
369
431
  result = s(:return, ret_args(val[1])).line(line)
@@ -587,8 +649,9 @@ rule
587
649
 
588
650
  | reswords
589
651
  {
652
+ (sym, _line), = val
590
653
  lexer.lex_state = :expr_end
591
- result = val[0]
654
+ result = sym
592
655
  }
593
656
 
594
657
  fsym: fname | symbol
@@ -618,7 +681,7 @@ rule
618
681
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
619
682
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
620
683
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
621
- #if V == 20
684
+ #if V >= 20
622
685
  | tUBANG
623
686
  #endif
624
687
 
@@ -632,51 +695,46 @@ rule
632
695
  | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
633
696
  | kUNTIL
634
697
 
635
- arg: lhs tEQL arg
698
+ arg: lhs tEQL arg_rhs
636
699
  {
637
700
  result = new_assign val[0], val[2]
638
701
  }
639
- | lhs tEQL arg kRESCUE_MOD arg
640
- {
641
- result = new_assign val[0], s(:rescue, val[2], new_resbody(s(:array), val[4]))
642
- }
643
- | var_lhs tOP_ASGN arg
644
- {
645
- result = new_op_asgn val
646
- }
647
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
702
+ | var_lhs tOP_ASGN arg_rhs
648
703
  {
649
704
  result = new_op_asgn val
650
- result = s(:rescue, result, new_resbody(s(:array), val[4]))
651
705
  }
652
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
706
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
653
707
  {
654
708
  val[2].sexp_type = :arglist if val[2]
655
709
  result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
656
710
  }
657
- | primary_value call_op tIDENTIFIER tOP_ASGN arg
711
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
658
712
  {
659
713
  result = new_op_asgn2 val
660
714
  }
661
- | primary_value call_op tCONSTANT tOP_ASGN arg
715
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
662
716
  {
663
717
  result = new_op_asgn2 val
664
718
  }
665
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
719
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
666
720
  {
667
721
  result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
668
722
  }
669
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
723
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
670
724
  {
671
- yyerror "constant re-assignment"
725
+ # TODO: assignment
726
+ raise "not yet: %p" % [val]
672
727
  }
673
- | tCOLON3 tCONSTANT tOP_ASGN arg
728
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
674
729
  {
675
- yyerror "constant re-assignment"
730
+ # TODO: assignment
731
+ raise "not yet: %p" % [val]
676
732
  }
677
- | backref tOP_ASGN arg
733
+ | backref tOP_ASGN arg_rhs
678
734
  {
679
- self.backref_assign_error val[0]
735
+ # TODO: lhs = var_field val[0]
736
+ asgn = new_op_asgn val
737
+ result = self.backref_assign_error asgn
680
738
  }
681
739
  | arg tDOT2 arg
682
740
  {
@@ -696,6 +754,20 @@ rule
696
754
  result = s(:dot3, v1, v2)
697
755
  end
698
756
  }
757
+ #if V >= 26
758
+ | arg tDOT2
759
+ {
760
+ v1, v2 = val[0], nil
761
+
762
+ result = s(:dot2, v1, v2)
763
+ }
764
+ | arg tDOT3
765
+ {
766
+ v1, v2 = val[0], nil
767
+
768
+ result = s(:dot3, v1, v2)
769
+ }
770
+ #endif
699
771
  | arg tPLUS arg
700
772
  {
701
773
  result = new_call val[0], :+, argl(val[2])
@@ -760,22 +832,7 @@ rule
760
832
  {
761
833
  result = new_call val[0], :"<=>", argl(val[2])
762
834
  }
763
- | arg tGT arg
764
- {
765
- result = new_call val[0], :">", argl(val[2])
766
- }
767
- | arg tGEQ arg
768
- {
769
- result = new_call val[0], :">=", argl(val[2])
770
- }
771
- | arg tLT arg
772
- {
773
- result = new_call val[0], :"<", argl(val[2])
774
- }
775
- | arg tLEQ arg
776
- {
777
- result = new_call val[0], :"<=", argl(val[2])
778
- }
835
+ | rel_expr =tCMP
779
836
  | arg tEQ arg
780
837
  {
781
838
  result = new_call val[0], :"==", argl(val[2])
@@ -834,6 +891,23 @@ rule
834
891
  }
835
892
  | primary
836
893
 
894
+ relop: tGT
895
+ | tLT
896
+ | tGEQ
897
+ | tLEQ
898
+
899
+ rel_expr: arg relop arg =tGT
900
+ {
901
+ lhs, op, rhs = val
902
+ result = new_call lhs, op.to_sym, argl(rhs)
903
+ }
904
+ | rel_expr relop arg =tGT
905
+ {
906
+ lhs, op, rhs = val
907
+ warn "comparison '%s' after comparison", op
908
+ result = new_call lhs, op.to_sym, argl(rhs)
909
+ }
910
+
837
911
  arg_value: arg
838
912
  {
839
913
  result = value_expr(val[0])
@@ -853,6 +927,15 @@ rule
853
927
  result = args [array_to_hash(val[0])]
854
928
  }
855
929
 
930
+ arg_rhs: arg =tOP_ASGN
931
+ | arg kRESCUE_MOD arg
932
+ {
933
+ body, _, resbody = val
934
+ body = value_expr body
935
+ resbody = remove_begin resbody
936
+ result = new_rescue(body, new_resbody(s(:array), resbody))
937
+ }
938
+
856
939
  paren_args: tLPAREN2 opt_call_args rparen
857
940
  {
858
941
  result = val[1]
@@ -908,12 +991,11 @@ rule
908
991
  }
909
992
 
910
993
  command_args: {
911
- result = lexer.cmdarg.stack.dup # TODO: smell?
912
- lexer.cmdarg.push true
994
+ result = lexer.cmdarg.store true
913
995
  }
914
996
  call_args
915
997
  {
916
- lexer.cmdarg.stack.replace val[0]
998
+ lexer.cmdarg.restore val[0]
917
999
  result = val[1]
918
1000
  }
919
1001
 
@@ -983,12 +1065,16 @@ rule
983
1065
  {
984
1066
  result = new_call nil, val[0].to_sym
985
1067
  }
986
- | kBEGIN
1068
+ | k_begin
987
1069
  {
988
1070
  result = self.lexer.lineno
1071
+ # TODO:
1072
+ # $<val>1 = cmdarg_stack;
1073
+ # CMDARG_SET(0);
989
1074
  }
990
- bodystmt kEND
1075
+ bodystmt k_end
991
1076
  {
1077
+ # TODO: CMDARG_SET($<val>1);
992
1078
  unless val[2] then
993
1079
  result = s(:nil)
994
1080
  else
@@ -999,22 +1085,25 @@ rule
999
1085
  }
1000
1086
  | tLPAREN_ARG rparen
1001
1087
  {
1088
+ # TODO: lex_state = :expr_endarg in between
1002
1089
  debug20 13, val, result
1003
1090
  }
1004
1091
  | tLPAREN_ARG
1005
1092
  {
1006
- result = self.lexer.cmdarg.stack.dup
1007
- lexer.cmdarg.stack.replace [false] # TODO add api for these
1093
+ result = lexer.cmdarg.store false
1094
+ # result = self.lexer.cmdarg.stack.dup
1095
+ # lexer.cmdarg.stack.replace [false] # TODO add api for these
1008
1096
  }
1009
- expr
1097
+ stmt
1010
1098
  {
1011
1099
  lexer.lex_state = :expr_endarg
1012
1100
  }
1013
1101
  rparen
1014
1102
  {
1103
+ _, cmdarg, stmt, _, _, = val
1015
1104
  warning "(...) interpreted as grouped expression"
1016
- lexer.cmdarg.stack.replace val[1]
1017
- result = val[2]
1105
+ lexer.cmdarg.restore cmdarg
1106
+ result = stmt
1018
1107
  }
1019
1108
  | tLPAREN compstmt tRPAREN
1020
1109
  {
@@ -1042,7 +1131,7 @@ rule
1042
1131
  {
1043
1132
  result = new_hash val
1044
1133
  }
1045
- | kRETURN
1134
+ | k_return
1046
1135
  {
1047
1136
  result = s(:return)
1048
1137
  }
@@ -1090,61 +1179,42 @@ rule
1090
1179
  {
1091
1180
  result = val[1] # TODO: fix lineno
1092
1181
  }
1093
- | kIF expr_value then compstmt if_tail kEND
1094
- {
1095
- result = new_if val[1], val[3], val[4]
1096
- }
1097
- | kUNLESS expr_value then compstmt opt_else kEND
1098
- {
1099
- result = new_if val[1], val[4], val[3]
1100
- }
1101
- | kWHILE
1102
- {
1103
- lexer.cond.push true
1104
- }
1105
- expr_value do
1106
- {
1107
- lexer.cond.pop
1108
- }
1109
- compstmt kEND
1182
+ | k_if expr_value then compstmt if_tail k_end
1110
1183
  {
1111
- result = new_while val[5], val[2], true
1184
+ _, c, _, t, f, _ = val
1185
+ result = new_if c, t, f
1112
1186
  }
1113
- | kUNTIL
1187
+ | k_unless expr_value then compstmt opt_else k_end
1114
1188
  {
1115
- lexer.cond.push true
1189
+ _, c, _, t, f, _ = val
1190
+ result = new_if c, f, t
1116
1191
  }
1117
- expr_value do
1192
+ | k_while expr_value_do compstmt k_end
1118
1193
  {
1119
- lexer.cond.pop
1194
+ _, cond, body, _ = val
1195
+ result = new_while body, cond, true
1120
1196
  }
1121
- compstmt kEND
1197
+ | k_until expr_value_do compstmt k_end
1122
1198
  {
1123
- result = new_until val[5], val[2], true
1199
+ _, cond, body, _ = val
1200
+ result = new_until body, cond, true
1124
1201
  }
1125
- | kCASE expr_value opt_terms case_body kEND
1202
+ | k_case expr_value opt_terms case_body k_end
1126
1203
  {
1127
1204
  (_, line), expr, _, body, _ = val
1128
1205
  result = new_case expr, body, line
1129
1206
  }
1130
- | kCASE opt_terms case_body kEND
1207
+ | k_case opt_terms case_body k_end
1131
1208
  {
1132
1209
  (_, line), _, body, _ = val
1133
1210
  result = new_case nil, body, line
1134
1211
  }
1135
- | kFOR for_var kIN
1136
- {
1137
- lexer.cond.push true
1138
- }
1139
- expr_value do
1140
- {
1141
- lexer.cond.pop
1142
- }
1143
- compstmt kEND
1212
+ | k_for for_var kIN expr_value_do compstmt k_end
1144
1213
  {
1145
- result = new_for val[4], val[1], val[7]
1214
+ _, var, _, iter, body, _ = val
1215
+ result = new_for iter, var, body
1146
1216
  }
1147
- | kCLASS
1217
+ | k_class
1148
1218
  {
1149
1219
  result = self.lexer.lineno
1150
1220
  }
@@ -1156,13 +1226,13 @@ rule
1156
1226
  end
1157
1227
  self.env.extend
1158
1228
  }
1159
- bodystmt kEND
1229
+ bodystmt k_end
1160
1230
  {
1161
1231
  result = new_class val
1162
1232
  self.env.unextend
1163
1233
  self.lexer.comments # we don't care about comments in the body
1164
1234
  }
1165
- | kCLASS tLSHFT
1235
+ | k_class tLSHFT
1166
1236
  {
1167
1237
  result = self.lexer.lineno
1168
1238
  }
@@ -1177,13 +1247,13 @@ rule
1177
1247
  self.in_single = 0
1178
1248
  self.env.extend
1179
1249
  }
1180
- bodystmt kEND
1250
+ bodystmt k_end
1181
1251
  {
1182
1252
  result = new_sclass val
1183
1253
  self.env.unextend
1184
1254
  self.lexer.comments # we don't care about comments in the body
1185
1255
  }
1186
- | kMODULE
1256
+ | k_module
1187
1257
  {
1188
1258
  result = self.lexer.lineno
1189
1259
  }
@@ -1195,13 +1265,13 @@ rule
1195
1265
 
1196
1266
  self.env.extend
1197
1267
  }
1198
- bodystmt kEND
1268
+ bodystmt k_end
1199
1269
  {
1200
1270
  result = new_module val
1201
1271
  self.env.unextend
1202
1272
  self.lexer.comments # we don't care about comments in the body
1203
1273
  }
1204
- | kDEF fname
1274
+ | k_def fname
1205
1275
  {
1206
1276
  result = [self.in_def, self.lexer.cmdarg.stack.dup]
1207
1277
 
@@ -1212,7 +1282,7 @@ rule
1212
1282
  # TODO: port local_push_gen and local_pop_gen
1213
1283
  lexer.cmdarg.stack.replace [false]
1214
1284
  }
1215
- f_arglist bodystmt kEND
1285
+ f_arglist bodystmt k_end
1216
1286
  {
1217
1287
  in_def, cmdarg = val[2]
1218
1288
 
@@ -1223,7 +1293,7 @@ rule
1223
1293
  self.in_def = in_def
1224
1294
  self.lexer.comments # we don't care about comments in the body
1225
1295
  }
1226
- | kDEF singleton dot_or_colon
1296
+ | k_def singleton dot_or_colon
1227
1297
  {
1228
1298
  self.comments.push self.lexer.comments
1229
1299
  lexer.lex_state = :expr_fname
@@ -1236,7 +1306,7 @@ rule
1236
1306
  result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1237
1307
  lexer.cmdarg.stack.replace [false]
1238
1308
  }
1239
- f_arglist bodystmt kEND
1309
+ f_arglist bodystmt k_end
1240
1310
  {
1241
1311
  line, cmdarg = val[5]
1242
1312
  result = new_defs val
@@ -1281,7 +1351,15 @@ rule
1281
1351
  k_class: kCLASS
1282
1352
  k_module: kMODULE
1283
1353
  k_def: kDEF
1354
+ k_do: kDO
1355
+ k_do_block: kDO_BLOCK
1356
+ k_rescue: kRESCUE
1357
+ k_ensure: kENSURE
1358
+ k_when: kWHEN
1359
+ k_else: kELSE
1360
+ k_elsif: kELSIF
1284
1361
  k_end: kEND
1362
+ k_return: kRETURN
1285
1363
 
1286
1364
  then: term
1287
1365
  | kTHEN
@@ -1291,7 +1369,7 @@ rule
1291
1369
  | kDO_COND
1292
1370
 
1293
1371
  if_tail: opt_else
1294
- | kELSIF expr_value then compstmt if_tail
1372
+ | k_elsif expr_value then compstmt if_tail
1295
1373
  {
1296
1374
  result = s(:if, val[1], val[3], val[4])
1297
1375
  }
@@ -1462,18 +1540,22 @@ opt_block_args_tail: tCOMMA block_args_tail
1462
1540
 
1463
1541
  opt_block_param: none { result = 0 }
1464
1542
  | block_param_def
1543
+ {
1544
+ self.lexer.command_start = true
1545
+ }
1465
1546
 
1466
1547
  block_param_def: tPIPE opt_bv_decl tPIPE
1467
1548
  {
1549
+ # TODO: current_arg = 0
1468
1550
  result = args val
1469
1551
  }
1470
1552
  | tOROP
1471
1553
  {
1472
- self.lexer.command_start = true
1473
1554
  result = s(:args)
1474
1555
  }
1475
1556
  | tPIPE block_param opt_bv_decl tPIPE
1476
1557
  {
1558
+ # TODO: current_arg = 0
1477
1559
  result = args val
1478
1560
  }
1479
1561
 
@@ -1506,13 +1588,21 @@ opt_block_args_tail: tCOMMA block_args_tail
1506
1588
  lexer.paren_nest += 1
1507
1589
  lexer.lpar_beg = lexer.paren_nest
1508
1590
  }
1509
- f_larglist lambda_body
1591
+ f_larglist
1592
+ {
1593
+ result = [lexer.cmdarg.store(false), self.lexer.lineno]
1594
+ }
1595
+ lambda_body
1510
1596
  {
1511
- lpar, args, body = val
1597
+ lpar, args, (cmdarg, lineno), body = val
1512
1598
  lexer.lpar_beg = lpar
1513
1599
 
1600
+ lexer.cmdarg.restore cmdarg
1601
+ lexer.cmdarg.lexpop
1602
+
1514
1603
  call = new_call nil, :lambda
1515
1604
  result = new_iter call, args, body
1605
+ result.line = lineno
1516
1606
  self.env.unextend
1517
1607
  }
1518
1608
 
@@ -1530,28 +1620,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1530
1620
  {
1531
1621
  result = val[1]
1532
1622
  }
1533
- | kDO_LAMBDA compstmt kEND
1623
+ | kDO_LAMBDA bodystmt kEND
1534
1624
  {
1535
1625
  result = val[1]
1536
1626
  }
1537
1627
 
1538
- do_block: kDO_BLOCK
1539
- {
1540
- self.env.extend :dynamic
1541
- result = self.lexer.lineno
1542
- }
1543
- opt_block_param
1544
- {
1545
- result = nil # self.env.dynamic.keys
1546
- }
1547
- compstmt kEND
1628
+ do_block: k_do_block do_body kEND
1548
1629
  {
1549
- args = val[2]
1550
- body = val[4]
1551
- result = new_iter nil, args, body
1552
- result.line = val[1]
1553
-
1554
- self.env.unextend
1630
+ # TODO: maybe fix lineno to kDO's lineno?
1631
+ result = val[1]
1555
1632
  }
1556
1633
 
1557
1634
  block_call: command do_block
@@ -1568,11 +1645,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1568
1645
  result = val[1]
1569
1646
  result.insert 1, val[0]
1570
1647
  }
1571
- | block_call dot_or_colon operation2 opt_paren_args
1648
+ | block_call call_op2 operation2 opt_paren_args
1572
1649
  {
1573
1650
  result = new_call val[0], val[2].to_sym, val[3]
1574
1651
  }
1575
- | block_call dot_or_colon operation2 opt_paren_args brace_block
1652
+ | block_call call_op2 operation2 opt_paren_args brace_block
1576
1653
  {
1577
1654
  iter1, _, name, args, iter2 = val
1578
1655
 
@@ -1581,7 +1658,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1581
1658
 
1582
1659
  result = iter2
1583
1660
  }
1584
- | block_call dot_or_colon operation2 command_args do_block
1661
+ | block_call call_op2 operation2 command_args do_block
1585
1662
  {
1586
1663
  iter1, _, name, args, iter2 = val
1587
1664
 
@@ -1638,43 +1715,59 @@ opt_block_args_tail: tCOMMA block_args_tail
1638
1715
  self.env.extend :dynamic
1639
1716
  result = self.lexer.lineno
1640
1717
  }
1641
- opt_block_param
1642
- {
1643
- result = nil # self.env.dynamic.keys
1644
- }
1645
- compstmt tRCURLY
1718
+ brace_body tRCURLY
1646
1719
  {
1647
- _, line, args, _, body, _ = val
1720
+ _, line, body, _ = val
1648
1721
 
1649
- result = new_iter nil, args, body
1722
+ result = body
1650
1723
  result.line = line
1651
1724
 
1652
1725
  self.env.unextend
1653
1726
  }
1654
- | kDO
1727
+ | k_do
1655
1728
  {
1656
1729
  self.env.extend :dynamic
1657
1730
  result = self.lexer.lineno
1658
1731
  }
1659
- opt_block_param
1732
+ do_body kEND
1733
+ {
1734
+ _, line, body, _ = val
1735
+
1736
+ result = body
1737
+ result.line = line
1738
+
1739
+ self.env.unextend
1740
+ }
1741
+
1742
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1743
+ { result = lexer.cmdarg.store(false) }
1744
+ opt_block_param compstmt
1660
1745
  {
1661
- result = nil # self.env.dynamic.keys
1746
+ line, cmdarg, param, cmpstmt = val
1747
+
1748
+ result = new_brace_body param, cmpstmt, line
1749
+ self.env.unextend
1750
+ lexer.cmdarg.restore cmdarg
1751
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1662
1752
  }
1753
+
1754
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1755
+ { result = lexer.cmdarg.store(false) }
1756
+ opt_block_param
1663
1757
  #if V >= 25
1664
- bodystmt kEND
1758
+ bodystmt
1665
1759
  #else
1666
- compstmt kEND
1760
+ compstmt
1667
1761
  #endif
1668
1762
  {
1669
- _, line, args, _, body, _ = val
1670
-
1671
- result = new_iter nil, args, body
1672
- result.line = line
1763
+ line, cmdarg, param, cmpstmt = val
1673
1764
 
1765
+ result = new_do_body param, cmpstmt, line
1674
1766
  self.env.unextend
1767
+ lexer.cmdarg.restore cmdarg
1675
1768
  }
1676
1769
 
1677
- case_body: kWHEN
1770
+ case_body: k_when
1678
1771
  {
1679
1772
  result = self.lexer.lineno
1680
1773
  }
@@ -1687,7 +1780,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1687
1780
 
1688
1781
  cases: opt_else | case_body
1689
1782
 
1690
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1783
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1691
1784
  {
1692
1785
  (_, line), klasses, var, _, body, rest = val
1693
1786
 
@@ -1716,7 +1809,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1716
1809
  }
1717
1810
  | none
1718
1811
 
1719
- opt_ensure: kENSURE compstmt
1812
+ opt_ensure: k_ensure compstmt
1720
1813
  {
1721
1814
  _, body = val
1722
1815
 
@@ -1883,7 +1976,7 @@ regexp_contents: none
1883
1976
  result = lexer.lex_strterm
1884
1977
 
1885
1978
  lexer.lex_strterm = nil
1886
- lexer.lex_state = :expr_beg # TODO: expr_value ?
1979
+ lexer.lex_state = :expr_beg
1887
1980
  }
1888
1981
  string_dvar
1889
1982
  {
@@ -1904,15 +1997,11 @@ regexp_contents: none
1904
1997
  lexer.brace_nest = 0
1905
1998
  lexer.string_nest = 0
1906
1999
 
1907
- lexer.lex_state = :expr_value
2000
+ lexer.lex_state = :expr_beg
1908
2001
  }
1909
- compstmt tRCURLY
2002
+ compstmt
2003
+ tSTRING_DEND
1910
2004
  {
1911
- #if V == 20
1912
- # TODO: tRCURLY -> tSTRING_DEND
1913
- #else
1914
- # TODO: tRCURLY -> tSTRING_END
1915
- #endif
1916
2005
  _, memo, stmt, _ = val
1917
2006
 
1918
2007
  lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
@@ -2049,23 +2138,18 @@ keyword_variable: kNIL { result = s(:nil) }
2049
2138
  backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2050
2139
  | tBACK_REF { result = s(:back_ref, val[0]) }
2051
2140
 
2052
- superclass: term
2053
- {
2054
- result = nil
2055
- }
2056
- | tLT
2141
+ superclass: tLT
2057
2142
  {
2058
2143
  lexer.lex_state = :expr_beg
2144
+ lexer.command_start = true
2059
2145
  }
2060
2146
  expr_value term
2061
2147
  {
2062
2148
  result = val[2]
2063
2149
  }
2064
- | error term
2150
+ | none
2065
2151
  {
2066
- yyerrok
2067
2152
  result = nil
2068
- debug20 30, val, result
2069
2153
  }
2070
2154
 
2071
2155
  f_arglist: tLPAREN2 f_args rparen
@@ -2073,16 +2157,20 @@ keyword_variable: kNIL { result = s(:nil) }
2073
2157
  result = val[1]
2074
2158
  self.lexer.lex_state = :expr_beg
2075
2159
  self.lexer.command_start = true
2076
- # TODO:
2077
- # $<num>$ = parser->parser_in_kwarg;
2078
- # parser->parser_in_kwarg = 1;
2079
2160
  }
2080
- | f_args term
2161
+ | {
2162
+ result = self.in_kwarg
2163
+ self.in_kwarg = true
2164
+ # TODO: self.lexer.lex_state |= :expr_label
2165
+ }
2166
+ f_args term
2081
2167
  {
2082
- # TODO: parser->parser_in_kwarg = $<num>1;
2083
- result = val[0]
2084
- self.lexer.lex_state = :expr_beg
2085
- self.lexer.command_start = true
2168
+ kwarg, args, _ = val
2169
+
2170
+ self.in_kwarg = kwarg
2171
+ result = args
2172
+ lexer.lex_state = :expr_beg
2173
+ lexer.command_start = true
2086
2174
  }
2087
2175
 
2088
2176
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2305,7 +2393,9 @@ keyword_variable: kNIL { result = s(:nil) }
2305
2393
 
2306
2394
  f_kwrest: kwrest_mark tIDENTIFIER
2307
2395
  {
2308
- result = :"**#{val[1]}"
2396
+ name = val[1].to_sym
2397
+ self.assignable name
2398
+ result = :"**#{name}"
2309
2399
  }
2310
2400
  | kwrest_mark
2311
2401
  {
@@ -2424,9 +2514,10 @@ keyword_variable: kNIL { result = s(:nil) }
2424
2514
  {
2425
2515
  result = s(:array, val[0], val[2])
2426
2516
  }
2427
- | tLABEL opt_nl arg_value
2517
+ | tLABEL arg_value
2428
2518
  {
2429
- result = s(:array, s(:lit, val[0][0].to_sym), val.last)
2519
+ (label, _), arg = val
2520
+ result = s(:array, s(:lit, label.to_sym), arg)
2430
2521
  }
2431
2522
  #if V >= 22
2432
2523
  | tSTRING_BEG string_contents tLABEL_END arg_value
@@ -2435,11 +2526,6 @@ keyword_variable: kNIL { result = s(:nil) }
2435
2526
  sym.sexp_type = :dsym
2436
2527
  result = s(:array, sym, value)
2437
2528
  }
2438
- | tSYMBOL arg_value
2439
- {
2440
- raise "not yet: #{val.inspect}"
2441
- # result = s(:array, s(:lit, val[1].to_sym), val[1])
2442
- }
2443
2529
  #endif
2444
2530
  | tDSTAR arg_value
2445
2531
  {
@@ -2452,8 +2538,12 @@ keyword_variable: kNIL { result = s(:nil) }
2452
2538
  dot_or_colon: tDOT | tCOLON2
2453
2539
  call_op: tDOT
2454
2540
  #if V >= 23
2455
- | tLONELY
2541
+ | tLONELY # TODO: rename tANDDOT?
2456
2542
  #endif
2543
+
2544
+ call_op2: call_op
2545
+ | tCOLON2
2546
+
2457
2547
  opt_terms: | terms
2458
2548
  opt_nl: | tNL
2459
2549
  rparen: opt_nl tRPAREN