parser 2.7.0.4 → 2.7.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +18 -29
  4. data/CHANGELOG.md +53 -1
  5. data/README.md +6 -6
  6. data/Rakefile +2 -1
  7. data/doc/AST_FORMAT.md +54 -5
  8. data/lib/parser.rb +1 -0
  9. data/lib/parser/all.rb +1 -0
  10. data/lib/parser/ast/processor.rb +7 -0
  11. data/lib/parser/builders/default.rb +63 -14
  12. data/lib/parser/current.rb +13 -4
  13. data/lib/parser/diagnostic.rb +1 -1
  14. data/lib/parser/diagnostic/engine.rb +1 -2
  15. data/lib/parser/lexer.rl +7 -0
  16. data/lib/parser/messages.rb +15 -0
  17. data/lib/parser/meta.rb +2 -2
  18. data/lib/parser/ruby27.y +16 -5
  19. data/lib/parser/ruby28.y +3016 -0
  20. data/lib/parser/runner.rb +26 -2
  21. data/lib/parser/runner/ruby_rewrite.rb +2 -2
  22. data/lib/parser/source/buffer.rb +3 -1
  23. data/lib/parser/source/comment/associator.rb +14 -4
  24. data/lib/parser/source/map/endless_definition.rb +23 -0
  25. data/lib/parser/source/range.rb +16 -0
  26. data/lib/parser/source/tree_rewriter.rb +49 -12
  27. data/lib/parser/source/tree_rewriter/action.rb +96 -26
  28. data/lib/parser/tree_rewriter.rb +1 -2
  29. data/lib/parser/version.rb +1 -1
  30. data/parser.gemspec +2 -1
  31. data/test/helper.rb +25 -6
  32. data/test/parse_helper.rb +11 -17
  33. data/test/test_ast_processor.rb +32 -0
  34. data/test/test_base.rb +1 -1
  35. data/test/test_current.rb +2 -0
  36. data/test/test_diagnostic.rb +6 -7
  37. data/test/test_diagnostic_engine.rb +5 -8
  38. data/test/test_lexer.rb +17 -8
  39. data/test/test_meta.rb +12 -0
  40. data/test/test_parser.rb +260 -21
  41. data/test/test_runner_parse.rb +22 -1
  42. data/test/test_runner_rewrite.rb +1 -1
  43. data/test/test_source_buffer.rb +4 -1
  44. data/test/test_source_comment.rb +2 -2
  45. data/test/test_source_comment_associator.rb +47 -15
  46. data/test/test_source_map.rb +1 -2
  47. data/test/test_source_range.rb +29 -9
  48. data/test/test_source_rewriter.rb +4 -4
  49. data/test/test_source_rewriter_action.rb +2 -2
  50. data/test/test_source_tree_rewriter.rb +96 -6
  51. metadata +14 -7
@@ -48,7 +48,7 @@ module Parser
48
48
  CurrentRuby = Ruby23
49
49
 
50
50
  when /^2\.4\./
51
- current_version = '2.4.9'
51
+ current_version = '2.4.10'
52
52
  if RUBY_VERSION != current_version
53
53
  warn_syntax_deviation 'parser/ruby24', current_version
54
54
  end
@@ -57,7 +57,7 @@ module Parser
57
57
  CurrentRuby = Ruby24
58
58
 
59
59
  when /^2\.5\./
60
- current_version = '2.5.7'
60
+ current_version = '2.5.8'
61
61
  if RUBY_VERSION != current_version
62
62
  warn_syntax_deviation 'parser/ruby25', current_version
63
63
  end
@@ -66,7 +66,7 @@ module Parser
66
66
  CurrentRuby = Ruby25
67
67
 
68
68
  when /^2\.6\./
69
- current_version = '2.6.5'
69
+ current_version = '2.6.6'
70
70
  if RUBY_VERSION != current_version
71
71
  warn_syntax_deviation 'parser/ruby26', current_version
72
72
  end
@@ -75,7 +75,7 @@ module Parser
75
75
  CurrentRuby = Ruby26
76
76
 
77
77
  when /^2\.7\./
78
- current_version = '2.7.0'
78
+ current_version = '2.7.1'
79
79
  if RUBY_VERSION != current_version
80
80
  warn_syntax_deviation 'parser/ruby27', current_version
81
81
  end
@@ -83,6 +83,15 @@ module Parser
83
83
  require 'parser/ruby27'
84
84
  CurrentRuby = Ruby27
85
85
 
86
+ when /^2\.8\./
87
+ current_version = '2.8.0-dev'
88
+ if RUBY_VERSION != current_version
89
+ warn_syntax_deviation 'parser/ruby28', current_version
90
+ end
91
+
92
+ require 'parser/ruby28'
93
+ CurrentRuby = Ruby28
94
+
86
95
  else # :nocov:
87
96
  # Keep this in sync with released Ruby.
88
97
  warn_syntax_deviation 'parser/ruby27', '2.7.x'
@@ -67,7 +67,7 @@ module Parser
67
67
  # @return [String] the rendered message.
68
68
  #
69
69
  def message
70
- MESSAGES[@reason] % @arguments
70
+ Messages.compile(@reason, @arguments)
71
71
  end
72
72
 
73
73
  ##
@@ -7,8 +7,7 @@ module Parser
7
7
  # diagnostics by delegating them to registered consumers.
8
8
  #
9
9
  # @example
10
- # buffer = Parser::Source::Buffer.new(__FILE__)
11
- # buffer.code = 'foobar'
10
+ # buffer = Parser::Source::Buffer.new(__FILE__, source: 'foobar')
12
11
  #
13
12
  # consumer = lambda do |diagnostic|
14
13
  # puts diagnostic.message
@@ -283,6 +283,13 @@ class Parser::Lexer
283
283
  %% write exec;
284
284
  # %
285
285
 
286
+ # Ragel creates a local variable called `testEof` but it doesn't use
287
+ # it in any assignment. This dead code is here to swallow the warning.
288
+ # It has no runtime cost because Ruby doesn't produce any instructions from it.
289
+ if false
290
+ testEof
291
+ end
292
+
286
293
  @p = p
287
294
 
288
295
  if @token_queue.any?
@@ -93,4 +93,19 @@ module Parser
93
93
  :crossing_insertions => 'the rewriting action on:',
94
94
  :crossing_insertions_conflict => 'is crossing that on:',
95
95
  }.freeze
96
+
97
+ # @api private
98
+ module Messages
99
+ # Formats the message, returns a raw template if there's nothing to interpolate
100
+ #
101
+ # Code like `format("", {})` gives a warning, and so this method tries interpolating
102
+ # only if `arguments` hash is not empty.
103
+ #
104
+ # @api private
105
+ def self.compile(reason, arguments)
106
+ template = MESSAGES[reason]
107
+ return template if Hash === arguments && arguments.empty?
108
+ format(template, arguments)
109
+ end
110
+ end
96
111
  end
@@ -12,11 +12,11 @@ module Parser
12
12
  sym dsym xstr regopt regexp array splat
13
13
  pair kwsplat hash irange erange self
14
14
  lvar ivar cvar gvar const defined? lvasgn
15
- ivasgn cvasgn gvasgn casgn mlhs masgn
15
+ ivasgn cvasgn gvasgn casgn mlhs masgn rasgn mrasgn
16
16
  op_asgn and_asgn ensure rescue arg_expr
17
17
  or_asgn back_ref nth_ref
18
18
  match_with_lvasgn match_current_line
19
- module class sclass def defs undef alias args
19
+ module class sclass def defs def_e defs_e undef alias args
20
20
  cbase arg optarg restarg blockarg block_pass kwarg kwoptarg
21
21
  kwrestarg kwnilarg send csend super zsuper yield block
22
22
  and not or if when case while until while_post
@@ -1784,7 +1784,7 @@ opt_block_args_tail:
1784
1784
  # array patterns that end with comma
1785
1785
  # like 1, 2,
1786
1786
  # must be emitted as `array_pattern_with_tail`
1787
- item = @builder.match_with_trailing_comma(val[0])
1787
+ item = @builder.match_with_trailing_comma(val[0], val[1])
1788
1788
  result = @builder.array_pattern(nil, [ item ], nil)
1789
1789
  }
1790
1790
  | p_expr tCOMMA p_args
@@ -1877,13 +1877,16 @@ opt_block_args_tail:
1877
1877
  | tLBRACE
1878
1878
  {
1879
1879
  @pattern_hash_keys.push
1880
+ result = @lexer.in_kwarg
1881
+ @lexer.in_kwarg = false
1880
1882
  }
1881
- p_kwargs tRCURLY
1883
+ p_kwargs rbrace
1882
1884
  {
1883
1885
  @pattern_hash_keys.pop
1886
+ @lexer.in_kwarg = val[1]
1884
1887
  result = @builder.hash_pattern(val[0], val[2], val[3])
1885
1888
  }
1886
- | tLBRACE tRCURLY
1889
+ | tLBRACE rbrace
1887
1890
  {
1888
1891
  result = @builder.hash_pattern(val[0], [], val[1])
1889
1892
  }
@@ -1934,7 +1937,7 @@ opt_block_args_tail:
1934
1937
  # array patterns that end with comma
1935
1938
  # like [1, 2,]
1936
1939
  # must be emitted as `array_pattern_with_tail`
1937
- item = @builder.match_with_trailing_comma(val[0])
1940
+ item = @builder.match_with_trailing_comma(val[0], val[1])
1938
1941
  result = [ item ]
1939
1942
  }
1940
1943
  | p_args_head p_arg tCOMMA
@@ -1942,7 +1945,7 @@ opt_block_args_tail:
1942
1945
  # array patterns that end with comma
1943
1946
  # like [1, 2,]
1944
1947
  # must be emitted as `array_pattern_with_tail`
1945
- last_item = @builder.match_with_trailing_comma(val[1])
1948
+ last_item = @builder.match_with_trailing_comma(val[1], val[2])
1946
1949
  result = [ *val[0], last_item ]
1947
1950
  }
1948
1951
 
@@ -1986,6 +1989,10 @@ opt_block_args_tail:
1986
1989
  {
1987
1990
  result = val[0]
1988
1991
  }
1992
+ | p_kwarg tCOMMA
1993
+ {
1994
+ result = val[0]
1995
+ }
1989
1996
  | p_kwrest
1990
1997
  {
1991
1998
  result = val[0]
@@ -2898,6 +2905,10 @@ keyword_variable: kNIL
2898
2905
  {
2899
2906
  result = val[1]
2900
2907
  }
2908
+ rbrace: opt_nl tRCURLY
2909
+ {
2910
+ result = val[1]
2911
+ }
2901
2912
  trailer: | tNL | tCOMMA
2902
2913
 
2903
2914
  term: tSEMI
@@ -0,0 +1,3016 @@
1
+ class Parser::Ruby28
2
+
3
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
4
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
5
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
6
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
7
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
8
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
9
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
10
+ tUPLUS tUMINUS tUNARY_NUM tPOW tCMP tEQ tEQQ tNEQ
11
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
12
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
13
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
14
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
15
+ tDSTAR tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
16
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
17
+ tWORDS_BEG tQWORDS_BEG tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DBEG
18
+ tSTRING_DVAR tSTRING_END tSTRING_DEND tSTRING tSYMBOL
19
+ tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG tCHARACTER
20
+ tRATIONAL tIMAGINARY tLABEL_END tANDDOT tBDOT2 tBDOT3
21
+
22
+ prechigh
23
+ right tBANG tTILDE tUPLUS
24
+ right tPOW
25
+ right tUNARY_NUM tUMINUS
26
+ left tSTAR2 tDIVIDE tPERCENT
27
+ left tPLUS tMINUS
28
+ left tLSHFT tRSHFT
29
+ left tAMPER2
30
+ left tPIPE tCARET
31
+ left tGT tGEQ tLT tLEQ
32
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
33
+ left tANDOP
34
+ left tOROP
35
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
36
+ right tEH tCOLON
37
+ left kRESCUE_MOD
38
+ right tEQL tOP_ASGN
39
+ nonassoc kDEFINED
40
+ right kNOT
41
+ left kOR kAND
42
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD kIN
43
+ nonassoc tLBRACE_ARG
44
+ nonassoc tLOWEST
45
+ preclow
46
+
47
+ rule
48
+
49
+ program: top_compstmt
50
+
51
+ top_compstmt: top_stmts opt_terms
52
+ {
53
+ result = @builder.compstmt(val[0])
54
+ }
55
+
56
+ top_stmts: # nothing
57
+ {
58
+ result = []
59
+ }
60
+ | top_stmt
61
+ {
62
+ result = [ val[0] ]
63
+ }
64
+ | top_stmts terms top_stmt
65
+ {
66
+ result = val[0] << val[2]
67
+ }
68
+ | error top_stmt
69
+ {
70
+ result = [ val[1] ]
71
+ }
72
+
73
+ top_stmt: stmt
74
+ | klBEGIN begin_block
75
+ {
76
+ result = @builder.preexe(val[0], *val[1])
77
+ }
78
+
79
+ begin_block: tLCURLY top_compstmt tRCURLY
80
+ {
81
+ result = val
82
+ }
83
+
84
+ bodystmt: compstmt opt_rescue opt_else opt_ensure
85
+ {
86
+ rescue_bodies = val[1]
87
+ else_t, else_ = val[2]
88
+ ensure_t, ensure_ = val[3]
89
+
90
+ if rescue_bodies.empty? && !else_t.nil?
91
+ diagnostic :error, :useless_else, nil, else_t
92
+ end
93
+
94
+ result = @builder.begin_body(val[0],
95
+ rescue_bodies,
96
+ else_t, else_,
97
+ ensure_t, ensure_)
98
+ }
99
+
100
+ compstmt: stmts opt_terms
101
+ {
102
+ result = @builder.compstmt(val[0])
103
+ }
104
+
105
+ stmts: # nothing
106
+ {
107
+ result = []
108
+ }
109
+ | stmt_or_begin
110
+ {
111
+ result = [ val[0] ]
112
+ }
113
+ | stmts terms stmt_or_begin
114
+ {
115
+ result = val[0] << val[2]
116
+ }
117
+ | error stmt
118
+ {
119
+ result = [ val[1] ]
120
+ }
121
+
122
+ stmt_or_begin: stmt
123
+ | klBEGIN begin_block
124
+ {
125
+ diagnostic :error, :begin_in_method, nil, val[0]
126
+ }
127
+
128
+ stmt: kALIAS fitem
129
+ {
130
+ @lexer.state = :expr_fname
131
+ }
132
+ fitem
133
+ {
134
+ result = @builder.alias(val[0], val[1], val[3])
135
+ }
136
+ | kALIAS tGVAR tGVAR
137
+ {
138
+ result = @builder.alias(val[0],
139
+ @builder.gvar(val[1]),
140
+ @builder.gvar(val[2]))
141
+ }
142
+ | kALIAS tGVAR tBACK_REF
143
+ {
144
+ result = @builder.alias(val[0],
145
+ @builder.gvar(val[1]),
146
+ @builder.back_ref(val[2]))
147
+ }
148
+ | kALIAS tGVAR tNTH_REF
149
+ {
150
+ diagnostic :error, :nth_ref_alias, nil, val[2]
151
+ }
152
+ | kUNDEF undef_list
153
+ {
154
+ result = @builder.undef_method(val[0], val[1])
155
+ }
156
+ | stmt kIF_MOD expr_value
157
+ {
158
+ result = @builder.condition_mod(val[0], nil,
159
+ val[1], val[2])
160
+ }
161
+ | stmt kUNLESS_MOD expr_value
162
+ {
163
+ result = @builder.condition_mod(nil, val[0],
164
+ val[1], val[2])
165
+ }
166
+ | stmt kWHILE_MOD expr_value
167
+ {
168
+ result = @builder.loop_mod(:while, val[0], val[1], val[2])
169
+ }
170
+ | stmt kUNTIL_MOD expr_value
171
+ {
172
+ result = @builder.loop_mod(:until, val[0], val[1], val[2])
173
+ }
174
+ | stmt kRESCUE_MOD stmt
175
+ {
176
+ rescue_body = @builder.rescue_body(val[1],
177
+ nil, nil, nil,
178
+ nil, val[2])
179
+
180
+ result = @builder.begin_body(val[0], [ rescue_body ])
181
+ }
182
+ | klEND tLCURLY compstmt tRCURLY
183
+ {
184
+ result = @builder.postexe(val[0], val[1], val[2], val[3])
185
+ }
186
+ | command_asgn
187
+ | mlhs tEQL command_call
188
+ {
189
+ result = @builder.multi_assign(val[0], val[1], val[2])
190
+ }
191
+ | lhs tEQL mrhs
192
+ {
193
+ result = @builder.assign(val[0], val[1],
194
+ @builder.array(nil, val[2], nil))
195
+ }
196
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
197
+ {
198
+ rescue_body = @builder.rescue_body(val[3],
199
+ nil, nil, nil,
200
+ nil, val[4])
201
+ begin_body = @builder.begin_body(val[2], [ rescue_body ])
202
+
203
+ result = @builder.multi_assign(val[0], val[1], begin_body)
204
+ }
205
+ | mlhs tEQL mrhs_arg
206
+ {
207
+ result = @builder.multi_assign(val[0], val[1], val[2])
208
+ }
209
+ | rassign
210
+ | expr
211
+
212
+ rassign: arg_value tASSOC lhs
213
+ {
214
+ result = @builder.rassign(val[0], val[1], val[2])
215
+ }
216
+ | arg_value tASSOC mlhs
217
+ {
218
+ result = @builder.multi_rassign(val[0], val[1], val[2])
219
+ }
220
+ | rassign tASSOC lhs
221
+ {
222
+ result = @builder.rassign(val[0], val[1], val[2])
223
+ }
224
+ | rassign tASSOC mlhs
225
+ {
226
+ result = @builder.multi_rassign(val[0], val[1], val[2])
227
+ }
228
+
229
+ command_asgn: lhs tEQL command_rhs
230
+ {
231
+ result = @builder.assign(val[0], val[1], val[2])
232
+ }
233
+ | var_lhs tOP_ASGN command_rhs
234
+ {
235
+ result = @builder.op_assign(val[0], val[1], val[2])
236
+ }
237
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
238
+ {
239
+ result = @builder.op_assign(
240
+ @builder.index(
241
+ val[0], val[1], val[2], val[3]),
242
+ val[4], val[5])
243
+ }
244
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
+ {
246
+ result = @builder.op_assign(
247
+ @builder.call_method(
248
+ val[0], val[1], val[2]),
249
+ val[3], val[4])
250
+ }
251
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
252
+ {
253
+ result = @builder.op_assign(
254
+ @builder.call_method(
255
+ val[0], val[1], val[2]),
256
+ val[3], val[4])
257
+ }
258
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
259
+ {
260
+ const = @builder.const_op_assignable(
261
+ @builder.const_fetch(val[0], val[1], val[2]))
262
+ result = @builder.op_assign(const, val[3], val[4])
263
+ }
264
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
265
+ {
266
+ result = @builder.op_assign(
267
+ @builder.call_method(
268
+ val[0], val[1], val[2]),
269
+ val[3], val[4])
270
+ }
271
+ | backref tOP_ASGN command_rhs
272
+ {
273
+ @builder.op_assign(val[0], val[1], val[2])
274
+ }
275
+
276
+ command_rhs: command_call =tOP_ASGN
277
+ | command_call kRESCUE_MOD stmt
278
+ {
279
+ rescue_body = @builder.rescue_body(val[1],
280
+ nil, nil, nil,
281
+ nil, val[2])
282
+
283
+ result = @builder.begin_body(val[0], [ rescue_body ])
284
+ }
285
+ | command_asgn
286
+
287
+ expr: command_call
288
+ | expr kAND expr
289
+ {
290
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
291
+ }
292
+ | expr kOR expr
293
+ {
294
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
295
+ }
296
+ | kNOT opt_nl expr
297
+ {
298
+ result = @builder.not_op(val[0], nil, val[2], nil)
299
+ }
300
+ | tBANG command_call
301
+ {
302
+ result = @builder.not_op(val[0], nil, val[1], nil)
303
+ }
304
+ | arg kIN
305
+ {
306
+ @lexer.state = :expr_beg
307
+ @lexer.command_start = false
308
+ pattern_variables.push
309
+
310
+ result = @lexer.in_kwarg
311
+ @lexer.in_kwarg = true
312
+ }
313
+ p_expr
314
+ {
315
+ @lexer.in_kwarg = val[2]
316
+ result = @builder.in_match(val[0], val[1], val[3])
317
+ }
318
+ | arg =tLBRACE_ARG
319
+
320
+ expr_value: expr
321
+
322
+ expr_value_do: {
323
+ @lexer.cond.push(true)
324
+ }
325
+ expr_value do
326
+ {
327
+ @lexer.cond.pop
328
+ result = [ val[1], val[2] ]
329
+ }
330
+
331
+ def_name: fname
332
+ {
333
+ @static_env.extend_static
334
+ @lexer.cmdarg.push(false)
335
+ @lexer.cond.push(false)
336
+ @current_arg_stack.push(nil)
337
+
338
+ result = val[0]
339
+ }
340
+
341
+ defn_head: kDEF def_name
342
+ {
343
+ @context.push(:def)
344
+
345
+ result = [ val[0], val[1] ]
346
+ }
347
+
348
+ defs_head: kDEF singleton dot_or_colon
349
+ {
350
+ @lexer.state = :expr_fname
351
+ }
352
+ def_name
353
+ {
354
+ @context.push(:defs)
355
+
356
+ result = [ val[0], val[1], val[2], val[4] ]
357
+ }
358
+
359
+
360
+ command_call: command
361
+ | block_command
362
+
363
+ block_command: block_call
364
+ | block_call dot_or_colon operation2 command_args
365
+ {
366
+ result = @builder.call_method(val[0], val[1], val[2],
367
+ nil, val[3], nil)
368
+ }
369
+
370
+ cmd_brace_block: tLBRACE_ARG
371
+ {
372
+ @context.push(:block)
373
+ }
374
+ brace_body tRCURLY
375
+ {
376
+ result = [ val[0], *val[2], val[3] ]
377
+ @context.pop
378
+ }
379
+
380
+ fcall: operation
381
+
382
+ command: fcall command_args =tLOWEST
383
+ {
384
+ result = @builder.call_method(nil, nil, val[0],
385
+ nil, val[1], nil)
386
+ }
387
+ | fcall command_args cmd_brace_block
388
+ {
389
+ method_call = @builder.call_method(nil, nil, val[0],
390
+ nil, val[1], nil)
391
+
392
+ begin_t, args, body, end_t = val[2]
393
+ result = @builder.block(method_call,
394
+ begin_t, args, body, end_t)
395
+ }
396
+ | primary_value call_op operation2 command_args =tLOWEST
397
+ {
398
+ result = @builder.call_method(val[0], val[1], val[2],
399
+ nil, val[3], nil)
400
+ }
401
+ | primary_value call_op operation2 command_args cmd_brace_block
402
+ {
403
+ method_call = @builder.call_method(val[0], val[1], val[2],
404
+ nil, val[3], nil)
405
+
406
+ begin_t, args, body, end_t = val[4]
407
+ result = @builder.block(method_call,
408
+ begin_t, args, body, end_t)
409
+ }
410
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
411
+ {
412
+ result = @builder.call_method(val[0], val[1], val[2],
413
+ nil, val[3], nil)
414
+ }
415
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
416
+ {
417
+ method_call = @builder.call_method(val[0], val[1], val[2],
418
+ nil, val[3], nil)
419
+
420
+ begin_t, args, body, end_t = val[4]
421
+ result = @builder.block(method_call,
422
+ begin_t, args, body, end_t)
423
+ }
424
+ | kSUPER command_args
425
+ {
426
+ result = @builder.keyword_cmd(:super, val[0],
427
+ nil, val[1], nil)
428
+ }
429
+ | kYIELD command_args
430
+ {
431
+ result = @builder.keyword_cmd(:yield, val[0],
432
+ nil, val[1], nil)
433
+ }
434
+ | k_return call_args
435
+ {
436
+ result = @builder.keyword_cmd(:return, val[0],
437
+ nil, val[1], nil)
438
+ }
439
+ | kBREAK call_args
440
+ {
441
+ result = @builder.keyword_cmd(:break, val[0],
442
+ nil, val[1], nil)
443
+ }
444
+ | kNEXT call_args
445
+ {
446
+ result = @builder.keyword_cmd(:next, val[0],
447
+ nil, val[1], nil)
448
+ }
449
+
450
+ mlhs: mlhs_basic
451
+ {
452
+ result = @builder.multi_lhs(nil, val[0], nil)
453
+ }
454
+ | tLPAREN mlhs_inner rparen
455
+ {
456
+ result = @builder.begin(val[0], val[1], val[2])
457
+ }
458
+
459
+ mlhs_inner: mlhs_basic
460
+ {
461
+ result = @builder.multi_lhs(nil, val[0], nil)
462
+ }
463
+ | tLPAREN mlhs_inner rparen
464
+ {
465
+ result = @builder.multi_lhs(val[0], val[1], val[2])
466
+ }
467
+
468
+ mlhs_basic: mlhs_head
469
+ | mlhs_head mlhs_item
470
+ {
471
+ result = val[0].
472
+ push(val[1])
473
+ }
474
+ | mlhs_head tSTAR mlhs_node
475
+ {
476
+ result = val[0].
477
+ push(@builder.splat(val[1], val[2]))
478
+ }
479
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
480
+ {
481
+ result = val[0].
482
+ push(@builder.splat(val[1], val[2])).
483
+ concat(val[4])
484
+ }
485
+ | mlhs_head tSTAR
486
+ {
487
+ result = val[0].
488
+ push(@builder.splat(val[1]))
489
+ }
490
+ | mlhs_head tSTAR tCOMMA mlhs_post
491
+ {
492
+ result = val[0].
493
+ push(@builder.splat(val[1])).
494
+ concat(val[3])
495
+ }
496
+ | tSTAR mlhs_node
497
+ {
498
+ result = [ @builder.splat(val[0], val[1]) ]
499
+ }
500
+ | tSTAR mlhs_node tCOMMA mlhs_post
501
+ {
502
+ result = [ @builder.splat(val[0], val[1]),
503
+ *val[3] ]
504
+ }
505
+ | tSTAR
506
+ {
507
+ result = [ @builder.splat(val[0]) ]
508
+ }
509
+ | tSTAR tCOMMA mlhs_post
510
+ {
511
+ result = [ @builder.splat(val[0]),
512
+ *val[2] ]
513
+ }
514
+
515
+ mlhs_item: mlhs_node
516
+ | tLPAREN mlhs_inner rparen
517
+ {
518
+ result = @builder.begin(val[0], val[1], val[2])
519
+ }
520
+
521
+ mlhs_head: mlhs_item tCOMMA
522
+ {
523
+ result = [ val[0] ]
524
+ }
525
+ | mlhs_head mlhs_item tCOMMA
526
+ {
527
+ result = val[0] << val[1]
528
+ }
529
+
530
+ mlhs_post: mlhs_item
531
+ {
532
+ result = [ val[0] ]
533
+ }
534
+ | mlhs_post tCOMMA mlhs_item
535
+ {
536
+ result = val[0] << val[2]
537
+ }
538
+
539
+ mlhs_node: user_variable
540
+ {
541
+ result = @builder.assignable(val[0])
542
+ }
543
+ | keyword_variable
544
+ {
545
+ result = @builder.assignable(val[0])
546
+ }
547
+ | primary_value tLBRACK2 opt_call_args rbracket
548
+ {
549
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
550
+ }
551
+ | primary_value call_op tIDENTIFIER
552
+ {
553
+ if (val[1][0] == :anddot)
554
+ diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1]
555
+ end
556
+
557
+ result = @builder.attr_asgn(val[0], val[1], val[2])
558
+ }
559
+ | primary_value tCOLON2 tIDENTIFIER
560
+ {
561
+ result = @builder.attr_asgn(val[0], val[1], val[2])
562
+ }
563
+ | primary_value call_op tCONSTANT
564
+ {
565
+ if (val[1][0] == :anddot)
566
+ diagnostic :error, :csend_in_lhs_of_masgn, nil, val[1]
567
+ end
568
+
569
+ result = @builder.attr_asgn(val[0], val[1], val[2])
570
+ }
571
+ | primary_value tCOLON2 tCONSTANT
572
+ {
573
+ result = @builder.assignable(
574
+ @builder.const_fetch(val[0], val[1], val[2]))
575
+ }
576
+ | tCOLON3 tCONSTANT
577
+ {
578
+ result = @builder.assignable(
579
+ @builder.const_global(val[0], val[1]))
580
+ }
581
+ | backref
582
+ {
583
+ result = @builder.assignable(val[0])
584
+ }
585
+
586
+ lhs: user_variable
587
+ {
588
+ result = @builder.assignable(val[0])
589
+ }
590
+ | keyword_variable
591
+ {
592
+ result = @builder.assignable(val[0])
593
+ }
594
+ | primary_value tLBRACK2 opt_call_args rbracket
595
+ {
596
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
597
+ }
598
+ | primary_value call_op tIDENTIFIER
599
+ {
600
+ result = @builder.attr_asgn(val[0], val[1], val[2])
601
+ }
602
+ | primary_value tCOLON2 tIDENTIFIER
603
+ {
604
+ result = @builder.attr_asgn(val[0], val[1], val[2])
605
+ }
606
+ | primary_value call_op tCONSTANT
607
+ {
608
+ result = @builder.attr_asgn(val[0], val[1], val[2])
609
+ }
610
+ | primary_value tCOLON2 tCONSTANT
611
+ {
612
+ result = @builder.assignable(
613
+ @builder.const_fetch(val[0], val[1], val[2]))
614
+ }
615
+ | tCOLON3 tCONSTANT
616
+ {
617
+ result = @builder.assignable(
618
+ @builder.const_global(val[0], val[1]))
619
+ }
620
+ | backref
621
+ {
622
+ result = @builder.assignable(val[0])
623
+ }
624
+
625
+ cname: tIDENTIFIER
626
+ {
627
+ diagnostic :error, :module_name_const, nil, val[0]
628
+ }
629
+ | tCONSTANT
630
+
631
+ cpath: tCOLON3 cname
632
+ {
633
+ result = @builder.const_global(val[0], val[1])
634
+ }
635
+ | cname
636
+ {
637
+ result = @builder.const(val[0])
638
+ }
639
+ | primary_value tCOLON2 cname
640
+ {
641
+ result = @builder.const_fetch(val[0], val[1], val[2])
642
+ }
643
+
644
+ fname: tIDENTIFIER | tCONSTANT | tFID
645
+ | op
646
+ | reswords
647
+
648
+ fitem: fname
649
+ {
650
+ result = @builder.symbol(val[0])
651
+ }
652
+ | symbol
653
+
654
+ undef_list: fitem
655
+ {
656
+ result = [ val[0] ]
657
+ }
658
+ | undef_list tCOMMA
659
+ {
660
+ @lexer.state = :expr_fname
661
+ }
662
+ fitem
663
+ {
664
+ result = val[0] << val[3]
665
+ }
666
+
667
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
668
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
669
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
670
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
671
+ | tUPLUS | tUMINUS | tAREF | tASET | tDSTAR | tBACK_REF2
672
+
673
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
674
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
675
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
676
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
677
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
678
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
679
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
680
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
681
+ | kUNTIL
682
+
683
+ arg: lhs tEQL arg_rhs
684
+ {
685
+ result = @builder.assign(val[0], val[1], val[2])
686
+ }
687
+ | var_lhs tOP_ASGN arg_rhs
688
+ {
689
+ result = @builder.op_assign(val[0], val[1], val[2])
690
+ }
691
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
692
+ {
693
+ result = @builder.op_assign(
694
+ @builder.index(
695
+ val[0], val[1], val[2], val[3]),
696
+ val[4], val[5])
697
+ }
698
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
699
+ {
700
+ result = @builder.op_assign(
701
+ @builder.call_method(
702
+ val[0], val[1], val[2]),
703
+ val[3], val[4])
704
+ }
705
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
706
+ {
707
+ result = @builder.op_assign(
708
+ @builder.call_method(
709
+ val[0], val[1], val[2]),
710
+ val[3], val[4])
711
+ }
712
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
713
+ {
714
+ result = @builder.op_assign(
715
+ @builder.call_method(
716
+ val[0], val[1], val[2]),
717
+ val[3], val[4])
718
+ }
719
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
720
+ {
721
+ const = @builder.const_op_assignable(
722
+ @builder.const_fetch(val[0], val[1], val[2]))
723
+ result = @builder.op_assign(const, val[3], val[4])
724
+ }
725
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
726
+ {
727
+ const = @builder.const_op_assignable(
728
+ @builder.const_global(val[0], val[1]))
729
+ result = @builder.op_assign(const, val[2], val[3])
730
+ }
731
+ | backref tOP_ASGN arg_rhs
732
+ {
733
+ result = @builder.op_assign(val[0], val[1], val[2])
734
+ }
735
+ | arg tDOT2 arg
736
+ {
737
+ result = @builder.range_inclusive(val[0], val[1], val[2])
738
+ }
739
+ | arg tDOT3 arg
740
+ {
741
+ result = @builder.range_exclusive(val[0], val[1], val[2])
742
+ }
743
+ | arg tDOT2
744
+ {
745
+ result = @builder.range_inclusive(val[0], val[1], nil)
746
+ }
747
+ | arg tDOT3
748
+ {
749
+ result = @builder.range_exclusive(val[0], val[1], nil)
750
+ }
751
+ | tBDOT2 arg
752
+ {
753
+ result = @builder.range_inclusive(nil, val[0], val[1])
754
+ }
755
+ | tBDOT3 arg
756
+ {
757
+ result = @builder.range_exclusive(nil, val[0], val[1])
758
+ }
759
+ | arg tPLUS arg
760
+ {
761
+ result = @builder.binary_op(val[0], val[1], val[2])
762
+ }
763
+ | arg tMINUS arg
764
+ {
765
+ result = @builder.binary_op(val[0], val[1], val[2])
766
+ }
767
+ | arg tSTAR2 arg
768
+ {
769
+ result = @builder.binary_op(val[0], val[1], val[2])
770
+ }
771
+ | arg tDIVIDE arg
772
+ {
773
+ result = @builder.binary_op(val[0], val[1], val[2])
774
+ }
775
+ | arg tPERCENT arg
776
+ {
777
+ result = @builder.binary_op(val[0], val[1], val[2])
778
+ }
779
+ | arg tPOW arg
780
+ {
781
+ result = @builder.binary_op(val[0], val[1], val[2])
782
+ }
783
+ | tUNARY_NUM simple_numeric tPOW arg
784
+ {
785
+ result = @builder.unary_op(val[0],
786
+ @builder.binary_op(
787
+ val[1], val[2], val[3]))
788
+ }
789
+ | tUPLUS arg
790
+ {
791
+ result = @builder.unary_op(val[0], val[1])
792
+ }
793
+ | tUMINUS arg
794
+ {
795
+ result = @builder.unary_op(val[0], val[1])
796
+ }
797
+ | arg tPIPE arg
798
+ {
799
+ result = @builder.binary_op(val[0], val[1], val[2])
800
+ }
801
+ | arg tCARET arg
802
+ {
803
+ result = @builder.binary_op(val[0], val[1], val[2])
804
+ }
805
+ | arg tAMPER2 arg
806
+ {
807
+ result = @builder.binary_op(val[0], val[1], val[2])
808
+ }
809
+ | arg tCMP arg
810
+ {
811
+ result = @builder.binary_op(val[0], val[1], val[2])
812
+ }
813
+ | rel_expr =tCMP
814
+ | arg tEQ arg
815
+ {
816
+ result = @builder.binary_op(val[0], val[1], val[2])
817
+ }
818
+ | arg tEQQ arg
819
+ {
820
+ result = @builder.binary_op(val[0], val[1], val[2])
821
+ }
822
+ | arg tNEQ arg
823
+ {
824
+ result = @builder.binary_op(val[0], val[1], val[2])
825
+ }
826
+ | arg tMATCH arg
827
+ {
828
+ result = @builder.match_op(val[0], val[1], val[2])
829
+ }
830
+ | arg tNMATCH arg
831
+ {
832
+ result = @builder.binary_op(val[0], val[1], val[2])
833
+ }
834
+ | tBANG arg
835
+ {
836
+ result = @builder.not_op(val[0], nil, val[1], nil)
837
+ }
838
+ | tTILDE arg
839
+ {
840
+ result = @builder.unary_op(val[0], val[1])
841
+ }
842
+ | arg tLSHFT arg
843
+ {
844
+ result = @builder.binary_op(val[0], val[1], val[2])
845
+ }
846
+ | arg tRSHFT arg
847
+ {
848
+ result = @builder.binary_op(val[0], val[1], val[2])
849
+ }
850
+ | arg tANDOP arg
851
+ {
852
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
853
+ }
854
+ | arg tOROP arg
855
+ {
856
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
857
+ }
858
+ | kDEFINED opt_nl arg
859
+ {
860
+ result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
861
+ }
862
+ | arg tEH arg opt_nl tCOLON arg
863
+ {
864
+ result = @builder.ternary(val[0], val[1],
865
+ val[2], val[4], val[5])
866
+ }
867
+ | defn_head f_paren_args tEQL arg
868
+ {
869
+ result = @builder.def_endless_method(*val[0],
870
+ val[1], val[2], val[3])
871
+
872
+ @lexer.cmdarg.pop
873
+ @lexer.cond.pop
874
+ @static_env.unextend
875
+ @context.pop
876
+ @current_arg_stack.pop
877
+ }
878
+ | defn_head f_paren_args tEQL arg kRESCUE_MOD arg
879
+ {
880
+ rescue_body = @builder.rescue_body(val[4],
881
+ nil, nil, nil,
882
+ nil, val[5])
883
+
884
+ method_body = @builder.begin_body(val[3], [ rescue_body ])
885
+
886
+ result = @builder.def_endless_method(*val[0],
887
+ val[1], val[2], method_body)
888
+
889
+ @lexer.cmdarg.pop
890
+ @lexer.cond.pop
891
+ @static_env.unextend
892
+ @context.pop
893
+ @current_arg_stack.pop
894
+ }
895
+ | defs_head f_paren_args tEQL arg
896
+ {
897
+ result = @builder.def_endless_singleton(*val[0],
898
+ val[1], val[2], val[3])
899
+
900
+ @lexer.cmdarg.pop
901
+ @lexer.cond.pop
902
+ @static_env.unextend
903
+ @context.pop
904
+ @current_arg_stack.pop
905
+ }
906
+ | defs_head f_paren_args tEQL arg kRESCUE_MOD arg
907
+ {
908
+ rescue_body = @builder.rescue_body(val[4],
909
+ nil, nil, nil,
910
+ nil, val[5])
911
+
912
+ method_body = @builder.begin_body(val[3], [ rescue_body ])
913
+
914
+ result = @builder.def_endless_singleton(*val[0],
915
+ val[1], val[2], method_body)
916
+
917
+ @lexer.cmdarg.pop
918
+ @lexer.cond.pop
919
+ @static_env.unextend
920
+ @context.pop
921
+ @current_arg_stack.pop
922
+ }
923
+ | primary
924
+
925
+ relop: tGT | tLT | tGEQ | tLEQ
926
+
927
+ rel_expr: arg relop arg =tGT
928
+ {
929
+ result = @builder.binary_op(val[0], val[1], val[2])
930
+ }
931
+ | rel_expr relop arg =tGT
932
+ {
933
+ result = @builder.binary_op(val[0], val[1], val[2])
934
+ }
935
+
936
+ arg_value: arg
937
+
938
+ aref_args: none
939
+ | args trailer
940
+ | args tCOMMA assocs trailer
941
+ {
942
+ result = val[0] << @builder.associate(nil, val[2], nil)
943
+ }
944
+ | assocs trailer
945
+ {
946
+ result = [ @builder.associate(nil, val[0], nil) ]
947
+ }
948
+
949
+ arg_rhs: arg =tOP_ASGN
950
+ | arg kRESCUE_MOD arg
951
+ {
952
+ rescue_body = @builder.rescue_body(val[1],
953
+ nil, nil, nil,
954
+ nil, val[2])
955
+
956
+ result = @builder.begin_body(val[0], [ rescue_body ])
957
+ }
958
+
959
+ paren_args: tLPAREN2 opt_call_args rparen
960
+ {
961
+ result = val
962
+ }
963
+ | tLPAREN2 args_forward rparen
964
+ {
965
+ unless @static_env.declared_forward_args?
966
+ diagnostic :error, :unexpected_token, { :token => 'tBDOT3' } , val[1]
967
+ end
968
+
969
+ result = [val[0], [@builder.forwarded_args(val[1])], val[2]]
970
+ }
971
+
972
+ opt_paren_args: # nothing
973
+ {
974
+ result = [ nil, [], nil ]
975
+ }
976
+ | paren_args
977
+
978
+ opt_call_args: # nothing
979
+ {
980
+ result = []
981
+ }
982
+ | call_args
983
+ | args tCOMMA
984
+ | args tCOMMA assocs tCOMMA
985
+ {
986
+ result = val[0] << @builder.associate(nil, val[2], nil)
987
+ }
988
+ | assocs tCOMMA
989
+ {
990
+ result = [ @builder.associate(nil, val[0], nil) ]
991
+ }
992
+
993
+ call_args: command
994
+ {
995
+ result = [ val[0] ]
996
+ }
997
+ | args opt_block_arg
998
+ {
999
+ result = val[0].concat(val[1])
1000
+ }
1001
+ | assocs opt_block_arg
1002
+ {
1003
+ result = [ @builder.associate(nil, val[0], nil) ]
1004
+ result.concat(val[1])
1005
+ }
1006
+ | args tCOMMA assocs opt_block_arg
1007
+ {
1008
+ assocs = @builder.associate(nil, val[2], nil)
1009
+ result = val[0] << assocs
1010
+ result.concat(val[3])
1011
+ }
1012
+ | block_arg
1013
+ {
1014
+ result = [ val[0] ]
1015
+ }
1016
+
1017
+ command_args: {
1018
+ # When branch gets invoked by RACC's lookahead
1019
+ # and command args start with '[' or '('
1020
+ # we need to put `true` to the cmdarg stack
1021
+ # **before** `false` pushed by lexer
1022
+ # m [], n
1023
+ # ^
1024
+ # Right here we have cmdarg [...0] because
1025
+ # lexer pushed it on '['
1026
+ # We need to modify cmdarg stack to [...10]
1027
+ #
1028
+ # For all other cases (like `m n` or `m n, []`) we simply put 1 to the stack
1029
+ # and later lexer pushes corresponding bits on top of it.
1030
+ last_token = @last_token[0]
1031
+ lookahead = last_token == :tLBRACK || last_token == :tLPAREN_ARG
1032
+
1033
+ if lookahead
1034
+ top = @lexer.cmdarg.pop
1035
+ @lexer.cmdarg.push(true)
1036
+ @lexer.cmdarg.push(top)
1037
+ else
1038
+ @lexer.cmdarg.push(true)
1039
+ end
1040
+ }
1041
+ call_args
1042
+ {
1043
+ # call_args can be followed by tLBRACE_ARG (that does cmdarg.push(0) in the lexer)
1044
+ # but the push must be done after cmdarg.pop() in the parser.
1045
+ # So this code does cmdarg.pop() to pop 0 pushed by tLBRACE_ARG,
1046
+ # cmdarg.pop() to pop 1 pushed by command_args,
1047
+ # and cmdarg.push(0) to restore back the flag set by tLBRACE_ARG.
1048
+ last_token = @last_token[0]
1049
+ lookahead = last_token == :tLBRACE_ARG
1050
+ if lookahead
1051
+ top = @lexer.cmdarg.pop
1052
+ @lexer.cmdarg.pop
1053
+ @lexer.cmdarg.push(top)
1054
+ else
1055
+ @lexer.cmdarg.pop
1056
+ end
1057
+
1058
+ result = val[1]
1059
+ }
1060
+
1061
+ block_arg: tAMPER arg_value
1062
+ {
1063
+ result = @builder.block_pass(val[0], val[1])
1064
+ }
1065
+
1066
+ opt_block_arg: tCOMMA block_arg
1067
+ {
1068
+ result = [ val[1] ]
1069
+ }
1070
+ | # nothing
1071
+ {
1072
+ result = []
1073
+ }
1074
+
1075
+ args: arg_value
1076
+ {
1077
+ result = [ val[0] ]
1078
+ }
1079
+ | tSTAR arg_value
1080
+ {
1081
+ result = [ @builder.splat(val[0], val[1]) ]
1082
+ }
1083
+ | args tCOMMA arg_value
1084
+ {
1085
+ result = val[0] << val[2]
1086
+ }
1087
+ | args tCOMMA tSTAR arg_value
1088
+ {
1089
+ result = val[0] << @builder.splat(val[2], val[3])
1090
+ }
1091
+
1092
+ mrhs_arg: mrhs
1093
+ {
1094
+ result = @builder.array(nil, val[0], nil)
1095
+ }
1096
+ | arg_value
1097
+
1098
+ mrhs: args tCOMMA arg_value
1099
+ {
1100
+ result = val[0] << val[2]
1101
+ }
1102
+ | args tCOMMA tSTAR arg_value
1103
+ {
1104
+ result = val[0] << @builder.splat(val[2], val[3])
1105
+ }
1106
+ | tSTAR arg_value
1107
+ {
1108
+ result = [ @builder.splat(val[0], val[1]) ]
1109
+ }
1110
+
1111
+ primary: literal
1112
+ | strings
1113
+ | xstring
1114
+ | regexp
1115
+ | words
1116
+ | qwords
1117
+ | symbols
1118
+ | qsymbols
1119
+ | var_ref
1120
+ | backref
1121
+ | tFID
1122
+ {
1123
+ result = @builder.call_method(nil, nil, val[0])
1124
+ }
1125
+ | kBEGIN
1126
+ {
1127
+ @lexer.cmdarg.push(false)
1128
+ }
1129
+ bodystmt kEND
1130
+ {
1131
+ @lexer.cmdarg.pop
1132
+
1133
+ result = @builder.begin_keyword(val[0], val[2], val[3])
1134
+ }
1135
+ | tLPAREN_ARG stmt
1136
+ {
1137
+ @lexer.state = :expr_endarg
1138
+ }
1139
+ rparen
1140
+ {
1141
+ result = @builder.begin(val[0], val[1], val[3])
1142
+ }
1143
+ | tLPAREN_ARG
1144
+ {
1145
+ @lexer.state = :expr_endarg
1146
+ }
1147
+ opt_nl tRPAREN
1148
+ {
1149
+ result = @builder.begin(val[0], nil, val[3])
1150
+ }
1151
+ | tLPAREN compstmt tRPAREN
1152
+ {
1153
+ result = @builder.begin(val[0], val[1], val[2])
1154
+ }
1155
+ | primary_value tCOLON2 tCONSTANT
1156
+ {
1157
+ result = @builder.const_fetch(val[0], val[1], val[2])
1158
+ }
1159
+ | tCOLON3 tCONSTANT
1160
+ {
1161
+ result = @builder.const_global(val[0], val[1])
1162
+ }
1163
+ | tLBRACK aref_args tRBRACK
1164
+ {
1165
+ result = @builder.array(val[0], val[1], val[2])
1166
+ }
1167
+ | tLBRACE assoc_list tRCURLY
1168
+ {
1169
+ result = @builder.associate(val[0], val[1], val[2])
1170
+ }
1171
+ | k_return
1172
+ {
1173
+ result = @builder.keyword_cmd(:return, val[0])
1174
+ }
1175
+ | kYIELD tLPAREN2 call_args rparen
1176
+ {
1177
+ result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
1178
+ }
1179
+ | kYIELD tLPAREN2 rparen
1180
+ {
1181
+ result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
1182
+ }
1183
+ | kYIELD
1184
+ {
1185
+ result = @builder.keyword_cmd(:yield, val[0])
1186
+ }
1187
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1188
+ {
1189
+ result = @builder.keyword_cmd(:defined?, val[0],
1190
+ val[2], [ val[3] ], val[4])
1191
+ }
1192
+ | kNOT tLPAREN2 expr rparen
1193
+ {
1194
+ result = @builder.not_op(val[0], val[1], val[2], val[3])
1195
+ }
1196
+ | kNOT tLPAREN2 rparen
1197
+ {
1198
+ result = @builder.not_op(val[0], val[1], nil, val[2])
1199
+ }
1200
+ | fcall brace_block
1201
+ {
1202
+ method_call = @builder.call_method(nil, nil, val[0])
1203
+
1204
+ begin_t, args, body, end_t = val[1]
1205
+ result = @builder.block(method_call,
1206
+ begin_t, args, body, end_t)
1207
+ }
1208
+ | method_call
1209
+ | method_call brace_block
1210
+ {
1211
+ begin_t, args, body, end_t = val[1]
1212
+ result = @builder.block(val[0],
1213
+ begin_t, args, body, end_t)
1214
+ }
1215
+ | tLAMBDA lambda
1216
+ {
1217
+ lambda_call = @builder.call_lambda(val[0])
1218
+
1219
+ args, (begin_t, body, end_t) = val[1]
1220
+ result = @builder.block(lambda_call,
1221
+ begin_t, args, body, end_t)
1222
+ }
1223
+ | kIF expr_value then compstmt if_tail kEND
1224
+ {
1225
+ else_t, else_ = val[4]
1226
+ result = @builder.condition(val[0], val[1], val[2],
1227
+ val[3], else_t,
1228
+ else_, val[5])
1229
+ }
1230
+ | kUNLESS expr_value then compstmt opt_else kEND
1231
+ {
1232
+ else_t, else_ = val[4]
1233
+ result = @builder.condition(val[0], val[1], val[2],
1234
+ else_, else_t,
1235
+ val[3], val[5])
1236
+ }
1237
+ | kWHILE expr_value_do compstmt kEND
1238
+ {
1239
+ result = @builder.loop(:while, val[0], *val[1], val[2], val[3])
1240
+ }
1241
+ | kUNTIL expr_value_do compstmt kEND
1242
+ {
1243
+ result = @builder.loop(:until, val[0], *val[1], val[2], val[3])
1244
+ }
1245
+ | kCASE expr_value opt_terms case_body kEND
1246
+ {
1247
+ *when_bodies, (else_t, else_body) = *val[3]
1248
+
1249
+ result = @builder.case(val[0], val[1],
1250
+ when_bodies, else_t, else_body,
1251
+ val[4])
1252
+ }
1253
+ | kCASE opt_terms case_body kEND
1254
+ {
1255
+ *when_bodies, (else_t, else_body) = *val[2]
1256
+
1257
+ result = @builder.case(val[0], nil,
1258
+ when_bodies, else_t, else_body,
1259
+ val[3])
1260
+ }
1261
+ | kCASE expr_value opt_terms p_case_body kEND
1262
+ {
1263
+ *in_bodies, (else_t, else_body) = *val[3]
1264
+
1265
+ result = @builder.case_match(val[0], val[1],
1266
+ in_bodies, else_t, else_body,
1267
+ val[4])
1268
+ }
1269
+ | kFOR for_var kIN expr_value_do compstmt kEND
1270
+ {
1271
+ result = @builder.for(val[0], val[1], val[2], *val[3], val[4], val[5])
1272
+ }
1273
+ | kCLASS cpath superclass
1274
+ {
1275
+ @static_env.extend_static
1276
+ @lexer.cmdarg.push(false)
1277
+ @lexer.cond.push(false)
1278
+ @context.push(:class)
1279
+ }
1280
+ bodystmt kEND
1281
+ {
1282
+ unless @context.class_definition_allowed?
1283
+ diagnostic :error, :class_in_def, nil, val[0]
1284
+ end
1285
+
1286
+ lt_t, superclass = val[2]
1287
+ result = @builder.def_class(val[0], val[1],
1288
+ lt_t, superclass,
1289
+ val[4], val[5])
1290
+
1291
+ @lexer.cmdarg.pop
1292
+ @lexer.cond.pop
1293
+ @static_env.unextend
1294
+ @context.pop
1295
+ }
1296
+ | kCLASS tLSHFT expr term
1297
+ {
1298
+ @static_env.extend_static
1299
+ @lexer.cmdarg.push(false)
1300
+ @lexer.cond.push(false)
1301
+ @context.push(:sclass)
1302
+ }
1303
+ bodystmt kEND
1304
+ {
1305
+ result = @builder.def_sclass(val[0], val[1], val[2],
1306
+ val[5], val[6])
1307
+
1308
+ @lexer.cmdarg.pop
1309
+ @lexer.cond.pop
1310
+ @static_env.unextend
1311
+ @context.pop
1312
+ }
1313
+ | kMODULE cpath
1314
+ {
1315
+ @static_env.extend_static
1316
+ @lexer.cmdarg.push(false)
1317
+ }
1318
+ bodystmt kEND
1319
+ {
1320
+ unless @context.module_definition_allowed?
1321
+ diagnostic :error, :module_in_def, nil, val[0]
1322
+ end
1323
+
1324
+ result = @builder.def_module(val[0], val[1],
1325
+ val[3], val[4])
1326
+
1327
+ @lexer.cmdarg.pop
1328
+ @static_env.unextend
1329
+ }
1330
+ | defn_head f_arglist bodystmt kEND
1331
+ {
1332
+ result = @builder.def_method(*val[0], val[1],
1333
+ val[2], val[3])
1334
+
1335
+ @lexer.cmdarg.pop
1336
+ @lexer.cond.pop
1337
+ @static_env.unextend
1338
+ @context.pop
1339
+ @current_arg_stack.pop
1340
+ }
1341
+ | defs_head f_arglist bodystmt kEND
1342
+ {
1343
+ result = @builder.def_singleton(*val[0], val[1],
1344
+ val[2], val[3])
1345
+
1346
+ @lexer.cmdarg.pop
1347
+ @lexer.cond.pop
1348
+ @static_env.unextend
1349
+ @context.pop
1350
+ @current_arg_stack.pop
1351
+ }
1352
+ | kBREAK
1353
+ {
1354
+ result = @builder.keyword_cmd(:break, val[0])
1355
+ }
1356
+ | kNEXT
1357
+ {
1358
+ result = @builder.keyword_cmd(:next, val[0])
1359
+ }
1360
+ | kREDO
1361
+ {
1362
+ result = @builder.keyword_cmd(:redo, val[0])
1363
+ }
1364
+ | kRETRY
1365
+ {
1366
+ result = @builder.keyword_cmd(:retry, val[0])
1367
+ }
1368
+
1369
+ primary_value: primary
1370
+
1371
+ k_return: kRETURN
1372
+ {
1373
+ if @context.in_class?
1374
+ diagnostic :error, :invalid_return, nil, val[0]
1375
+ end
1376
+ }
1377
+
1378
+ then: term
1379
+ | kTHEN
1380
+ | term kTHEN
1381
+ {
1382
+ result = val[1]
1383
+ }
1384
+
1385
+ do: term
1386
+ | kDO_COND
1387
+
1388
+ if_tail: opt_else
1389
+ | kELSIF expr_value then compstmt if_tail
1390
+ {
1391
+ else_t, else_ = val[4]
1392
+ result = [ val[0],
1393
+ @builder.condition(val[0], val[1], val[2],
1394
+ val[3], else_t,
1395
+ else_, nil),
1396
+ ]
1397
+ }
1398
+
1399
+ opt_else: none
1400
+ | kELSE compstmt
1401
+ {
1402
+ result = val
1403
+ }
1404
+
1405
+ for_var: lhs
1406
+ | mlhs
1407
+
1408
+ f_marg: f_norm_arg
1409
+ {
1410
+ result = @builder.arg(val[0])
1411
+ }
1412
+ | tLPAREN f_margs rparen
1413
+ {
1414
+ result = @builder.multi_lhs(val[0], val[1], val[2])
1415
+ }
1416
+
1417
+ f_marg_list: f_marg
1418
+ {
1419
+ result = [ val[0] ]
1420
+ }
1421
+ | f_marg_list tCOMMA f_marg
1422
+ {
1423
+ result = val[0] << val[2]
1424
+ }
1425
+
1426
+ f_margs: f_marg_list
1427
+ | f_marg_list tCOMMA f_rest_marg
1428
+ {
1429
+ result = val[0].
1430
+ push(val[2])
1431
+ }
1432
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1433
+ {
1434
+ result = val[0].
1435
+ push(val[2]).
1436
+ concat(val[4])
1437
+ }
1438
+ | f_rest_marg
1439
+ {
1440
+ result = [ val[0] ]
1441
+ }
1442
+ | f_rest_marg tCOMMA f_marg_list
1443
+ {
1444
+ result = [ val[0], *val[2] ]
1445
+ }
1446
+
1447
+ f_rest_marg: tSTAR f_norm_arg
1448
+ {
1449
+ result = @builder.restarg(val[0], val[1])
1450
+ }
1451
+ | tSTAR
1452
+ {
1453
+ result = @builder.restarg(val[0])
1454
+ }
1455
+
1456
+ f_any_kwrest: f_kwrest
1457
+ | f_no_kwarg
1458
+
1459
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1460
+ {
1461
+ result = val[0].concat(val[2]).concat(val[3])
1462
+ }
1463
+ | f_block_kwarg opt_f_block_arg
1464
+ {
1465
+ result = val[0].concat(val[1])
1466
+ }
1467
+ | f_any_kwrest opt_f_block_arg
1468
+ {
1469
+ result = val[0].concat(val[1])
1470
+ }
1471
+ | f_block_arg
1472
+ {
1473
+ result = [ val[0] ]
1474
+ }
1475
+
1476
+ opt_block_args_tail:
1477
+ tCOMMA block_args_tail
1478
+ {
1479
+ result = val[1]
1480
+ }
1481
+ | # nothing
1482
+ {
1483
+ result = []
1484
+ }
1485
+
1486
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1487
+ {
1488
+ result = val[0].
1489
+ concat(val[2]).
1490
+ concat(val[4]).
1491
+ concat(val[5])
1492
+ }
1493
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1494
+ {
1495
+ result = val[0].
1496
+ concat(val[2]).
1497
+ concat(val[4]).
1498
+ concat(val[6]).
1499
+ concat(val[7])
1500
+ }
1501
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1502
+ {
1503
+ result = val[0].
1504
+ concat(val[2]).
1505
+ concat(val[3])
1506
+ }
1507
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1508
+ {
1509
+ result = val[0].
1510
+ concat(val[2]).
1511
+ concat(val[4]).
1512
+ concat(val[5])
1513
+ }
1514
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1515
+ {
1516
+ result = val[0].
1517
+ concat(val[2]).
1518
+ concat(val[3])
1519
+ }
1520
+ | f_arg tCOMMA
1521
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1522
+ {
1523
+ result = val[0].
1524
+ concat(val[2]).
1525
+ concat(val[4]).
1526
+ concat(val[5])
1527
+ }
1528
+ | f_arg opt_block_args_tail
1529
+ {
1530
+ if val[1].empty? && val[0].size == 1
1531
+ result = [@builder.procarg0(val[0][0])]
1532
+ else
1533
+ result = val[0].concat(val[1])
1534
+ end
1535
+ }
1536
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1537
+ {
1538
+ result = val[0].
1539
+ concat(val[2]).
1540
+ concat(val[3])
1541
+ }
1542
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1543
+ {
1544
+ result = val[0].
1545
+ concat(val[2]).
1546
+ concat(val[4]).
1547
+ concat(val[5])
1548
+ }
1549
+ | f_block_optarg opt_block_args_tail
1550
+ {
1551
+ result = val[0].
1552
+ concat(val[1])
1553
+ }
1554
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1555
+ {
1556
+ result = val[0].
1557
+ concat(val[2]).
1558
+ concat(val[3])
1559
+ }
1560
+ | f_rest_arg opt_block_args_tail
1561
+ {
1562
+ result = val[0].
1563
+ concat(val[1])
1564
+ }
1565
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1566
+ {
1567
+ result = val[0].
1568
+ concat(val[2]).
1569
+ concat(val[3])
1570
+ }
1571
+ | block_args_tail
1572
+
1573
+ opt_block_param: # nothing
1574
+ {
1575
+ result = @builder.args(nil, [], nil)
1576
+ }
1577
+ | block_param_def
1578
+ {
1579
+ @lexer.state = :expr_value
1580
+ }
1581
+
1582
+ block_param_def: tPIPE opt_bv_decl tPIPE
1583
+ {
1584
+ @max_numparam_stack.has_ordinary_params!
1585
+ @current_arg_stack.set(nil)
1586
+ result = @builder.args(val[0], val[1], val[2])
1587
+ }
1588
+ | tPIPE block_param opt_bv_decl tPIPE
1589
+ {
1590
+ @max_numparam_stack.has_ordinary_params!
1591
+ @current_arg_stack.set(nil)
1592
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
1593
+ }
1594
+
1595
+ opt_bv_decl: opt_nl
1596
+ {
1597
+ result = []
1598
+ }
1599
+ | opt_nl tSEMI bv_decls opt_nl
1600
+ {
1601
+ result = val[2]
1602
+ }
1603
+
1604
+ bv_decls: bvar
1605
+ {
1606
+ result = [ val[0] ]
1607
+ }
1608
+ | bv_decls tCOMMA bvar
1609
+ {
1610
+ result = val[0] << val[2]
1611
+ }
1612
+
1613
+ bvar: tIDENTIFIER
1614
+ {
1615
+ @static_env.declare val[0][0]
1616
+ result = @builder.shadowarg(val[0])
1617
+ }
1618
+ | f_bad_arg
1619
+
1620
+ lambda: {
1621
+ @static_env.extend_dynamic
1622
+ @max_numparam_stack.push
1623
+ @context.push(:lambda)
1624
+ }
1625
+ f_larglist
1626
+ {
1627
+ @context.pop
1628
+ @lexer.cmdarg.push(false)
1629
+ }
1630
+ lambda_body
1631
+ {
1632
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
1633
+ result = [ args, val[3] ]
1634
+
1635
+ @max_numparam_stack.pop
1636
+ @static_env.unextend
1637
+ @lexer.cmdarg.pop
1638
+ }
1639
+
1640
+ f_larglist: tLPAREN2 f_args opt_bv_decl tRPAREN
1641
+ {
1642
+ @max_numparam_stack.has_ordinary_params!
1643
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
1644
+ }
1645
+ | f_args
1646
+ {
1647
+ if val[0].any?
1648
+ @max_numparam_stack.has_ordinary_params!
1649
+ end
1650
+ result = @builder.args(nil, val[0], nil)
1651
+ }
1652
+
1653
+ lambda_body: tLAMBEG
1654
+ {
1655
+ @context.push(:lambda)
1656
+ }
1657
+ compstmt tRCURLY
1658
+ {
1659
+ result = [ val[0], val[2], val[3] ]
1660
+ @context.pop
1661
+ }
1662
+ | kDO_LAMBDA
1663
+ {
1664
+ @context.push(:lambda)
1665
+ }
1666
+ bodystmt kEND
1667
+ {
1668
+ result = [ val[0], val[2], val[3] ]
1669
+ @context.pop
1670
+ }
1671
+
1672
+ do_block: kDO_BLOCK
1673
+ {
1674
+ @context.push(:block)
1675
+ }
1676
+ do_body kEND
1677
+ {
1678
+ result = [ val[0], *val[2], val[3] ]
1679
+ @context.pop
1680
+ }
1681
+
1682
+ block_call: command do_block
1683
+ {
1684
+ begin_t, block_args, body, end_t = val[1]
1685
+ result = @builder.block(val[0],
1686
+ begin_t, block_args, body, end_t)
1687
+ }
1688
+ | block_call dot_or_colon operation2 opt_paren_args
1689
+ {
1690
+ lparen_t, args, rparen_t = val[3]
1691
+ result = @builder.call_method(val[0], val[1], val[2],
1692
+ lparen_t, args, rparen_t)
1693
+ }
1694
+ | block_call dot_or_colon operation2 opt_paren_args brace_block
1695
+ {
1696
+ lparen_t, args, rparen_t = val[3]
1697
+ method_call = @builder.call_method(val[0], val[1], val[2],
1698
+ lparen_t, args, rparen_t)
1699
+
1700
+ begin_t, args, body, end_t = val[4]
1701
+ result = @builder.block(method_call,
1702
+ begin_t, args, body, end_t)
1703
+ }
1704
+ | block_call dot_or_colon operation2 command_args do_block
1705
+ {
1706
+ method_call = @builder.call_method(val[0], val[1], val[2],
1707
+ nil, val[3], nil)
1708
+
1709
+ begin_t, args, body, end_t = val[4]
1710
+ result = @builder.block(method_call,
1711
+ begin_t, args, body, end_t)
1712
+ }
1713
+
1714
+ method_call: fcall paren_args
1715
+ {
1716
+ lparen_t, args, rparen_t = val[1]
1717
+ result = @builder.call_method(nil, nil, val[0],
1718
+ lparen_t, args, rparen_t)
1719
+ }
1720
+ | primary_value call_op operation2 opt_paren_args
1721
+ {
1722
+ lparen_t, args, rparen_t = val[3]
1723
+ result = @builder.call_method(val[0], val[1], val[2],
1724
+ lparen_t, args, rparen_t)
1725
+ }
1726
+ | primary_value tCOLON2 operation2 paren_args
1727
+ {
1728
+ lparen_t, args, rparen_t = val[3]
1729
+ result = @builder.call_method(val[0], val[1], val[2],
1730
+ lparen_t, args, rparen_t)
1731
+ }
1732
+ | primary_value tCOLON2 operation3
1733
+ {
1734
+ result = @builder.call_method(val[0], val[1], val[2])
1735
+ }
1736
+ | primary_value call_op paren_args
1737
+ {
1738
+ lparen_t, args, rparen_t = val[2]
1739
+ result = @builder.call_method(val[0], val[1], nil,
1740
+ lparen_t, args, rparen_t)
1741
+ }
1742
+ | primary_value tCOLON2 paren_args
1743
+ {
1744
+ lparen_t, args, rparen_t = val[2]
1745
+ result = @builder.call_method(val[0], val[1], nil,
1746
+ lparen_t, args, rparen_t)
1747
+ }
1748
+ | kSUPER paren_args
1749
+ {
1750
+ lparen_t, args, rparen_t = val[1]
1751
+ result = @builder.keyword_cmd(:super, val[0],
1752
+ lparen_t, args, rparen_t)
1753
+ }
1754
+ | kSUPER
1755
+ {
1756
+ result = @builder.keyword_cmd(:zsuper, val[0])
1757
+ }
1758
+ | primary_value tLBRACK2 opt_call_args rbracket
1759
+ {
1760
+ result = @builder.index(val[0], val[1], val[2], val[3])
1761
+ }
1762
+
1763
+ brace_block: tLCURLY
1764
+ {
1765
+ @context.push(:block)
1766
+ }
1767
+ brace_body tRCURLY
1768
+ {
1769
+ result = [ val[0], *val[2], val[3] ]
1770
+ @context.pop
1771
+ }
1772
+ | kDO
1773
+ {
1774
+ @context.push(:block)
1775
+ }
1776
+ do_body kEND
1777
+ {
1778
+ result = [ val[0], *val[2], val[3] ]
1779
+ @context.pop
1780
+ }
1781
+
1782
+ brace_body: {
1783
+ @static_env.extend_dynamic
1784
+ @max_numparam_stack.push
1785
+ }
1786
+ opt_block_param compstmt
1787
+ {
1788
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[1]
1789
+ result = [ args, val[2] ]
1790
+
1791
+ @max_numparam_stack.pop
1792
+ @static_env.unextend
1793
+ }
1794
+
1795
+ do_body: {
1796
+ @static_env.extend_dynamic
1797
+ @max_numparam_stack.push
1798
+ }
1799
+ {
1800
+ @lexer.cmdarg.push(false)
1801
+ }
1802
+ opt_block_param bodystmt
1803
+ {
1804
+ args = @max_numparam_stack.has_numparams? ? @builder.numargs(@max_numparam_stack.top) : val[2]
1805
+ result = [ args, val[3] ]
1806
+
1807
+ @max_numparam_stack.pop
1808
+ @static_env.unextend
1809
+ @lexer.cmdarg.pop
1810
+ }
1811
+
1812
+ case_body: kWHEN args then compstmt cases
1813
+ {
1814
+ result = [ @builder.when(val[0], val[1], val[2], val[3]),
1815
+ *val[4] ]
1816
+ }
1817
+
1818
+ cases: opt_else
1819
+ {
1820
+ result = [ val[0] ]
1821
+ }
1822
+ | case_body
1823
+
1824
+ p_case_body: kIN
1825
+ {
1826
+ @lexer.state = :expr_beg
1827
+ @lexer.command_start = false
1828
+ @pattern_variables.push
1829
+ @pattern_hash_keys.push
1830
+
1831
+ result = @lexer.in_kwarg
1832
+ @lexer.in_kwarg = true
1833
+ }
1834
+ p_top_expr then
1835
+ {
1836
+ @lexer.in_kwarg = val[1]
1837
+ }
1838
+ compstmt p_cases
1839
+ {
1840
+ result = [ @builder.in_pattern(val[0], *val[2], val[3], val[5]),
1841
+ *val[6] ]
1842
+ }
1843
+
1844
+ p_cases: opt_else
1845
+ {
1846
+ result = [ val[0] ]
1847
+ }
1848
+ | p_case_body
1849
+
1850
+ p_top_expr: p_top_expr_body
1851
+ {
1852
+ result = [ val[0], nil ]
1853
+ }
1854
+ | p_top_expr_body kIF_MOD expr_value
1855
+ {
1856
+ result = [ val[0], @builder.if_guard(val[1], val[2]) ]
1857
+ }
1858
+ | p_top_expr_body kUNLESS_MOD expr_value
1859
+ {
1860
+ result = [ val[0], @builder.unless_guard(val[1], val[2]) ]
1861
+ }
1862
+
1863
+ p_top_expr_body: p_expr
1864
+ | p_expr tCOMMA
1865
+ {
1866
+ # array patterns that end with comma
1867
+ # like 1, 2,
1868
+ # must be emitted as `array_pattern_with_tail`
1869
+ item = @builder.match_with_trailing_comma(val[0], val[1])
1870
+ result = @builder.array_pattern(nil, [ item ], nil)
1871
+ }
1872
+ | p_expr tCOMMA p_args
1873
+ {
1874
+ result = @builder.array_pattern(nil, [val[0]].concat(val[2]), nil)
1875
+ }
1876
+ | p_args_tail
1877
+ {
1878
+ result = @builder.array_pattern(nil, val[0], nil)
1879
+ }
1880
+ | p_kwargs
1881
+ {
1882
+ result = @builder.hash_pattern(nil, val[0], nil)
1883
+ }
1884
+
1885
+ p_expr: p_as
1886
+
1887
+ p_as: p_expr tASSOC p_variable
1888
+ {
1889
+ result = @builder.match_as(val[0], val[1], val[2])
1890
+ }
1891
+ | p_alt
1892
+
1893
+ p_alt: p_alt tPIPE p_expr_basic
1894
+ {
1895
+ result = @builder.match_alt(val[0], val[1], val[2])
1896
+ }
1897
+ | p_expr_basic
1898
+
1899
+ p_lparen: tLPAREN2
1900
+ {
1901
+ result = val[0]
1902
+ @pattern_hash_keys.push
1903
+ }
1904
+
1905
+ p_lbracket: tLBRACK2
1906
+ {
1907
+ result = val[0]
1908
+ @pattern_hash_keys.push
1909
+ }
1910
+
1911
+ p_expr_basic: p_value
1912
+ | p_const p_lparen p_args rparen
1913
+ {
1914
+ @pattern_hash_keys.pop
1915
+ pattern = @builder.array_pattern(nil, val[2], nil)
1916
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1917
+ }
1918
+ | p_const p_lparen p_kwargs rparen
1919
+ {
1920
+ @pattern_hash_keys.pop
1921
+ pattern = @builder.hash_pattern(nil, val[2], nil)
1922
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1923
+ }
1924
+ | p_const tLPAREN2 rparen
1925
+ {
1926
+ pattern = @builder.array_pattern(val[1], nil, val[2])
1927
+ result = @builder.const_pattern(val[0], val[1], pattern, val[2])
1928
+ }
1929
+ | p_const p_lbracket p_args rbracket
1930
+ {
1931
+ @pattern_hash_keys.pop
1932
+ pattern = @builder.array_pattern(nil, val[2], nil)
1933
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1934
+ }
1935
+ | p_const p_lbracket p_kwargs rbracket
1936
+ {
1937
+ @pattern_hash_keys.pop
1938
+ pattern = @builder.hash_pattern(nil, val[2], nil)
1939
+ result = @builder.const_pattern(val[0], val[1], pattern, val[3])
1940
+ }
1941
+ | p_const tLBRACK2 rbracket
1942
+ {
1943
+ pattern = @builder.array_pattern(val[1], nil, val[2])
1944
+ result = @builder.const_pattern(val[0], val[1], pattern, val[2])
1945
+ }
1946
+ | tLBRACK
1947
+ {
1948
+ @pattern_hash_keys.push
1949
+ }
1950
+ p_args rbracket
1951
+ {
1952
+ @pattern_hash_keys.pop
1953
+ result = @builder.array_pattern(val[0], val[2], val[3])
1954
+ }
1955
+ | tLBRACK rbracket
1956
+ {
1957
+ result = @builder.array_pattern(val[0], [], val[1])
1958
+ }
1959
+ | tLBRACE
1960
+ {
1961
+ @pattern_hash_keys.push
1962
+ result = @lexer.in_kwarg
1963
+ @lexer.in_kwarg = false
1964
+ }
1965
+ p_kwargs rbrace
1966
+ {
1967
+ @pattern_hash_keys.pop
1968
+ @lexer.in_kwarg = val[1]
1969
+ result = @builder.hash_pattern(val[0], val[2], val[3])
1970
+ }
1971
+ | tLBRACE rbrace
1972
+ {
1973
+ result = @builder.hash_pattern(val[0], [], val[1])
1974
+ }
1975
+ | tLPAREN
1976
+ {
1977
+ @pattern_hash_keys.push
1978
+ }
1979
+ p_expr rparen
1980
+ {
1981
+ @pattern_hash_keys.pop
1982
+ result = @builder.begin(val[0], val[2], val[3])
1983
+ }
1984
+
1985
+ p_args: p_expr
1986
+ {
1987
+ result = [ val[0] ]
1988
+ }
1989
+ | p_args_head
1990
+ {
1991
+ result = val[0]
1992
+ }
1993
+ | p_args_head p_arg
1994
+ {
1995
+ result = [ *val[0], val[1] ]
1996
+ }
1997
+ | p_args_head tSTAR tIDENTIFIER
1998
+ {
1999
+ match_rest = @builder.match_rest(val[1], val[2])
2000
+ result = [ *val[0], match_rest ]
2001
+ }
2002
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2003
+ {
2004
+ match_rest = @builder.match_rest(val[1], val[2])
2005
+ result = [ *val[0], match_rest, *val[4] ]
2006
+ }
2007
+ | p_args_head tSTAR
2008
+ {
2009
+ result = [ *val[0], @builder.match_rest(val[1]) ]
2010
+ }
2011
+ | p_args_head tSTAR tCOMMA p_args_post
2012
+ {
2013
+ result = [ *val[0], @builder.match_rest(val[1]), *val[3] ]
2014
+ }
2015
+ | p_args_tail
2016
+
2017
+ p_args_head: p_arg tCOMMA
2018
+ {
2019
+ # array patterns that end with comma
2020
+ # like [1, 2,]
2021
+ # must be emitted as `array_pattern_with_tail`
2022
+ item = @builder.match_with_trailing_comma(val[0], val[1])
2023
+ result = [ item ]
2024
+ }
2025
+ | p_args_head p_arg tCOMMA
2026
+ {
2027
+ # array patterns that end with comma
2028
+ # like [1, 2,]
2029
+ # must be emitted as `array_pattern_with_tail`
2030
+ last_item = @builder.match_with_trailing_comma(val[1], val[2])
2031
+ result = [ *val[0], last_item ]
2032
+ }
2033
+
2034
+ p_args_tail: tSTAR tIDENTIFIER
2035
+ {
2036
+ match_rest = @builder.match_rest(val[0], val[1])
2037
+ result = [ match_rest ]
2038
+ }
2039
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2040
+ {
2041
+ match_rest = @builder.match_rest(val[0], val[1])
2042
+ result = [ match_rest, *val[3] ]
2043
+ }
2044
+ | tSTAR
2045
+ {
2046
+ match_rest = @builder.match_rest(val[0])
2047
+ result = [ match_rest ]
2048
+ }
2049
+ | tSTAR tCOMMA p_args_post
2050
+ {
2051
+ match_rest = @builder.match_rest(val[0])
2052
+ result = [ match_rest, *val[2] ]
2053
+ }
2054
+
2055
+ p_args_post: p_arg
2056
+ {
2057
+ result = [ val[0] ]
2058
+ }
2059
+ | p_args_post tCOMMA p_arg
2060
+ {
2061
+ result = [ *val[0], val[2] ]
2062
+ }
2063
+
2064
+ p_arg: p_expr
2065
+
2066
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2067
+ {
2068
+ result = [ *val[0], *val[2] ]
2069
+ }
2070
+ | p_kwarg
2071
+ {
2072
+ result = val[0]
2073
+ }
2074
+ | p_kwarg tCOMMA
2075
+ {
2076
+ result = val[0]
2077
+ }
2078
+ | p_any_kwrest
2079
+ {
2080
+ result = val[0]
2081
+ }
2082
+
2083
+ p_kwarg: p_kw
2084
+ {
2085
+ result = [ val[0] ]
2086
+ }
2087
+ | p_kwarg tCOMMA p_kw
2088
+ {
2089
+ result = [ *val[0], val[2] ]
2090
+ }
2091
+
2092
+ p_kw: p_kw_label p_expr
2093
+ {
2094
+ result = @builder.match_pair(*val[0], val[1])
2095
+ }
2096
+ | p_kw_label
2097
+ {
2098
+ result = @builder.match_label(*val[0])
2099
+ }
2100
+
2101
+ p_kw_label: tLABEL
2102
+ {
2103
+ check_kwarg_name(val[0])
2104
+ result = [:label, val[0]]
2105
+ }
2106
+ | tSTRING_BEG string_contents tLABEL_END
2107
+ {
2108
+ result = [:quoted, [val[0], val[1], val[2]]]
2109
+ }
2110
+
2111
+ p_kwrest: kwrest_mark tIDENTIFIER
2112
+ {
2113
+ result = [ @builder.match_rest(val[0], val[1]) ]
2114
+ }
2115
+ | kwrest_mark
2116
+ {
2117
+ result = [ @builder.match_rest(val[0], nil) ]
2118
+ }
2119
+
2120
+ p_kwnorest: kwrest_mark kNIL
2121
+ {
2122
+ result = [ @builder.match_nil_pattern(val[0], val[1]) ]
2123
+ }
2124
+
2125
+ p_any_kwrest: p_kwrest
2126
+ | p_kwnorest
2127
+
2128
+ p_value: p_primitive
2129
+ | p_primitive tDOT2 p_primitive
2130
+ {
2131
+ result = @builder.range_inclusive(val[0], val[1], val[2])
2132
+ }
2133
+ | p_primitive tDOT3 p_primitive
2134
+ {
2135
+ result = @builder.range_exclusive(val[0], val[1], val[2])
2136
+ }
2137
+ | p_primitive tDOT2
2138
+ {
2139
+ result = @builder.range_inclusive(val[0], val[1], nil)
2140
+ }
2141
+ | p_primitive tDOT3
2142
+ {
2143
+ result = @builder.range_exclusive(val[0], val[1], nil)
2144
+ }
2145
+ | p_variable
2146
+ | p_var_ref
2147
+ | p_const
2148
+ | tBDOT2 p_primitive
2149
+ {
2150
+ result = @builder.range_inclusive(nil, val[0], val[1])
2151
+ }
2152
+ | tBDOT3 p_primitive
2153
+ {
2154
+ result = @builder.range_exclusive(nil, val[0], val[1])
2155
+ }
2156
+
2157
+ p_primitive: literal
2158
+ | strings
2159
+ | xstring
2160
+ | regexp
2161
+ | words
2162
+ | qwords
2163
+ | symbols
2164
+ | qsymbols
2165
+ | keyword_variable
2166
+ {
2167
+ result = @builder.accessible(val[0])
2168
+ }
2169
+ | tLAMBDA lambda
2170
+ {
2171
+ lambda_call = @builder.call_lambda(val[0])
2172
+
2173
+ args, (begin_t, body, end_t) = val[1]
2174
+ result = @builder.block(lambda_call,
2175
+ begin_t, args, body, end_t)
2176
+ }
2177
+
2178
+ p_variable: tIDENTIFIER
2179
+ {
2180
+ result = @builder.match_var(val[0])
2181
+ }
2182
+
2183
+ p_var_ref: tCARET tIDENTIFIER
2184
+ {
2185
+ name = val[1][0]
2186
+ unless static_env.declared?(name)
2187
+ diagnostic :error, :undefined_lvar, { :name => name }, val[1]
2188
+ end
2189
+
2190
+ lvar = @builder.accessible(@builder.ident(val[1]))
2191
+ result = @builder.pin(val[0], lvar)
2192
+ }
2193
+
2194
+ p_const: tCOLON3 cname
2195
+ {
2196
+ result = @builder.const_global(val[0], val[1])
2197
+ }
2198
+ | p_const tCOLON2 cname
2199
+ {
2200
+ result = @builder.const_fetch(val[0], val[1], val[2])
2201
+ }
2202
+ | tCONSTANT
2203
+ {
2204
+ result = @builder.const(val[0])
2205
+ }
2206
+
2207
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
2208
+ {
2209
+ assoc_t, exc_var = val[2]
2210
+
2211
+ if val[1]
2212
+ exc_list = @builder.array(nil, val[1], nil)
2213
+ end
2214
+
2215
+ result = [ @builder.rescue_body(val[0],
2216
+ exc_list, assoc_t, exc_var,
2217
+ val[3], val[4]),
2218
+ *val[5] ]
2219
+ }
2220
+ |
2221
+ {
2222
+ result = []
2223
+ }
2224
+
2225
+ exc_list: arg_value
2226
+ {
2227
+ result = [ val[0] ]
2228
+ }
2229
+ | mrhs
2230
+ | none
2231
+
2232
+ exc_var: tASSOC lhs
2233
+ {
2234
+ result = [ val[0], val[1] ]
2235
+ }
2236
+ | none
2237
+
2238
+ opt_ensure: kENSURE compstmt
2239
+ {
2240
+ result = [ val[0], val[1] ]
2241
+ }
2242
+ | none
2243
+
2244
+ literal: numeric
2245
+ | symbol
2246
+
2247
+ strings: string
2248
+ {
2249
+ result = @builder.string_compose(nil, val[0], nil)
2250
+ }
2251
+
2252
+ string: string1
2253
+ {
2254
+ result = [ val[0] ]
2255
+ }
2256
+ | string string1
2257
+ {
2258
+ result = val[0] << val[1]
2259
+ }
2260
+
2261
+ string1: tSTRING_BEG string_contents tSTRING_END
2262
+ {
2263
+ string = @builder.string_compose(val[0], val[1], val[2])
2264
+ result = @builder.dedent_string(string, @lexer.dedent_level)
2265
+ }
2266
+ | tSTRING
2267
+ {
2268
+ string = @builder.string(val[0])
2269
+ result = @builder.dedent_string(string, @lexer.dedent_level)
2270
+ }
2271
+ | tCHARACTER
2272
+ {
2273
+ result = @builder.character(val[0])
2274
+ }
2275
+
2276
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2277
+ {
2278
+ string = @builder.xstring_compose(val[0], val[1], val[2])
2279
+ result = @builder.dedent_string(string, @lexer.dedent_level)
2280
+ }
2281
+
2282
+ regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
2283
+ {
2284
+ opts = @builder.regexp_options(val[3])
2285
+ result = @builder.regexp_compose(val[0], val[1], val[2], opts)
2286
+ }
2287
+
2288
+ words: tWORDS_BEG word_list tSTRING_END
2289
+ {
2290
+ result = @builder.words_compose(val[0], val[1], val[2])
2291
+ }
2292
+
2293
+ word_list: # nothing
2294
+ {
2295
+ result = []
2296
+ }
2297
+ | word_list word tSPACE
2298
+ {
2299
+ result = val[0] << @builder.word(val[1])
2300
+ }
2301
+
2302
+ word: string_content
2303
+ {
2304
+ result = [ val[0] ]
2305
+ }
2306
+ | word string_content
2307
+ {
2308
+ result = val[0] << val[1]
2309
+ }
2310
+
2311
+ symbols: tSYMBOLS_BEG symbol_list tSTRING_END
2312
+ {
2313
+ result = @builder.symbols_compose(val[0], val[1], val[2])
2314
+ }
2315
+
2316
+ symbol_list: # nothing
2317
+ {
2318
+ result = []
2319
+ }
2320
+ | symbol_list word tSPACE
2321
+ {
2322
+ result = val[0] << @builder.word(val[1])
2323
+ }
2324
+
2325
+ qwords: tQWORDS_BEG qword_list tSTRING_END
2326
+ {
2327
+ result = @builder.words_compose(val[0], val[1], val[2])
2328
+ }
2329
+
2330
+ qsymbols: tQSYMBOLS_BEG qsym_list tSTRING_END
2331
+ {
2332
+ result = @builder.symbols_compose(val[0], val[1], val[2])
2333
+ }
2334
+
2335
+ qword_list: # nothing
2336
+ {
2337
+ result = []
2338
+ }
2339
+ | qword_list tSTRING_CONTENT tSPACE
2340
+ {
2341
+ result = val[0] << @builder.string_internal(val[1])
2342
+ }
2343
+
2344
+ qsym_list: # nothing
2345
+ {
2346
+ result = []
2347
+ }
2348
+ | qsym_list tSTRING_CONTENT tSPACE
2349
+ {
2350
+ result = val[0] << @builder.symbol_internal(val[1])
2351
+ }
2352
+
2353
+ string_contents: # nothing
2354
+ {
2355
+ result = []
2356
+ }
2357
+ | string_contents string_content
2358
+ {
2359
+ result = val[0] << val[1]
2360
+ }
2361
+
2362
+ xstring_contents: # nothing
2363
+ {
2364
+ result = []
2365
+ }
2366
+ | xstring_contents string_content
2367
+ {
2368
+ result = val[0] << val[1]
2369
+ }
2370
+
2371
+ regexp_contents: # nothing
2372
+ {
2373
+ result = []
2374
+ }
2375
+ | regexp_contents string_content
2376
+ {
2377
+ result = val[0] << val[1]
2378
+ }
2379
+
2380
+ string_content: tSTRING_CONTENT
2381
+ {
2382
+ result = @builder.string_internal(val[0])
2383
+ }
2384
+ | tSTRING_DVAR string_dvar
2385
+ {
2386
+ result = val[1]
2387
+ }
2388
+ | tSTRING_DBEG
2389
+ {
2390
+ @lexer.cmdarg.push(false)
2391
+ @lexer.cond.push(false)
2392
+ }
2393
+ compstmt tSTRING_DEND
2394
+ {
2395
+ @lexer.cmdarg.pop
2396
+ @lexer.cond.pop
2397
+
2398
+ result = @builder.begin(val[0], val[2], val[3])
2399
+ }
2400
+
2401
+ string_dvar: tGVAR
2402
+ {
2403
+ result = @builder.gvar(val[0])
2404
+ }
2405
+ | tIVAR
2406
+ {
2407
+ result = @builder.ivar(val[0])
2408
+ }
2409
+ | tCVAR
2410
+ {
2411
+ result = @builder.cvar(val[0])
2412
+ }
2413
+ | backref
2414
+
2415
+ symbol: ssym
2416
+ | dsym
2417
+
2418
+ ssym: tSYMBOL
2419
+ {
2420
+ @lexer.state = :expr_end
2421
+ result = @builder.symbol(val[0])
2422
+ }
2423
+
2424
+ dsym: tSYMBEG string_contents tSTRING_END
2425
+ {
2426
+ @lexer.state = :expr_end
2427
+ result = @builder.symbol_compose(val[0], val[1], val[2])
2428
+ }
2429
+
2430
+ numeric: simple_numeric
2431
+ {
2432
+ result = val[0]
2433
+ }
2434
+ | tUNARY_NUM simple_numeric =tLOWEST
2435
+ {
2436
+ if @builder.respond_to? :negate
2437
+ # AST builder interface compatibility
2438
+ result = @builder.negate(val[0], val[1])
2439
+ else
2440
+ result = @builder.unary_num(val[0], val[1])
2441
+ end
2442
+ }
2443
+
2444
+ simple_numeric: tINTEGER
2445
+ {
2446
+ @lexer.state = :expr_end
2447
+ result = @builder.integer(val[0])
2448
+ }
2449
+ | tFLOAT
2450
+ {
2451
+ @lexer.state = :expr_end
2452
+ result = @builder.float(val[0])
2453
+ }
2454
+ | tRATIONAL
2455
+ {
2456
+ @lexer.state = :expr_end
2457
+ result = @builder.rational(val[0])
2458
+ }
2459
+ | tIMAGINARY
2460
+ {
2461
+ @lexer.state = :expr_end
2462
+ result = @builder.complex(val[0])
2463
+ }
2464
+
2465
+ user_variable: tIDENTIFIER
2466
+ {
2467
+ result = @builder.ident(val[0])
2468
+ }
2469
+ | tIVAR
2470
+ {
2471
+ result = @builder.ivar(val[0])
2472
+ }
2473
+ | tGVAR
2474
+ {
2475
+ result = @builder.gvar(val[0])
2476
+ }
2477
+ | tCONSTANT
2478
+ {
2479
+ result = @builder.const(val[0])
2480
+ }
2481
+ | tCVAR
2482
+ {
2483
+ result = @builder.cvar(val[0])
2484
+ }
2485
+
2486
+ keyword_variable: kNIL
2487
+ {
2488
+ result = @builder.nil(val[0])
2489
+ }
2490
+ | kSELF
2491
+ {
2492
+ result = @builder.self(val[0])
2493
+ }
2494
+ | kTRUE
2495
+ {
2496
+ result = @builder.true(val[0])
2497
+ }
2498
+ | kFALSE
2499
+ {
2500
+ result = @builder.false(val[0])
2501
+ }
2502
+ | k__FILE__
2503
+ {
2504
+ result = @builder.__FILE__(val[0])
2505
+ }
2506
+ | k__LINE__
2507
+ {
2508
+ result = @builder.__LINE__(val[0])
2509
+ }
2510
+ | k__ENCODING__
2511
+ {
2512
+ result = @builder.__ENCODING__(val[0])
2513
+ }
2514
+
2515
+ var_ref: user_variable
2516
+ {
2517
+ if (node = val[0]) && node.type == :ident
2518
+ name = node.children[0]
2519
+
2520
+ if name =~ /\A_[1-9]\z/ && !static_env.declared?(name) && context.in_dynamic_block?
2521
+ # definitely an implicit param
2522
+ location = node.loc.expression
2523
+
2524
+ if max_numparam_stack.has_ordinary_params?
2525
+ diagnostic :error, :ordinary_param_defined, nil, [nil, location]
2526
+ end
2527
+
2528
+ raw_context = context.stack.dup
2529
+ raw_max_numparam_stack = max_numparam_stack.stack.dup
2530
+
2531
+ # ignore current block scope
2532
+ raw_context.pop
2533
+ raw_max_numparam_stack.pop
2534
+
2535
+ raw_context.reverse_each do |outer_scope|
2536
+ if outer_scope == :block || outer_scope == :lambda
2537
+ outer_scope_has_numparams = raw_max_numparam_stack.pop > 0
2538
+
2539
+ if outer_scope_has_numparams
2540
+ diagnostic :error, :numparam_used_in_outer_scope, nil, [nil, location]
2541
+ else
2542
+ # for now it's ok, but an outer scope can also be a block
2543
+ # with numparams, so we need to continue
2544
+ end
2545
+ else
2546
+ # found an outer scope that can't have numparams
2547
+ # like def/class/etc
2548
+ break
2549
+ end
2550
+ end
2551
+
2552
+ static_env.declare(name)
2553
+ max_numparam_stack.register(name[1].to_i)
2554
+ end
2555
+ end
2556
+
2557
+ result = @builder.accessible(val[0])
2558
+ }
2559
+ | keyword_variable
2560
+ {
2561
+ result = @builder.accessible(val[0])
2562
+ }
2563
+
2564
+ var_lhs: user_variable
2565
+ {
2566
+ result = @builder.assignable(val[0])
2567
+ }
2568
+ | keyword_variable
2569
+ {
2570
+ result = @builder.assignable(val[0])
2571
+ }
2572
+
2573
+ backref: tNTH_REF
2574
+ {
2575
+ result = @builder.nth_ref(val[0])
2576
+ }
2577
+ | tBACK_REF
2578
+ {
2579
+ result = @builder.back_ref(val[0])
2580
+ }
2581
+
2582
+ superclass: tLT
2583
+ {
2584
+ @lexer.state = :expr_value
2585
+ }
2586
+ expr_value term
2587
+ {
2588
+ result = [ val[0], val[2] ]
2589
+ }
2590
+ | # nothing
2591
+ {
2592
+ result = nil
2593
+ }
2594
+
2595
+ f_paren_args: tLPAREN2 f_args rparen
2596
+ {
2597
+ result = @builder.args(val[0], val[1], val[2])
2598
+
2599
+ @lexer.state = :expr_value
2600
+ }
2601
+ | tLPAREN2 args_forward rparen
2602
+ {
2603
+ result = @builder.forward_args(val[0], val[1], val[2])
2604
+ @static_env.declare_forward_args
2605
+
2606
+ @lexer.state = :expr_value
2607
+ }
2608
+
2609
+ f_arglist: f_paren_args
2610
+ | {
2611
+ result = @lexer.in_kwarg
2612
+ @lexer.in_kwarg = true
2613
+ }
2614
+ f_args term
2615
+ {
2616
+ @lexer.in_kwarg = val[0]
2617
+ result = @builder.args(nil, val[1], nil)
2618
+ }
2619
+
2620
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2621
+ {
2622
+ result = val[0].concat(val[2]).concat(val[3])
2623
+ }
2624
+ | f_kwarg opt_f_block_arg
2625
+ {
2626
+ result = val[0].concat(val[1])
2627
+ }
2628
+ | f_any_kwrest opt_f_block_arg
2629
+ {
2630
+ result = val[0].concat(val[1])
2631
+ }
2632
+ | f_block_arg
2633
+ {
2634
+ result = [ val[0] ]
2635
+ }
2636
+
2637
+ opt_args_tail: tCOMMA args_tail
2638
+ {
2639
+ result = val[1]
2640
+ }
2641
+ | # nothing
2642
+ {
2643
+ result = []
2644
+ }
2645
+
2646
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2647
+ {
2648
+ result = val[0].
2649
+ concat(val[2]).
2650
+ concat(val[4]).
2651
+ concat(val[5])
2652
+ }
2653
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2654
+ {
2655
+ result = val[0].
2656
+ concat(val[2]).
2657
+ concat(val[4]).
2658
+ concat(val[6]).
2659
+ concat(val[7])
2660
+ }
2661
+ | f_arg tCOMMA f_optarg opt_args_tail
2662
+ {
2663
+ result = val[0].
2664
+ concat(val[2]).
2665
+ concat(val[3])
2666
+ }
2667
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2668
+ {
2669
+ result = val[0].
2670
+ concat(val[2]).
2671
+ concat(val[4]).
2672
+ concat(val[5])
2673
+ }
2674
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2675
+ {
2676
+ result = val[0].
2677
+ concat(val[2]).
2678
+ concat(val[3])
2679
+ }
2680
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2681
+ {
2682
+ result = val[0].
2683
+ concat(val[2]).
2684
+ concat(val[4]).
2685
+ concat(val[5])
2686
+ }
2687
+ | f_arg opt_args_tail
2688
+ {
2689
+ result = val[0].
2690
+ concat(val[1])
2691
+ }
2692
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2693
+ {
2694
+ result = val[0].
2695
+ concat(val[2]).
2696
+ concat(val[3])
2697
+ }
2698
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2699
+ {
2700
+ result = val[0].
2701
+ concat(val[2]).
2702
+ concat(val[4]).
2703
+ concat(val[5])
2704
+ }
2705
+ | f_optarg opt_args_tail
2706
+ {
2707
+ result = val[0].
2708
+ concat(val[1])
2709
+ }
2710
+ | f_optarg tCOMMA f_arg opt_args_tail
2711
+ {
2712
+ result = val[0].
2713
+ concat(val[2]).
2714
+ concat(val[3])
2715
+ }
2716
+ | f_rest_arg opt_args_tail
2717
+ {
2718
+ result = val[0].
2719
+ concat(val[1])
2720
+ }
2721
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2722
+ {
2723
+ result = val[0].
2724
+ concat(val[2]).
2725
+ concat(val[3])
2726
+ }
2727
+ | args_tail
2728
+ {
2729
+ result = val[0]
2730
+ }
2731
+ | # nothing
2732
+ {
2733
+ result = []
2734
+ }
2735
+
2736
+ args_forward: tBDOT3
2737
+ {
2738
+ result = val[0]
2739
+ }
2740
+
2741
+ f_bad_arg: tCONSTANT
2742
+ {
2743
+ diagnostic :error, :argument_const, nil, val[0]
2744
+ }
2745
+ | tIVAR
2746
+ {
2747
+ diagnostic :error, :argument_ivar, nil, val[0]
2748
+ }
2749
+ | tGVAR
2750
+ {
2751
+ diagnostic :error, :argument_gvar, nil, val[0]
2752
+ }
2753
+ | tCVAR
2754
+ {
2755
+ diagnostic :error, :argument_cvar, nil, val[0]
2756
+ }
2757
+
2758
+ f_norm_arg: f_bad_arg
2759
+ | tIDENTIFIER
2760
+ {
2761
+ @static_env.declare val[0][0]
2762
+
2763
+ @max_numparam_stack.has_ordinary_params!
2764
+
2765
+ result = val[0]
2766
+ }
2767
+
2768
+ f_arg_asgn: f_norm_arg
2769
+ {
2770
+ @current_arg_stack.set(val[0][0])
2771
+ result = val[0]
2772
+ }
2773
+
2774
+ f_arg_item: f_arg_asgn
2775
+ {
2776
+ @current_arg_stack.set(0)
2777
+ result = @builder.arg(val[0])
2778
+ }
2779
+ | tLPAREN f_margs rparen
2780
+ {
2781
+ result = @builder.multi_lhs(val[0], val[1], val[2])
2782
+ }
2783
+
2784
+ f_arg: f_arg_item
2785
+ {
2786
+ result = [ val[0] ]
2787
+ }
2788
+ | f_arg tCOMMA f_arg_item
2789
+ {
2790
+ result = val[0] << val[2]
2791
+ }
2792
+
2793
+ f_label: tLABEL
2794
+ {
2795
+ check_kwarg_name(val[0])
2796
+
2797
+ @static_env.declare val[0][0]
2798
+
2799
+ @max_numparam_stack.has_ordinary_params!
2800
+
2801
+ @current_arg_stack.set(val[0][0])
2802
+
2803
+ result = val[0]
2804
+ }
2805
+
2806
+ f_kw: f_label arg_value
2807
+ {
2808
+ @current_arg_stack.set(nil)
2809
+ result = @builder.kwoptarg(val[0], val[1])
2810
+ }
2811
+ | f_label
2812
+ {
2813
+ @current_arg_stack.set(nil)
2814
+ result = @builder.kwarg(val[0])
2815
+ }
2816
+
2817
+ f_block_kw: f_label primary_value
2818
+ {
2819
+ result = @builder.kwoptarg(val[0], val[1])
2820
+ }
2821
+ | f_label
2822
+ {
2823
+ result = @builder.kwarg(val[0])
2824
+ }
2825
+
2826
+ f_block_kwarg: f_block_kw
2827
+ {
2828
+ result = [ val[0] ]
2829
+ }
2830
+ | f_block_kwarg tCOMMA f_block_kw
2831
+ {
2832
+ result = val[0] << val[2]
2833
+ }
2834
+
2835
+ f_kwarg: f_kw
2836
+ {
2837
+ result = [ val[0] ]
2838
+ }
2839
+ | f_kwarg tCOMMA f_kw
2840
+ {
2841
+ result = val[0] << val[2]
2842
+ }
2843
+
2844
+ kwrest_mark: tPOW | tDSTAR
2845
+
2846
+ f_no_kwarg: kwrest_mark kNIL
2847
+ {
2848
+ result = [ @builder.kwnilarg(val[0], val[1]) ]
2849
+ }
2850
+
2851
+ f_kwrest: kwrest_mark tIDENTIFIER
2852
+ {
2853
+ @static_env.declare val[1][0]
2854
+
2855
+ result = [ @builder.kwrestarg(val[0], val[1]) ]
2856
+ }
2857
+ | kwrest_mark
2858
+ {
2859
+ result = [ @builder.kwrestarg(val[0]) ]
2860
+ }
2861
+
2862
+ f_opt: f_arg_asgn tEQL arg_value
2863
+ {
2864
+ @current_arg_stack.set(0)
2865
+ result = @builder.optarg(val[0], val[1], val[2])
2866
+ }
2867
+
2868
+ f_block_opt: f_arg_asgn tEQL primary_value
2869
+ {
2870
+ @current_arg_stack.set(0)
2871
+ result = @builder.optarg(val[0], val[1], val[2])
2872
+ }
2873
+
2874
+ f_block_optarg: f_block_opt
2875
+ {
2876
+ result = [ val[0] ]
2877
+ }
2878
+ | f_block_optarg tCOMMA f_block_opt
2879
+ {
2880
+ result = val[0] << val[2]
2881
+ }
2882
+
2883
+ f_optarg: f_opt
2884
+ {
2885
+ result = [ val[0] ]
2886
+ }
2887
+ | f_optarg tCOMMA f_opt
2888
+ {
2889
+ result = val[0] << val[2]
2890
+ }
2891
+
2892
+ restarg_mark: tSTAR2 | tSTAR
2893
+
2894
+ f_rest_arg: restarg_mark tIDENTIFIER
2895
+ {
2896
+ @static_env.declare val[1][0]
2897
+
2898
+ result = [ @builder.restarg(val[0], val[1]) ]
2899
+ }
2900
+ | restarg_mark
2901
+ {
2902
+ result = [ @builder.restarg(val[0]) ]
2903
+ }
2904
+
2905
+ blkarg_mark: tAMPER2 | tAMPER
2906
+
2907
+ f_block_arg: blkarg_mark tIDENTIFIER
2908
+ {
2909
+ @static_env.declare val[1][0]
2910
+
2911
+ result = @builder.blockarg(val[0], val[1])
2912
+ }
2913
+
2914
+ opt_f_block_arg: tCOMMA f_block_arg
2915
+ {
2916
+ result = [ val[1] ]
2917
+ }
2918
+ |
2919
+ {
2920
+ result = []
2921
+ }
2922
+
2923
+ singleton: var_ref
2924
+ | tLPAREN2 expr rparen
2925
+ {
2926
+ result = val[1]
2927
+ }
2928
+
2929
+ assoc_list: # nothing
2930
+ {
2931
+ result = []
2932
+ }
2933
+ | assocs trailer
2934
+
2935
+ assocs: assoc
2936
+ {
2937
+ result = [ val[0] ]
2938
+ }
2939
+ | assocs tCOMMA assoc
2940
+ {
2941
+ result = val[0] << val[2]
2942
+ }
2943
+
2944
+ assoc: arg_value tASSOC arg_value
2945
+ {
2946
+ result = @builder.pair(val[0], val[1], val[2])
2947
+ }
2948
+ | tLABEL arg_value
2949
+ {
2950
+ result = @builder.pair_keyword(val[0], val[1])
2951
+ }
2952
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2953
+ {
2954
+ result = @builder.pair_quoted(val[0], val[1], val[2], val[3])
2955
+ }
2956
+ | tDSTAR arg_value
2957
+ {
2958
+ result = @builder.kwsplat(val[0], val[1])
2959
+ }
2960
+
2961
+ operation: tIDENTIFIER | tCONSTANT | tFID
2962
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2963
+ operation3: tIDENTIFIER | tFID | op
2964
+ dot_or_colon: call_op | tCOLON2
2965
+ call_op: tDOT
2966
+ {
2967
+ result = [:dot, val[0][1]]
2968
+ }
2969
+ | tANDDOT
2970
+ {
2971
+ result = [:anddot, val[0][1]]
2972
+ }
2973
+ opt_terms: | terms
2974
+ opt_nl: | tNL
2975
+ rparen: opt_nl tRPAREN
2976
+ {
2977
+ result = val[1]
2978
+ }
2979
+ rbracket: opt_nl tRBRACK
2980
+ {
2981
+ result = val[1]
2982
+ }
2983
+ rbrace: opt_nl tRCURLY
2984
+ {
2985
+ result = val[1]
2986
+ }
2987
+ trailer: | tNL | tCOMMA
2988
+
2989
+ term: tSEMI
2990
+ {
2991
+ yyerrok
2992
+ }
2993
+ | tNL
2994
+
2995
+ terms: term
2996
+ | terms tSEMI
2997
+
2998
+ none: # nothing
2999
+ {
3000
+ result = nil
3001
+ }
3002
+ end
3003
+
3004
+ ---- header
3005
+
3006
+ require 'parser'
3007
+
3008
+ ---- inner
3009
+
3010
+ def version
3011
+ 28
3012
+ end
3013
+
3014
+ def default_encoding
3015
+ Encoding::UTF_8
3016
+ end