ruby_parser 3.12.0 → 3.13.0

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