brakeman 4.1.1 → 4.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES.md +13 -0
  3. data/bundle/load.rb +3 -3
  4. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/History.rdoc +7 -0
  5. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/Manifest.txt +0 -0
  6. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/README.rdoc +0 -0
  7. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/Rakefile +0 -0
  8. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/bin/r2r_show +0 -0
  9. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/lib/ruby2ruby.rb +43 -2
  10. data/bundle/ruby/2.3.0/gems/{ruby2ruby-2.4.0 → ruby2ruby-2.4.1}/test/test_ruby2ruby.rb +5 -4
  11. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/History.rdoc +12 -0
  12. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/Manifest.txt +2 -0
  13. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/README.rdoc +5 -1
  14. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/Rakefile +1 -1
  15. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/bin/ruby_parse +0 -0
  16. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/bin/ruby_parse_extract_error +0 -0
  17. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/compare/normalize.rb +0 -0
  18. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/rp_extensions.rb +0 -0
  19. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/rp_stringscanner.rb +0 -0
  20. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby18_parser.rb +0 -0
  21. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby18_parser.y +0 -0
  22. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby19_parser.rb +1751 -1745
  23. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby19_parser.y +2 -2
  24. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby20_parser.rb +1717 -1717
  25. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby20_parser.y +2 -2
  26. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby21_parser.rb +1824 -1819
  27. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby21_parser.y +2 -2
  28. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby22_parser.rb +1838 -1846
  29. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby22_parser.y +2 -2
  30. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby23_parser.rb +1836 -1837
  31. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby23_parser.y +2 -2
  32. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby24_parser.rb +1836 -1837
  33. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby24_parser.y +2 -2
  34. data/bundle/ruby/2.3.0/gems/ruby_parser-3.11.0/lib/ruby25_parser.rb +6818 -0
  35. data/bundle/ruby/2.3.0/gems/ruby_parser-3.11.0/lib/ruby25_parser.y +2378 -0
  36. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_lexer.rb +8 -2
  37. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_lexer.rex +0 -0
  38. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_lexer.rex.rb +0 -0
  39. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_parser.rb +2 -0
  40. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_parser.yy +4 -2
  41. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/lib/ruby_parser_extras.rb +2 -7
  42. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/test/test_ruby_lexer.rb +22 -0
  43. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/test/test_ruby_parser.rb +39 -0
  44. data/bundle/ruby/2.3.0/gems/{ruby_parser-3.10.1 → ruby_parser-3.11.0}/test/test_ruby_parser_extras.rb +0 -0
  45. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0/History.txt → sexp_processor-4.10.1/History.rdoc} +6 -0
  46. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/Manifest.txt +2 -2
  47. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0/README.txt → sexp_processor-4.10.1/README.rdoc} +0 -0
  48. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/Rakefile +1 -0
  49. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/composite_sexp_processor.rb +0 -0
  50. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/pt_testcase.rb +16 -9
  51. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/sexp.rb +1 -2
  52. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/sexp_processor.rb +1 -1
  53. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/strict_sexp.rb +0 -0
  54. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/lib/unique.rb +0 -0
  55. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/test/test_composite_sexp_processor.rb +0 -0
  56. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/test/test_environment.rb +0 -0
  57. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/test/test_sexp.rb +0 -0
  58. data/bundle/ruby/2.3.0/gems/{sexp_processor-4.10.0 → sexp_processor-4.10.1}/test/test_sexp_processor.rb +0 -0
  59. data/lib/brakeman/app_tree.rb +1 -1
  60. data/lib/brakeman/checks/base_check.rb +2 -6
  61. data/lib/brakeman/checks/check_execute.rb +21 -3
  62. data/lib/brakeman/checks/check_redirect.rb +3 -1
  63. data/lib/brakeman/checks/check_sql.rb +2 -2
  64. data/lib/brakeman/checks/check_symbol_dos.rb +8 -0
  65. data/lib/brakeman/checks/check_unscoped_find.rb +17 -1
  66. data/lib/brakeman/processors/alias_processor.rb +5 -2
  67. data/lib/brakeman/processors/base_processor.rb +1 -5
  68. data/lib/brakeman/processors/erb_template_processor.rb +1 -1
  69. data/lib/brakeman/processors/library_processor.rb +9 -1
  70. data/lib/brakeman/version.rb +1 -1
  71. data/lib/ruby_parser/bm_sexp.rb +4 -0
  72. metadata +58 -56
@@ -0,0 +1,2378 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby25Parser
4
+
5
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
6
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
7
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
8
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
9
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
10
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
11
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
12
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
13
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
14
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
15
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
16
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
17
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
18
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
22
+ tRATIONAL tIMAGINARY
23
+ tLABEL_END
24
+ tLONELY
25
+
26
+ prechigh
27
+ right tBANG tTILDE tUPLUS
28
+ right tPOW
29
+ right tUMINUS_NUM tUMINUS
30
+ left tSTAR2 tDIVIDE tPERCENT
31
+ left tPLUS tMINUS
32
+ left tLSHFT tRSHFT
33
+ left tAMPER2
34
+ left tPIPE tCARET
35
+ left tGT tGEQ tLT tLEQ
36
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
37
+ left tANDOP
38
+ left tOROP
39
+ nonassoc tDOT2 tDOT3
40
+ right tEH tCOLON
41
+ left kRESCUE_MOD
42
+ right tEQL tOP_ASGN
43
+ nonassoc kDEFINED
44
+ right kNOT
45
+ left kOR kAND
46
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
47
+ nonassoc tLBRACE_ARG
48
+ nonassoc tLOWEST
49
+ preclow
50
+
51
+ rule
52
+
53
+ program: {
54
+ self.lexer.lex_state = :expr_beg
55
+ }
56
+ top_compstmt
57
+ {
58
+ result = new_compstmt val
59
+ }
60
+
61
+ top_compstmt: top_stmts opt_terms
62
+ {
63
+ result = val[0]
64
+ }
65
+
66
+ top_stmts: none
67
+ | top_stmt
68
+ | top_stmts terms top_stmt
69
+ {
70
+ result = self.block_append val[0], val[2]
71
+ }
72
+ | error top_stmt
73
+
74
+ top_stmt: stmt
75
+ {
76
+ result = val[0]
77
+
78
+ # TODO: remove once I have more confidence this is fixed
79
+ # result.each_of_type :call_args do |s|
80
+ # debug20 666, s, result
81
+ # end
82
+ }
83
+ | klBEGIN
84
+ {
85
+ if (self.in_def || self.in_single > 0) then
86
+ debug20 1
87
+ yyerror "BEGIN in method"
88
+ end
89
+ self.env.extend
90
+ }
91
+ tLCURLY top_compstmt tRCURLY
92
+ {
93
+ result = new_iter s(:preexe), nil, val[3]
94
+ }
95
+
96
+ bodystmt: compstmt opt_rescue opt_else opt_ensure
97
+ {
98
+ result = new_body val
99
+ }
100
+
101
+ compstmt: stmts opt_terms
102
+ {
103
+ result = new_compstmt val
104
+ }
105
+
106
+ stmts: none
107
+ | stmt
108
+ | stmts terms stmt
109
+ {
110
+ result = self.block_append val[0], val[2]
111
+ }
112
+ | error stmt
113
+ {
114
+ result = val[1]
115
+ debug20 2, val, result
116
+ }
117
+
118
+ stmt: kALIAS fitem
119
+ {
120
+ lexer.lex_state = :expr_fname
121
+ result = self.lexer.lineno
122
+ }
123
+ fitem
124
+ {
125
+ result = s(:alias, val[1], val[3]).line(val[2])
126
+ }
127
+ | kALIAS tGVAR tGVAR
128
+ {
129
+ result = s(:valias, val[1].to_sym, val[2].to_sym)
130
+ }
131
+ | kALIAS tGVAR tBACK_REF
132
+ {
133
+ result = s(:valias, val[1].to_sym, :"$#{val[2]}")
134
+ }
135
+ | kALIAS tGVAR tNTH_REF
136
+ {
137
+ yyerror "can't make alias for the number variables"
138
+ }
139
+ | kUNDEF undef_list
140
+ {
141
+ result = val[1]
142
+ }
143
+ | stmt kIF_MOD expr_value
144
+ {
145
+ result = new_if val[2], val[0], nil
146
+ }
147
+ | stmt kUNLESS_MOD expr_value
148
+ {
149
+ result = new_if val[2], nil, val[0]
150
+ }
151
+ | stmt kWHILE_MOD expr_value
152
+ {
153
+ result = new_while val[0], val[2], true
154
+ }
155
+ | stmt kUNTIL_MOD expr_value
156
+ {
157
+ result = new_until val[0], val[2], true
158
+ }
159
+ | stmt kRESCUE_MOD stmt
160
+ {
161
+ result = s(:rescue, val[0], new_resbody(s(:array), val[2]))
162
+ }
163
+ | klEND tLCURLY compstmt tRCURLY
164
+ {
165
+ if (self.in_def || self.in_single > 0) then
166
+ debug20 3
167
+ yyerror "END in method; use at_exit"
168
+ end
169
+ result = new_iter s(:postexe), 0, val[2]
170
+ }
171
+ | command_asgn
172
+ | mlhs tEQL command_call
173
+ {
174
+ result = new_masgn val[0], val[2], :wrap
175
+ }
176
+ | var_lhs tOP_ASGN command_call
177
+ {
178
+ result = new_op_asgn val
179
+ }
180
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
181
+ {
182
+ result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
183
+ }
184
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_call
185
+ {
186
+ result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
187
+ if val[1] == '&.'
188
+ result.sexp_type = :safe_op_asgn
189
+ end
190
+ result.line = val[0].line
191
+ }
192
+ | primary_value call_op tCONSTANT tOP_ASGN command_call
193
+ {
194
+ result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
195
+ if val[1] == '&.'
196
+ result.sexp_type = :safe_op_asgn
197
+ end
198
+ result.line = val[0].line
199
+ }
200
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
201
+ {
202
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
203
+ debug20 4, val, result
204
+ }
205
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
206
+ {
207
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
208
+ debug20 5, val, result
209
+ }
210
+ | backref tOP_ASGN command_call
211
+ {
212
+ self.backref_assign_error val[0]
213
+ }
214
+ | lhs tEQL mrhs
215
+ {
216
+ result = new_assign val[0], s(:svalue, val[2])
217
+ }
218
+ | mlhs tEQL mrhs_arg
219
+ {
220
+ result = new_masgn val[0], val[2]
221
+ }
222
+ | expr
223
+
224
+ command_asgn: lhs tEQL command_call
225
+ {
226
+ result = new_assign val[0], val[2]
227
+ }
228
+ | lhs tEQL command_asgn
229
+ {
230
+ result = new_assign val[0], val[2]
231
+ }
232
+
233
+ expr: command_call
234
+ | expr kAND expr
235
+ {
236
+ result = logical_op :and, val[0], val[2]
237
+ }
238
+ | expr kOR expr
239
+ {
240
+ result = logical_op :or, val[0], val[2]
241
+ }
242
+ | kNOT opt_nl expr
243
+ {
244
+ result = s(:call, val[2], :"!")
245
+ }
246
+ | tBANG command_call
247
+ {
248
+ result = s(:call, val[1], :"!")
249
+ }
250
+ | arg
251
+
252
+ expr_value: expr
253
+ {
254
+ result = value_expr(val[0])
255
+ }
256
+
257
+ command_call: command
258
+ | block_command
259
+
260
+ block_command: block_call
261
+ | block_call dot_or_colon operation2 command_args
262
+ {
263
+ result = new_call val[0], val[2].to_sym, val[3]
264
+ }
265
+
266
+ cmd_brace_block: tLBRACE_ARG
267
+ {
268
+ self.env.extend(:dynamic)
269
+ result = self.lexer.lineno
270
+ }
271
+ opt_block_param
272
+ {
273
+ result = nil # self.env.dynamic.keys
274
+ }
275
+ compstmt tRCURLY
276
+ {
277
+ result = new_iter nil, val[2], val[4]
278
+ result.line = val[1]
279
+
280
+ self.env.unextend
281
+ }
282
+
283
+ fcall: operation
284
+ {
285
+ result = new_call nil, val[0].to_sym
286
+ }
287
+
288
+ command: fcall command_args =tLOWEST
289
+ {
290
+ result = val[0].concat val[1].sexp_body # REFACTOR pattern
291
+ }
292
+ | fcall command_args cmd_brace_block
293
+ {
294
+ result = val[0].concat val[1].sexp_body
295
+ if val[2] then
296
+ block_dup_check result, val[2]
297
+
298
+ result, operation = val[2], result
299
+ result.insert 1, operation
300
+ end
301
+ }
302
+ | primary_value call_op operation2 command_args =tLOWEST
303
+ {
304
+ result = new_call val[0], val[2].to_sym, val[3], val[1]
305
+ }
306
+ | primary_value call_op operation2 command_args cmd_brace_block
307
+ {
308
+ recv, _, msg, args, block = val
309
+ call = new_call recv, msg.to_sym, args, val[1]
310
+
311
+ block_dup_check call, block
312
+
313
+ block.insert 1, call
314
+ result = block
315
+ }
316
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
317
+ {
318
+ result = new_call val[0], val[2].to_sym, val[3]
319
+ }
320
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
321
+ {
322
+ recv, _, msg, args, block = val
323
+ call = new_call recv, msg.to_sym, args
324
+
325
+ block_dup_check call, block
326
+
327
+ block.insert 1, call
328
+ result = block
329
+ }
330
+ | kSUPER command_args
331
+ {
332
+ result = new_super val[1]
333
+ }
334
+ | kYIELD command_args
335
+ {
336
+ result = new_yield val[1]
337
+ }
338
+ | kRETURN call_args
339
+ {
340
+ line = val[0].last
341
+ result = s(:return, ret_args(val[1])).line(line)
342
+ }
343
+ | kBREAK call_args
344
+ {
345
+ line = val[0].last
346
+ result = s(:break, ret_args(val[1])).line(line)
347
+ }
348
+ | kNEXT call_args
349
+ {
350
+ line = val[0].last
351
+ result = s(:next, ret_args(val[1])).line(line)
352
+ }
353
+
354
+ mlhs: mlhs_basic
355
+ | tLPAREN mlhs_inner rparen
356
+ {
357
+ result = val[1]
358
+ }
359
+
360
+ mlhs_inner: mlhs_basic
361
+ | tLPAREN mlhs_inner rparen
362
+ {
363
+ result = s(:masgn, s(:array, val[1]))
364
+ }
365
+
366
+ mlhs_basic: mlhs_head
367
+ {
368
+ result = s(:masgn, val[0])
369
+ }
370
+ | mlhs_head mlhs_item
371
+ {
372
+ result = s(:masgn, val[0] << val[1].compact)
373
+ }
374
+ | mlhs_head tSTAR mlhs_node
375
+ {
376
+ result = s(:masgn, val[0] << s(:splat, val[2]))
377
+ }
378
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
379
+ {
380
+ ary1, _, splat, _, ary2 = val
381
+
382
+ result = list_append ary1, s(:splat, splat)
383
+ result.concat ary2.sexp_body
384
+ result = s(:masgn, result)
385
+ }
386
+ | mlhs_head tSTAR
387
+ {
388
+ result = s(:masgn, val[0] << s(:splat))
389
+ }
390
+ | mlhs_head tSTAR tCOMMA mlhs_post
391
+ {
392
+ ary = list_append val[0], s(:splat)
393
+ ary.concat val[3].sexp_body
394
+ result = s(:masgn, ary)
395
+ }
396
+ | tSTAR mlhs_node
397
+ {
398
+ result = s(:masgn, s(:array, s(:splat, val[1])))
399
+ }
400
+ | tSTAR mlhs_node tCOMMA mlhs_post
401
+ {
402
+ ary = s(:array, s(:splat, val[1]))
403
+ ary.concat val[3].sexp_body
404
+ result = s(:masgn, ary)
405
+ }
406
+ | tSTAR
407
+ {
408
+ result = s(:masgn, s(:array, s(:splat)))
409
+ }
410
+ | tSTAR tCOMMA mlhs_post
411
+ {
412
+ result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
413
+ }
414
+
415
+ mlhs_item: mlhs_node
416
+ | tLPAREN mlhs_inner rparen
417
+ {
418
+ result = val[1]
419
+ }
420
+
421
+ mlhs_head: mlhs_item tCOMMA
422
+ {
423
+ result = s(:array, val[0])
424
+ }
425
+ | mlhs_head mlhs_item tCOMMA
426
+ {
427
+ result = val[0] << val[1].compact
428
+ }
429
+
430
+ mlhs_post: mlhs_item
431
+ {
432
+ result = s(:array, val[0])
433
+ }
434
+ | mlhs_post tCOMMA mlhs_item
435
+ {
436
+ result = list_append val[0], val[2]
437
+ }
438
+
439
+ mlhs_node: user_variable
440
+ {
441
+ result = self.assignable val[0]
442
+ }
443
+ | keyword_variable
444
+ {
445
+ result = self.assignable val[0]
446
+ }
447
+ | primary_value tLBRACK2 opt_call_args rbracket
448
+ {
449
+ result = self.aryset val[0], val[2]
450
+ }
451
+ | primary_value call_op tIDENTIFIER
452
+ {
453
+ result = new_attrasgn val[0], val[2], val[1]
454
+ }
455
+ | primary_value tCOLON2 tIDENTIFIER
456
+ {
457
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
458
+ }
459
+ | primary_value call_op tCONSTANT
460
+ {
461
+ result = new_attrasgn val[0], val[2], val[1]
462
+ }
463
+ | primary_value tCOLON2 tCONSTANT
464
+ {
465
+ if (self.in_def || self.in_single > 0) then
466
+ debug20 7
467
+ yyerror "dynamic constant assignment"
468
+ end
469
+
470
+ result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
471
+ }
472
+ | tCOLON3 tCONSTANT
473
+ {
474
+ if (self.in_def || self.in_single > 0) then
475
+ debug20 8
476
+ yyerror "dynamic constant assignment"
477
+ end
478
+
479
+ result = s(:const, nil, s(:colon3, val[1].to_sym))
480
+ }
481
+ | backref
482
+ {
483
+ self.backref_assign_error val[0]
484
+ }
485
+
486
+ lhs: user_variable
487
+ {
488
+ result = self.assignable val[0]
489
+ }
490
+ | keyword_variable
491
+ {
492
+ result = self.assignable val[0]
493
+ debug20 9, val, result
494
+ }
495
+ | primary_value tLBRACK2 opt_call_args rbracket
496
+ {
497
+ result = self.aryset val[0], val[2]
498
+ }
499
+ | primary_value call_op tIDENTIFIER # REFACTOR
500
+ {
501
+ result = new_attrasgn val[0], val[2], val[1]
502
+ }
503
+ | primary_value tCOLON2 tIDENTIFIER
504
+ {
505
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
506
+ }
507
+ | primary_value call_op tCONSTANT # REFACTOR?
508
+ {
509
+ result = new_attrasgn val[0], val[2], val[1]
510
+ }
511
+ | primary_value tCOLON2 tCONSTANT
512
+ {
513
+ if (self.in_def || self.in_single > 0) then
514
+ debug20 10
515
+ yyerror "dynamic constant assignment"
516
+ end
517
+
518
+ result = s(:const, s(:colon2, val[0], val[2].to_sym))
519
+ }
520
+ | tCOLON3 tCONSTANT
521
+ {
522
+ if (self.in_def || self.in_single > 0) then
523
+ debug20 11
524
+ yyerror "dynamic constant assignment"
525
+ end
526
+
527
+ result = s(:const, s(:colon3, val[1].to_sym))
528
+ }
529
+ | backref
530
+ {
531
+ self.backref_assign_error val[0]
532
+ }
533
+
534
+ cname: tIDENTIFIER
535
+ {
536
+ yyerror "class/module name must be CONSTANT"
537
+ }
538
+ | tCONSTANT
539
+
540
+ cpath: tCOLON3 cname
541
+ {
542
+ result = s(:colon3, val[1].to_sym)
543
+ }
544
+ | cname
545
+ {
546
+ result = val[0].to_sym
547
+ }
548
+ | primary_value tCOLON2 cname
549
+ {
550
+ result = s(:colon2, val[0], val[2].to_sym)
551
+ }
552
+
553
+ fname: tIDENTIFIER | tCONSTANT | tFID
554
+ | op
555
+ {
556
+ lexer.lex_state = :expr_end
557
+ result = val[0]
558
+ }
559
+
560
+ | reswords
561
+ {
562
+ lexer.lex_state = :expr_end
563
+ result = val[0]
564
+ }
565
+
566
+ fsym: fname | symbol
567
+
568
+ fitem: fsym
569
+ {
570
+ result = s(:lit, val[0].to_sym)
571
+ }
572
+ | dsym
573
+
574
+ undef_list: fitem
575
+ {
576
+ result = new_undef val[0]
577
+ }
578
+ |
579
+ undef_list tCOMMA
580
+ {
581
+ lexer.lex_state = :expr_fname
582
+ }
583
+ fitem
584
+ {
585
+ result = new_undef val[0], val[3]
586
+ }
587
+
588
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
589
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
590
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
591
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
592
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
593
+
594
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
595
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
596
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
597
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
598
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
599
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
600
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
601
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
602
+ | kUNTIL
603
+
604
+ arg: lhs tEQL arg
605
+ {
606
+ result = new_assign val[0], val[2]
607
+ }
608
+ | lhs tEQL arg kRESCUE_MOD arg
609
+ {
610
+ result = new_assign val[0], s(:rescue, val[2], new_resbody(s(:array), val[4]))
611
+ }
612
+ | var_lhs tOP_ASGN arg
613
+ {
614
+ result = new_op_asgn val
615
+ }
616
+ | var_lhs tOP_ASGN arg kRESCUE_MOD arg
617
+ {
618
+ result = new_op_asgn val
619
+ result = s(:rescue, result, new_resbody(s(:array), val[4]))
620
+ }
621
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
622
+ {
623
+ val[2].sexp_type = :arglist if val[2]
624
+ result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
625
+ }
626
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg
627
+ {
628
+ result = new_op_asgn2 val
629
+ }
630
+ | primary_value call_op tCONSTANT tOP_ASGN arg
631
+ {
632
+ result = new_op_asgn2 val
633
+ }
634
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
635
+ {
636
+ result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
637
+ }
638
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
639
+ {
640
+ yyerror "constant re-assignment"
641
+ }
642
+ | tCOLON3 tCONSTANT tOP_ASGN arg
643
+ {
644
+ yyerror "constant re-assignment"
645
+ }
646
+ | backref tOP_ASGN arg
647
+ {
648
+ self.backref_assign_error val[0]
649
+ }
650
+ | arg tDOT2 arg
651
+ {
652
+ v1, v2 = val[0], val[2]
653
+ if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
654
+ result = s(:lit, (v1.last)..(v2.last))
655
+ else
656
+ result = s(:dot2, v1, v2)
657
+ end
658
+ }
659
+ | arg tDOT3 arg
660
+ {
661
+ v1, v2 = val[0], val[2]
662
+ if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
663
+ result = s(:lit, (v1.last)...(v2.last))
664
+ else
665
+ result = s(:dot3, v1, v2)
666
+ end
667
+ }
668
+ | arg tPLUS arg
669
+ {
670
+ result = new_call val[0], :+, argl(val[2])
671
+ }
672
+ | arg tMINUS arg
673
+ {
674
+ result = new_call val[0], :-, argl(val[2])
675
+ }
676
+ | arg tSTAR2 arg # TODO: rename
677
+ {
678
+ result = new_call val[0], :*, argl(val[2])
679
+ }
680
+ | arg tDIVIDE arg
681
+ {
682
+ result = new_call val[0], :"/", argl(val[2])
683
+ }
684
+ | arg tPERCENT arg
685
+ {
686
+ result = new_call val[0], :"%", argl(val[2])
687
+ }
688
+ | arg tPOW arg
689
+ {
690
+ result = new_call val[0], :**, argl(val[2])
691
+ }
692
+ | tUMINUS_NUM simple_numeric tPOW arg
693
+ {
694
+ result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
695
+ }
696
+ | tUPLUS arg
697
+ {
698
+ result = new_call val[1], :"+@"
699
+ }
700
+ | tUMINUS arg
701
+ {
702
+ result = new_call val[1], :"-@"
703
+ }
704
+ | arg tPIPE arg
705
+ {
706
+ result = new_call val[0], :"|", argl(val[2])
707
+ }
708
+ | arg tCARET arg
709
+ {
710
+ result = new_call val[0], :"^", argl(val[2])
711
+ }
712
+ | arg tAMPER2 arg
713
+ {
714
+ result = new_call val[0], :"&", argl(val[2])
715
+ }
716
+ | arg tCMP arg
717
+ {
718
+ result = new_call val[0], :"<=>", argl(val[2])
719
+ }
720
+ | arg tGT arg
721
+ {
722
+ result = new_call val[0], :">", argl(val[2])
723
+ }
724
+ | arg tGEQ arg
725
+ {
726
+ result = new_call val[0], :">=", argl(val[2])
727
+ }
728
+ | arg tLT arg
729
+ {
730
+ result = new_call val[0], :"<", argl(val[2])
731
+ }
732
+ | arg tLEQ arg
733
+ {
734
+ result = new_call val[0], :"<=", argl(val[2])
735
+ }
736
+ | arg tEQ arg
737
+ {
738
+ result = new_call val[0], :"==", argl(val[2])
739
+ }
740
+ | arg tEQQ arg
741
+ {
742
+ result = new_call val[0], :"===", argl(val[2])
743
+ }
744
+ | arg tNEQ arg
745
+ {
746
+ result = new_call val[0], :"!=", argl(val[2])
747
+ }
748
+ | arg tMATCH arg
749
+ {
750
+ result = new_match val[0], val[2]
751
+ }
752
+ | arg tNMATCH arg
753
+ {
754
+ result = s(:not, new_match(val[0], val[2]))
755
+ }
756
+ | tBANG arg
757
+ {
758
+ result = new_call val[1], :"!"
759
+ }
760
+ | tTILDE arg
761
+ {
762
+ result = new_call value_expr(val[1]), :"~"
763
+ }
764
+ | arg tLSHFT arg
765
+ {
766
+ val[0] = value_expr val[0]
767
+ val[2] = value_expr val[2]
768
+ result = new_call val[0], :"\<\<", argl(val[2])
769
+ }
770
+ | arg tRSHFT arg
771
+ {
772
+ val[0] = value_expr val[0]
773
+ val[2] = value_expr val[2]
774
+ result = new_call val[0], :">>", argl(val[2])
775
+ }
776
+ | arg tANDOP arg
777
+ {
778
+ result = logical_op :and, val[0], val[2]
779
+ }
780
+ | arg tOROP arg
781
+ {
782
+ result = logical_op :or, val[0], val[2]
783
+ }
784
+ | kDEFINED opt_nl arg
785
+ {
786
+ result = s(:defined, val[2])
787
+ }
788
+ | arg tEH arg opt_nl tCOLON arg
789
+ {
790
+ result = s(:if, val[0], val[2], val[5])
791
+ }
792
+ | primary
793
+
794
+ arg_value: arg
795
+ {
796
+ result = value_expr(val[0])
797
+ }
798
+
799
+ aref_args: none
800
+ | args trailer
801
+ {
802
+ result = args [val[0]]
803
+ }
804
+ | args tCOMMA assocs trailer
805
+ {
806
+ result = args [val[0], array_to_hash(val[2])]
807
+ }
808
+ | assocs trailer
809
+ {
810
+ result = args [array_to_hash(val[0])]
811
+ }
812
+
813
+ paren_args: tLPAREN2 opt_call_args rparen
814
+ {
815
+ result = val[1]
816
+ }
817
+
818
+ opt_paren_args: none
819
+ | paren_args
820
+
821
+ opt_call_args: none
822
+ {
823
+ result = val[0]
824
+ }
825
+ | call_args
826
+ {
827
+ result = val[0]
828
+ }
829
+ | args tCOMMA
830
+ {
831
+ result = args val
832
+ }
833
+ | args tCOMMA assocs tCOMMA
834
+ {
835
+ result = args [val[0], array_to_hash(val[2])]
836
+ }
837
+ | assocs tCOMMA
838
+ {
839
+ result = args [array_to_hash(val[0])]
840
+ }
841
+
842
+ call_args: command
843
+ {
844
+ warning "parenthesize argument(s) for future version"
845
+ result = call_args val
846
+ }
847
+ | args opt_block_arg
848
+ {
849
+ result = call_args val
850
+ result = self.arg_blk_pass val[0], val[1]
851
+ }
852
+ | assocs opt_block_arg
853
+ {
854
+ result = call_args [array_to_hash(val[0])]
855
+ result = self.arg_blk_pass result, val[1]
856
+ }
857
+ | args tCOMMA assocs opt_block_arg
858
+ {
859
+ result = call_args [val[0], array_to_hash(val[2])]
860
+ result = self.arg_blk_pass result, val[3]
861
+ }
862
+ | block_arg
863
+ {
864
+ result = call_args val
865
+ }
866
+
867
+ command_args: {
868
+ result = lexer.cmdarg.stack.dup # TODO: smell?
869
+ lexer.cmdarg.push true
870
+ }
871
+ call_args
872
+ {
873
+ lexer.cmdarg.stack.replace val[0]
874
+ result = val[1]
875
+ }
876
+
877
+ block_arg: tAMPER arg_value
878
+ {
879
+ result = s(:block_pass, val[1])
880
+ }
881
+
882
+ opt_block_arg: tCOMMA block_arg
883
+ {
884
+ result = val[1]
885
+ }
886
+ | none
887
+
888
+ args: arg_value
889
+ {
890
+ result = s(:array, val[0])
891
+ }
892
+ | tSTAR arg_value
893
+ {
894
+ result = s(:array, s(:splat, val[1]))
895
+ }
896
+ | args tCOMMA arg_value
897
+ {
898
+ result = self.list_append val[0], val[2]
899
+ }
900
+ | args tCOMMA tSTAR arg_value
901
+ {
902
+ result = self.list_append val[0], s(:splat, val[3])
903
+ }
904
+
905
+ mrhs_arg: mrhs
906
+ {
907
+ result = new_masgn_arg val[0]
908
+ }
909
+ | arg_value
910
+ {
911
+ result = new_masgn_arg val[0], :wrap
912
+ }
913
+
914
+ mrhs: args tCOMMA arg_value
915
+ {
916
+ result = val[0] << val[2]
917
+ }
918
+ | args tCOMMA tSTAR arg_value
919
+ {
920
+ result = self.arg_concat val[0], val[3]
921
+ }
922
+ | tSTAR arg_value
923
+ {
924
+ result = s(:splat, val[1])
925
+ }
926
+
927
+ primary: literal
928
+ | strings
929
+ | xstring
930
+ | regexp
931
+ | words
932
+ | qwords
933
+ | symbols
934
+ | qsymbols
935
+ | var_ref
936
+ | backref
937
+ | tFID
938
+ {
939
+ result = new_call nil, val[0].to_sym
940
+ }
941
+ | kBEGIN
942
+ {
943
+ result = self.lexer.lineno
944
+ }
945
+ bodystmt kEND
946
+ {
947
+ unless val[2] then
948
+ result = s(:nil)
949
+ else
950
+ result = s(:begin, val[2])
951
+ end
952
+
953
+ result.line = val[1]
954
+ }
955
+ | tLPAREN_ARG rparen
956
+ {
957
+ debug20 13, val, result
958
+ }
959
+ | tLPAREN_ARG
960
+ {
961
+ result = self.lexer.cmdarg.stack.dup
962
+ lexer.cmdarg.stack.replace [false] # TODO add api for these
963
+ }
964
+ expr
965
+ {
966
+ lexer.lex_state = :expr_endarg
967
+ }
968
+ rparen
969
+ {
970
+ warning "(...) interpreted as grouped expression"
971
+ lexer.cmdarg.stack.replace val[1]
972
+ result = val[2]
973
+ }
974
+ | tLPAREN compstmt tRPAREN
975
+ {
976
+ result = val[1] || s(:nil)
977
+ result.paren = true
978
+ }
979
+ | primary_value tCOLON2 tCONSTANT
980
+ {
981
+ result = s(:colon2, val[0], val[2].to_sym)
982
+ }
983
+ | tCOLON3 tCONSTANT
984
+ {
985
+ result = s(:colon3, val[1].to_sym)
986
+ }
987
+ | tLBRACK aref_args tRBRACK
988
+ {
989
+ result = val[1] || s(:array)
990
+ result.sexp_type = :array # aref_args is :args
991
+ }
992
+ | tLBRACE
993
+ {
994
+ result = self.lexer.lineno
995
+ }
996
+ assoc_list tRCURLY
997
+ {
998
+ result = new_hash val
999
+ }
1000
+ | kRETURN
1001
+ {
1002
+ result = s(:return)
1003
+ }
1004
+ | kYIELD tLPAREN2 call_args rparen
1005
+ {
1006
+ result = new_yield val[2]
1007
+ }
1008
+ | kYIELD tLPAREN2 rparen
1009
+ {
1010
+ result = new_yield
1011
+ }
1012
+ | kYIELD
1013
+ {
1014
+ result = new_yield
1015
+ }
1016
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1017
+ {
1018
+ result = s(:defined, val[3])
1019
+ }
1020
+ | kNOT tLPAREN2 expr rparen
1021
+ {
1022
+ result = s(:call, val[2], :"!")
1023
+ }
1024
+ | kNOT tLPAREN2 rparen
1025
+ {
1026
+ debug20 14, val, result
1027
+ }
1028
+ | fcall brace_block
1029
+ {
1030
+ oper, iter = val[0], val[1]
1031
+ call = oper # FIX
1032
+ iter.insert 1, call
1033
+ result = iter
1034
+ call.line = iter.line
1035
+ }
1036
+ | method_call
1037
+ | method_call brace_block
1038
+ {
1039
+ call, iter = val[0], val[1]
1040
+ block_dup_check call, iter
1041
+ iter.insert 1, call # FIX
1042
+ result = iter
1043
+ }
1044
+ | tLAMBDA lambda
1045
+ {
1046
+ result = val[1] # TODO: fix lineno
1047
+ }
1048
+ | kIF expr_value then compstmt if_tail kEND
1049
+ {
1050
+ result = new_if val[1], val[3], val[4]
1051
+ }
1052
+ | kUNLESS expr_value then compstmt opt_else kEND
1053
+ {
1054
+ result = new_if val[1], val[4], val[3]
1055
+ }
1056
+ | kWHILE
1057
+ {
1058
+ lexer.cond.push true
1059
+ }
1060
+ expr_value do
1061
+ {
1062
+ lexer.cond.pop
1063
+ }
1064
+ compstmt kEND
1065
+ {
1066
+ result = new_while val[5], val[2], true
1067
+ }
1068
+ | kUNTIL
1069
+ {
1070
+ lexer.cond.push true
1071
+ }
1072
+ expr_value do
1073
+ {
1074
+ lexer.cond.pop
1075
+ }
1076
+ compstmt kEND
1077
+ {
1078
+ result = new_until val[5], val[2], true
1079
+ }
1080
+ | kCASE expr_value opt_terms case_body kEND
1081
+ {
1082
+ (_, line), expr, _, body, _ = val
1083
+ result = new_case expr, body, line
1084
+ }
1085
+ | kCASE opt_terms case_body kEND
1086
+ {
1087
+ (_, line), _, body, _ = val
1088
+ result = new_case nil, body, line
1089
+ }
1090
+ | kFOR for_var kIN
1091
+ {
1092
+ lexer.cond.push true
1093
+ }
1094
+ expr_value do
1095
+ {
1096
+ lexer.cond.pop
1097
+ }
1098
+ compstmt kEND
1099
+ {
1100
+ result = new_for val[4], val[1], val[7]
1101
+ }
1102
+ | kCLASS
1103
+ {
1104
+ result = self.lexer.lineno
1105
+ }
1106
+ cpath superclass
1107
+ {
1108
+ self.comments.push self.lexer.comments
1109
+ if (self.in_def || self.in_single > 0) then
1110
+ yyerror "class definition in method body"
1111
+ end
1112
+ self.env.extend
1113
+ }
1114
+ bodystmt kEND
1115
+ {
1116
+ result = new_class val
1117
+ self.env.unextend
1118
+ self.lexer.comments # we don't care about comments in the body
1119
+ }
1120
+ | kCLASS tLSHFT
1121
+ {
1122
+ result = self.lexer.lineno
1123
+ }
1124
+ expr
1125
+ {
1126
+ result = self.in_def
1127
+ self.in_def = false
1128
+ }
1129
+ term
1130
+ {
1131
+ result = self.in_single
1132
+ self.in_single = 0
1133
+ self.env.extend
1134
+ }
1135
+ bodystmt kEND
1136
+ {
1137
+ result = new_sclass val
1138
+ self.env.unextend
1139
+ self.lexer.comments # we don't care about comments in the body
1140
+ }
1141
+ | kMODULE
1142
+ {
1143
+ result = self.lexer.lineno
1144
+ }
1145
+ cpath
1146
+ {
1147
+ self.comments.push self.lexer.comments
1148
+ yyerror "module definition in method body" if
1149
+ self.in_def or self.in_single > 0
1150
+
1151
+ self.env.extend
1152
+ }
1153
+ bodystmt kEND
1154
+ {
1155
+ result = new_module val
1156
+ self.env.unextend
1157
+ self.lexer.comments # we don't care about comments in the body
1158
+ }
1159
+ | kDEF fname
1160
+ {
1161
+ result = [self.in_def, self.lexer.cmdarg.stack.dup]
1162
+
1163
+ self.comments.push self.lexer.comments
1164
+ self.in_def = true
1165
+ self.env.extend
1166
+ # TODO: local->cmdargs = cmdarg_stack;
1167
+ # TODO: port local_push_gen and local_pop_gen
1168
+ lexer.cmdarg.stack.replace [false]
1169
+ }
1170
+ f_arglist bodystmt kEND
1171
+ {
1172
+ in_def, cmdarg = val[2]
1173
+
1174
+ result = new_defn val
1175
+
1176
+ lexer.cmdarg.stack.replace cmdarg
1177
+ self.env.unextend
1178
+ self.in_def = in_def
1179
+ self.lexer.comments # we don't care about comments in the body
1180
+ }
1181
+ | kDEF singleton dot_or_colon
1182
+ {
1183
+ self.comments.push self.lexer.comments
1184
+ lexer.lex_state = :expr_fname
1185
+ }
1186
+ fname
1187
+ {
1188
+ self.in_single += 1
1189
+ self.env.extend
1190
+ lexer.lex_state = :expr_endfn # force for args
1191
+ result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1192
+ lexer.cmdarg.stack.replace [false]
1193
+ }
1194
+ f_arglist bodystmt kEND
1195
+ {
1196
+ line, cmdarg = val[5]
1197
+ result = new_defs val
1198
+ result[3].line line
1199
+
1200
+ lexer.cmdarg.stack.replace cmdarg
1201
+
1202
+ self.env.unextend
1203
+ self.in_single -= 1
1204
+ self.lexer.comments # we don't care about comments in the body
1205
+ }
1206
+ | kBREAK
1207
+ {
1208
+ result = s(:break)
1209
+ }
1210
+ | kNEXT
1211
+ {
1212
+ result = s(:next)
1213
+ }
1214
+ | kREDO
1215
+ {
1216
+ result = s(:redo)
1217
+ }
1218
+ | kRETRY
1219
+ {
1220
+ result = s(:retry)
1221
+ }
1222
+
1223
+ primary_value: primary
1224
+ {
1225
+ result = value_expr(val[0])
1226
+ }
1227
+
1228
+ # These are really stupid
1229
+ k_begin: kBEGIN
1230
+ k_if: kIF
1231
+ k_unless: kUNLESS
1232
+ k_while: kWHILE
1233
+ k_until: kUNTIL
1234
+ k_case: kCASE
1235
+ k_for: kFOR
1236
+ k_class: kCLASS
1237
+ k_module: kMODULE
1238
+ k_def: kDEF
1239
+ k_end: kEND
1240
+
1241
+ then: term
1242
+ | kTHEN
1243
+ | term kTHEN
1244
+
1245
+ do: term
1246
+ | kDO_COND
1247
+
1248
+ if_tail: opt_else
1249
+ | kELSIF expr_value then compstmt if_tail
1250
+ {
1251
+ result = s(:if, val[1], val[3], val[4])
1252
+ }
1253
+
1254
+ opt_else: none
1255
+ | kELSE compstmt
1256
+ {
1257
+ result = val[1]
1258
+ }
1259
+
1260
+ for_var: lhs
1261
+ | mlhs
1262
+ {
1263
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1264
+ }
1265
+
1266
+ f_marg: f_norm_arg
1267
+ | tLPAREN f_margs rparen
1268
+ {
1269
+ result = val[1]
1270
+ }
1271
+
1272
+ f_marg_list: f_marg
1273
+ {
1274
+ result = s(:array, val[0])
1275
+ }
1276
+ | f_marg_list tCOMMA f_marg
1277
+ {
1278
+ result = list_append val[0], val[2]
1279
+ }
1280
+
1281
+ f_margs: f_marg_list
1282
+ {
1283
+ args, = val
1284
+
1285
+ result = block_var args
1286
+ }
1287
+ | f_marg_list tCOMMA tSTAR f_norm_arg
1288
+ {
1289
+ args, _, _, splat = val
1290
+
1291
+ result = block_var args, "*#{splat}".to_sym
1292
+ }
1293
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1294
+ {
1295
+ args, _, _, splat, _, args2 = val
1296
+
1297
+ result = block_var args, "*#{splat}".to_sym, args2
1298
+ }
1299
+ | f_marg_list tCOMMA tSTAR
1300
+ {
1301
+ args, _, _ = val
1302
+
1303
+ result = block_var args, :*
1304
+ }
1305
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1306
+ {
1307
+ args, _, _, _, args2 = val
1308
+
1309
+ result = block_var args, :*, args2
1310
+ }
1311
+ | tSTAR f_norm_arg
1312
+ {
1313
+ _, splat = val
1314
+
1315
+ result = block_var :"*#{splat}"
1316
+ }
1317
+ | tSTAR f_norm_arg tCOMMA f_marg_list
1318
+ {
1319
+ _, splat, _, args = val
1320
+
1321
+ result = block_var :"*#{splat}", args
1322
+ }
1323
+ | tSTAR
1324
+ {
1325
+ result = block_var :*
1326
+ }
1327
+ | tSTAR tCOMMA f_marg_list
1328
+ {
1329
+ _, _, args = val
1330
+
1331
+ result = block_var :*, args
1332
+ }
1333
+
1334
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1335
+ {
1336
+ result = call_args val
1337
+ }
1338
+ | f_block_kwarg opt_f_block_arg
1339
+ {
1340
+ result = call_args val
1341
+ }
1342
+ | f_kwrest opt_f_block_arg
1343
+ {
1344
+ result = call_args val
1345
+ }
1346
+ | f_block_arg
1347
+ {
1348
+ result = call_args val
1349
+ }
1350
+
1351
+ opt_block_args_tail: tCOMMA block_args_tail
1352
+ {
1353
+ result = args val
1354
+ }
1355
+ | none
1356
+
1357
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1358
+ {
1359
+ result = args val
1360
+ }
1361
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1362
+ {
1363
+ result = args val
1364
+ }
1365
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1366
+ {
1367
+ result = args val
1368
+ }
1369
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1370
+ {
1371
+ result = args val
1372
+ }
1373
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1374
+ {
1375
+ result = args val
1376
+ }
1377
+ | f_arg tCOMMA
1378
+ {
1379
+ result = args val
1380
+ }
1381
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1382
+ {
1383
+ result = args val
1384
+ }
1385
+ | f_arg opt_block_args_tail
1386
+ {
1387
+ result = args val
1388
+ }
1389
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1390
+ {
1391
+ result = args val
1392
+ }
1393
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1394
+ {
1395
+ result = args val
1396
+ }
1397
+ | f_block_optarg opt_block_args_tail
1398
+ {
1399
+ result = args val
1400
+ }
1401
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1402
+ {
1403
+ result = args val
1404
+ }
1405
+ | f_rest_arg opt_block_args_tail
1406
+ {
1407
+ result = args val
1408
+ }
1409
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1410
+ {
1411
+ result = args val
1412
+ }
1413
+ | block_args_tail
1414
+ {
1415
+ result = args val
1416
+ }
1417
+
1418
+ opt_block_param: none { result = 0 }
1419
+ | block_param_def
1420
+
1421
+ block_param_def: tPIPE opt_bv_decl tPIPE
1422
+ {
1423
+ result = args val
1424
+ }
1425
+ | tOROP
1426
+ {
1427
+ self.lexer.command_start = true
1428
+ result = s(:args)
1429
+ }
1430
+ | tPIPE block_param opt_bv_decl tPIPE
1431
+ {
1432
+ result = args val
1433
+ }
1434
+
1435
+ opt_bv_decl: opt_nl
1436
+ | opt_nl tSEMI bv_decls opt_nl
1437
+ {
1438
+ result = args val
1439
+ }
1440
+
1441
+ bv_decls: bvar
1442
+ {
1443
+ result = args val
1444
+ }
1445
+ | bv_decls tCOMMA bvar
1446
+ {
1447
+ result = args val
1448
+ }
1449
+
1450
+ bvar: tIDENTIFIER
1451
+ {
1452
+ result = s(:shadow, val[0].to_sym)
1453
+ }
1454
+ | f_bad_arg
1455
+
1456
+ lambda: {
1457
+ self.env.extend :dynamic
1458
+ result = self.lexer.lineno
1459
+
1460
+ result = lexer.lpar_beg
1461
+ lexer.paren_nest += 1
1462
+ lexer.lpar_beg = lexer.paren_nest
1463
+ }
1464
+ f_larglist lambda_body
1465
+ {
1466
+ lpar, args, body = val
1467
+ lexer.lpar_beg = lpar
1468
+
1469
+ call = new_call nil, :lambda
1470
+ result = new_iter call, args, body
1471
+ self.env.unextend
1472
+ }
1473
+
1474
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1475
+ {
1476
+ result = args val
1477
+ }
1478
+ | f_args
1479
+ {
1480
+ result = val[0]
1481
+ result = 0 if result == s(:args)
1482
+ }
1483
+
1484
+ lambda_body: tLAMBEG compstmt tRCURLY
1485
+ {
1486
+ result = val[1]
1487
+ }
1488
+ | kDO_LAMBDA compstmt kEND
1489
+ {
1490
+ result = val[1]
1491
+ }
1492
+
1493
+ do_block: kDO_BLOCK
1494
+ {
1495
+ self.env.extend :dynamic
1496
+ result = self.lexer.lineno
1497
+ }
1498
+ opt_block_param
1499
+ {
1500
+ result = nil # self.env.dynamic.keys
1501
+ }
1502
+ compstmt kEND
1503
+ {
1504
+ args = val[2]
1505
+ body = val[4]
1506
+ result = new_iter nil, args, body
1507
+ result.line = val[1]
1508
+
1509
+ self.env.unextend
1510
+ }
1511
+
1512
+ block_call: command do_block
1513
+ {
1514
+ # TODO:
1515
+ ## if (nd_type($1) == NODE_YIELD) {
1516
+ ## compile_error(PARSER_ARG "block given to yield");
1517
+
1518
+ syntax_error "Both block arg and actual block given." if
1519
+ val[0].block_pass?
1520
+
1521
+ val = invert_block_call val if inverted? val
1522
+
1523
+ result = val[1]
1524
+ result.insert 1, val[0]
1525
+ }
1526
+ | block_call dot_or_colon operation2 opt_paren_args
1527
+ {
1528
+ result = new_call val[0], val[2].to_sym, val[3]
1529
+ }
1530
+ | block_call dot_or_colon operation2 opt_paren_args brace_block
1531
+ {
1532
+ iter1, _, name, args, iter2 = val
1533
+
1534
+ call = new_call iter1, name.to_sym, args
1535
+ iter2.insert 1, call
1536
+
1537
+ result = iter2
1538
+ }
1539
+ | block_call dot_or_colon operation2 command_args do_block
1540
+ {
1541
+ iter1, _, name, args, iter2 = val
1542
+
1543
+ call = new_call iter1, name.to_sym, args
1544
+ iter2.insert 1, call
1545
+
1546
+ result = iter2
1547
+ }
1548
+
1549
+ method_call: fcall
1550
+ {
1551
+ result = self.lexer.lineno
1552
+ }
1553
+ paren_args
1554
+ {
1555
+ args = self.call_args val[2..-1]
1556
+ result = val[0].concat args.sexp_body
1557
+ }
1558
+ | primary_value call_op operation2 opt_paren_args
1559
+ {
1560
+ result = new_call val[0], val[2].to_sym, val[3], val[1]
1561
+ }
1562
+ | primary_value tCOLON2 operation2 paren_args
1563
+ {
1564
+ result = new_call val[0], val[2].to_sym, val[3]
1565
+ }
1566
+ | primary_value tCOLON2 operation3
1567
+ {
1568
+ result = new_call val[0], val[2].to_sym
1569
+ }
1570
+ | primary_value call_op paren_args
1571
+ {
1572
+ result = new_call val[0], :call, val[2], val[1]
1573
+ }
1574
+ | primary_value tCOLON2 paren_args
1575
+ {
1576
+ result = new_call val[0], :call, val[2]
1577
+ }
1578
+ | kSUPER paren_args
1579
+ {
1580
+ result = new_super val[1]
1581
+ }
1582
+ | kSUPER
1583
+ {
1584
+ result = s(:zsuper)
1585
+ }
1586
+ | primary_value tLBRACK2 opt_call_args rbracket
1587
+ {
1588
+ result = new_aref val
1589
+ }
1590
+
1591
+ brace_block: tLCURLY
1592
+ {
1593
+ self.env.extend :dynamic
1594
+ result = self.lexer.lineno
1595
+ }
1596
+ opt_block_param
1597
+ {
1598
+ result = nil # self.env.dynamic.keys
1599
+ }
1600
+ compstmt tRCURLY
1601
+ {
1602
+ _, line, args, _, body, _ = val
1603
+
1604
+ result = new_iter nil, args, body
1605
+ result.line = line
1606
+
1607
+ self.env.unextend
1608
+ }
1609
+ | kDO
1610
+ {
1611
+ self.env.extend :dynamic
1612
+ result = self.lexer.lineno
1613
+ }
1614
+ opt_block_param
1615
+ {
1616
+ result = nil # self.env.dynamic.keys
1617
+ }
1618
+ compstmt kEND
1619
+ {
1620
+ _, line, args, _, body, _ = val
1621
+
1622
+ result = new_iter nil, args, body
1623
+ result.line = line
1624
+
1625
+ self.env.unextend
1626
+ }
1627
+
1628
+ case_body: kWHEN
1629
+ {
1630
+ result = self.lexer.lineno
1631
+ }
1632
+ args then compstmt cases
1633
+ {
1634
+ result = new_when(val[2], val[4])
1635
+ result.line = val[1]
1636
+ result << val[5] if val[5]
1637
+ }
1638
+
1639
+ cases: opt_else | case_body
1640
+
1641
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1642
+ {
1643
+ (_, line), klasses, var, _, body, rest = val
1644
+
1645
+ klasses ||= s(:array)
1646
+ klasses << new_assign(var, s(:gvar, :"$!")) if var
1647
+ klasses.line line
1648
+
1649
+ result = new_resbody(klasses, body)
1650
+ result << rest if rest # UGH, rewritten above
1651
+ }
1652
+ |
1653
+ {
1654
+ result = nil
1655
+ }
1656
+
1657
+ exc_list: arg_value
1658
+ {
1659
+ result = s(:array, val[0])
1660
+ }
1661
+ | mrhs
1662
+ | none
1663
+
1664
+ exc_var: tASSOC lhs
1665
+ {
1666
+ result = val[1]
1667
+ }
1668
+ | none
1669
+
1670
+ opt_ensure: kENSURE compstmt
1671
+ {
1672
+ _, body = val
1673
+
1674
+ result = body || s(:nil)
1675
+ }
1676
+ | none
1677
+
1678
+ literal: numeric
1679
+ {
1680
+ result = s(:lit, val[0])
1681
+ }
1682
+ | symbol
1683
+ {
1684
+ result = s(:lit, val[0])
1685
+ }
1686
+ | dsym
1687
+
1688
+ strings: string
1689
+ {
1690
+ val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1691
+ result = val[0]
1692
+ }
1693
+
1694
+ string: tCHAR
1695
+ {
1696
+ debug20 23, val, result
1697
+ }
1698
+ | string1
1699
+ | string string1
1700
+ {
1701
+ result = self.literal_concat val[0], val[1]
1702
+ }
1703
+
1704
+ string1: tSTRING_BEG string_contents tSTRING_END
1705
+ {
1706
+ result = val[1]
1707
+ }
1708
+ | tSTRING
1709
+ {
1710
+ result = new_string val
1711
+ }
1712
+
1713
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1714
+ {
1715
+ result = new_xstring val[1]
1716
+ }
1717
+
1718
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
1719
+ {
1720
+ result = new_regexp val
1721
+ }
1722
+
1723
+ words: tWORDS_BEG tSPACE tSTRING_END
1724
+ {
1725
+ result = s(:array)
1726
+ }
1727
+ | tWORDS_BEG word_list tSTRING_END
1728
+ {
1729
+ result = val[1]
1730
+ }
1731
+
1732
+ word_list: none
1733
+ {
1734
+ result = new_word_list
1735
+ }
1736
+ | word_list word tSPACE
1737
+ {
1738
+ result = val[0].dup << new_word_list_entry(val)
1739
+ }
1740
+
1741
+ word: string_content
1742
+ | word string_content
1743
+ {
1744
+ result = self.literal_concat val[0], val[1]
1745
+ }
1746
+
1747
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1748
+ {
1749
+ result = s(:array)
1750
+ }
1751
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1752
+ {
1753
+ result = val[1]
1754
+ }
1755
+
1756
+ symbol_list: none
1757
+ {
1758
+ result = new_symbol_list
1759
+ }
1760
+ | symbol_list word tSPACE
1761
+ {
1762
+ result = val[0].dup << new_symbol_list_entry(val)
1763
+ }
1764
+
1765
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
1766
+ {
1767
+ result = s(:array)
1768
+ }
1769
+ | tQWORDS_BEG qword_list tSTRING_END
1770
+ {
1771
+ result = val[1]
1772
+ }
1773
+
1774
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1775
+ {
1776
+ result = s(:array)
1777
+ }
1778
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
1779
+ {
1780
+ result = val[1]
1781
+ }
1782
+
1783
+ qword_list: none
1784
+ {
1785
+ result = new_qword_list
1786
+ }
1787
+ | qword_list tSTRING_CONTENT tSPACE
1788
+ {
1789
+ result = val[0].dup << new_qword_list_entry(val)
1790
+ }
1791
+
1792
+ qsym_list: none
1793
+ {
1794
+ result = new_qsym_list
1795
+ }
1796
+ | qsym_list tSTRING_CONTENT tSPACE
1797
+ {
1798
+ result = val[0].dup << new_qsym_list_entry(val)
1799
+ }
1800
+
1801
+ string_contents: none
1802
+ {
1803
+ result = s(:str, "")
1804
+ }
1805
+ | string_contents string_content
1806
+ {
1807
+ result = literal_concat(val[0], val[1])
1808
+ }
1809
+
1810
+ xstring_contents: none
1811
+ {
1812
+ result = nil
1813
+ }
1814
+ | xstring_contents string_content
1815
+ {
1816
+ result = literal_concat(val[0], val[1])
1817
+ }
1818
+
1819
+ regexp_contents: none
1820
+ {
1821
+ result = nil
1822
+ }
1823
+ | regexp_contents string_content
1824
+ {
1825
+ result = literal_concat(val[0], val[1])
1826
+ }
1827
+
1828
+ string_content: tSTRING_CONTENT
1829
+ {
1830
+ result = new_string val
1831
+ }
1832
+ | tSTRING_DVAR
1833
+ {
1834
+ result = lexer.lex_strterm
1835
+
1836
+ lexer.lex_strterm = nil
1837
+ lexer.lex_state = :expr_beg # TODO: expr_value ?
1838
+ }
1839
+ string_dvar
1840
+ {
1841
+ lexer.lex_strterm = val[1]
1842
+ result = s(:evstr, val[2])
1843
+ }
1844
+ | tSTRING_DBEG
1845
+ {
1846
+ result = [lexer.lex_strterm,
1847
+ lexer.brace_nest,
1848
+ lexer.string_nest, # TODO: remove
1849
+ lexer.cond.store,
1850
+ lexer.cmdarg.store,
1851
+ lexer.lex_state,
1852
+ ]
1853
+
1854
+ lexer.lex_strterm = nil
1855
+ lexer.brace_nest = 0
1856
+ lexer.string_nest = 0
1857
+
1858
+ lexer.lex_state = :expr_value
1859
+ }
1860
+ compstmt tRCURLY
1861
+ {
1862
+ # TODO: tRCURLY -> tSTRING_END
1863
+ _, memo, stmt, _ = val
1864
+
1865
+ lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
1866
+
1867
+ lexer.lex_strterm = lex_strterm
1868
+ lexer.brace_nest = brace_nest
1869
+ lexer.string_nest = string_nest
1870
+
1871
+ lexer.cond.restore oldcond
1872
+ lexer.cmdarg.restore oldcmdarg
1873
+
1874
+ lexer.lex_state = oldlex_state
1875
+
1876
+ case stmt
1877
+ when Sexp then
1878
+ case stmt.sexp_type
1879
+ when :str, :dstr, :evstr then
1880
+ result = stmt
1881
+ else
1882
+ result = s(:evstr, stmt)
1883
+ end
1884
+ when nil then
1885
+ result = s(:evstr)
1886
+ else
1887
+ debug20 25
1888
+ raise "unknown string body: #{stmt.inspect}"
1889
+ end
1890
+ }
1891
+
1892
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1893
+ | tIVAR { result = s(:ivar, val[0].to_sym) }
1894
+ | tCVAR { result = s(:cvar, val[0].to_sym) }
1895
+ | backref
1896
+
1897
+ symbol: tSYMBEG sym
1898
+ {
1899
+ lexer.lex_state = :expr_end
1900
+ result = val[1].to_sym
1901
+ }
1902
+ | tSYMBOL
1903
+ {
1904
+ result = val[0].to_sym
1905
+ }
1906
+
1907
+ sym: fname | tIVAR | tGVAR | tCVAR
1908
+
1909
+ dsym: tSYMBEG xstring_contents tSTRING_END
1910
+ {
1911
+ lexer.lex_state = :expr_end
1912
+ result = val[1]
1913
+
1914
+ result ||= s(:str, "")
1915
+
1916
+ case result.sexp_type
1917
+ when :dstr then
1918
+ result.sexp_type = :dsym
1919
+ when :str then
1920
+ result = s(:lit, result.last.to_sym)
1921
+ when :evstr then
1922
+ result = s(:dsym, "", result)
1923
+ else
1924
+ debug20 26, val, result
1925
+ end
1926
+ }
1927
+
1928
+ numeric: simple_numeric
1929
+ | tUMINUS_NUM simple_numeric
1930
+ {
1931
+ result = -val[1] # TODO: pt_testcase
1932
+ }
1933
+
1934
+ simple_numeric: tINTEGER
1935
+ | tFLOAT
1936
+ | tRATIONAL
1937
+ | tIMAGINARY
1938
+
1939
+ user_variable: tIDENTIFIER
1940
+ | tIVAR
1941
+ | tGVAR
1942
+ | tCONSTANT
1943
+ | tCVAR
1944
+
1945
+ keyword_variable: kNIL { result = s(:nil) }
1946
+ | kSELF { result = s(:self) }
1947
+ | kTRUE { result = s(:true) }
1948
+ | kFALSE { result = s(:false) }
1949
+ | k__FILE__ { result = s(:str, self.file) }
1950
+ | k__LINE__ { result = s(:lit, lexer.lineno) }
1951
+ | k__ENCODING__
1952
+ {
1953
+ result =
1954
+ if defined? Encoding then
1955
+ s(:colon2, s(:const, :Encoding), :UTF_8)
1956
+ else
1957
+ s(:str, "Unsupported!")
1958
+ end
1959
+ }
1960
+
1961
+ var_ref: user_variable
1962
+ {
1963
+ var = val[0]
1964
+ result = Sexp === var ? var : self.gettable(var)
1965
+ }
1966
+ | keyword_variable
1967
+ {
1968
+ var = val[0]
1969
+ result = Sexp === var ? var : self.gettable(var)
1970
+ }
1971
+
1972
+ var_lhs: user_variable
1973
+ {
1974
+ result = self.assignable val[0]
1975
+ }
1976
+ | keyword_variable
1977
+ {
1978
+ result = self.assignable val[0]
1979
+ debug20 29, val, result
1980
+ }
1981
+
1982
+ backref: tNTH_REF { result = s(:nth_ref, val[0]) }
1983
+ | tBACK_REF { result = s(:back_ref, val[0]) }
1984
+
1985
+ superclass: term
1986
+ {
1987
+ result = nil
1988
+ }
1989
+ | tLT
1990
+ {
1991
+ lexer.lex_state = :expr_beg
1992
+ }
1993
+ expr_value term
1994
+ {
1995
+ result = val[2]
1996
+ }
1997
+ | error term
1998
+ {
1999
+ yyerrok
2000
+ result = nil
2001
+ debug20 30, val, result
2002
+ }
2003
+
2004
+ f_arglist: tLPAREN2 f_args rparen
2005
+ {
2006
+ result = val[1]
2007
+ self.lexer.lex_state = :expr_beg
2008
+ self.lexer.command_start = true
2009
+ # TODO:
2010
+ # $<num>$ = parser->parser_in_kwarg;
2011
+ # parser->parser_in_kwarg = 1;
2012
+ }
2013
+ | f_args term
2014
+ {
2015
+ # TODO: parser->parser_in_kwarg = $<num>1;
2016
+ result = val[0]
2017
+ self.lexer.lex_state = :expr_beg
2018
+ self.lexer.command_start = true
2019
+ }
2020
+
2021
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2022
+ {
2023
+ result = args val
2024
+ }
2025
+ | f_kwarg opt_f_block_arg
2026
+ {
2027
+ result = args val
2028
+ }
2029
+ | f_kwrest opt_f_block_arg
2030
+ {
2031
+ result = args val
2032
+ }
2033
+ | f_block_arg
2034
+
2035
+ opt_args_tail: tCOMMA args_tail
2036
+ {
2037
+ result = val[1]
2038
+ }
2039
+ |
2040
+ {
2041
+ result = nil
2042
+ }
2043
+
2044
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2045
+ {
2046
+ result = args val
2047
+ }
2048
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2049
+ {
2050
+ result = args val
2051
+ }
2052
+ | f_arg tCOMMA f_optarg opt_args_tail
2053
+ {
2054
+ result = args val
2055
+ }
2056
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2057
+ {
2058
+ result = args val
2059
+ }
2060
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2061
+ {
2062
+ result = args val
2063
+ }
2064
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2065
+ {
2066
+ result = args val
2067
+ }
2068
+ | f_arg opt_args_tail
2069
+ {
2070
+ result = args val
2071
+ }
2072
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2073
+ {
2074
+ result = args val
2075
+ }
2076
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2077
+ {
2078
+ result = args val
2079
+ }
2080
+ | f_optarg opt_args_tail
2081
+ {
2082
+ result = args val
2083
+ }
2084
+ | f_optarg tCOMMA f_arg opt_args_tail
2085
+ {
2086
+ result = args val
2087
+ }
2088
+ | f_rest_arg opt_args_tail
2089
+ {
2090
+ result = args val
2091
+ }
2092
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2093
+ {
2094
+ result = args val
2095
+ }
2096
+ | args_tail
2097
+ {
2098
+ result = args val
2099
+ }
2100
+ |
2101
+ {
2102
+ result = args val
2103
+ }
2104
+
2105
+ f_bad_arg: tCONSTANT
2106
+ {
2107
+ yyerror "formal argument cannot be a constant"
2108
+ }
2109
+ | tIVAR
2110
+ {
2111
+ yyerror "formal argument cannot be an instance variable"
2112
+ }
2113
+ | tGVAR
2114
+ {
2115
+ yyerror "formal argument cannot be a global variable"
2116
+ }
2117
+ | tCVAR
2118
+ {
2119
+ yyerror "formal argument cannot be a class variable"
2120
+ }
2121
+
2122
+ f_norm_arg: f_bad_arg
2123
+ | tIDENTIFIER
2124
+ {
2125
+ identifier = val[0].to_sym
2126
+ self.env[identifier] = :lvar
2127
+
2128
+ result = identifier
2129
+ }
2130
+
2131
+ f_arg_asgn: f_norm_arg
2132
+
2133
+ f_arg_item: f_arg_asgn
2134
+ | tLPAREN f_margs rparen
2135
+ {
2136
+ result = val[1]
2137
+ }
2138
+
2139
+ f_arg: f_arg_item
2140
+ {
2141
+ case val[0]
2142
+ when Symbol then
2143
+ result = s(:args)
2144
+ result << val[0]
2145
+ when Sexp then
2146
+ result = val[0]
2147
+ else
2148
+ debug20 32
2149
+ raise "Unknown f_arg type: #{val.inspect}"
2150
+ end
2151
+ }
2152
+ | f_arg tCOMMA f_arg_item
2153
+ {
2154
+ list, _, item = val
2155
+
2156
+ if list.sexp_type == :args then
2157
+ result = list
2158
+ else
2159
+ result = s(:args, list)
2160
+ end
2161
+
2162
+ result << item
2163
+ }
2164
+
2165
+ f_label: tLABEL
2166
+
2167
+ f_kw: f_label arg_value
2168
+ {
2169
+ # TODO: call_args
2170
+ label, _ = val[0] # TODO: fix lineno?
2171
+ identifier = label.to_sym
2172
+ self.env[identifier] = :lvar
2173
+
2174
+ result = s(:array, s(:kwarg, identifier, val[1]))
2175
+ }
2176
+ | f_label
2177
+ {
2178
+ label, _ = val[0] # TODO: fix lineno?
2179
+ identifier = label.to_sym
2180
+ self.env[identifier] = :lvar
2181
+
2182
+ result = s(:array, s(:kwarg, identifier))
2183
+ }
2184
+
2185
+ f_block_kw: f_label primary_value
2186
+ {
2187
+ # TODO: call_args
2188
+ label, _ = val[0] # TODO: fix lineno?
2189
+ identifier = label.to_sym
2190
+ self.env[identifier] = :lvar
2191
+
2192
+ result = s(:array, s(:kwarg, identifier, val[1]))
2193
+ }
2194
+ | f_label
2195
+ {
2196
+ label, _ = val[0] # TODO: fix lineno?
2197
+ identifier = label.to_sym
2198
+ self.env[identifier] = :lvar
2199
+
2200
+ result = s(:array, s(:kwarg, identifier))
2201
+ }
2202
+
2203
+ f_block_kwarg: f_block_kw
2204
+ | f_block_kwarg tCOMMA f_block_kw
2205
+ {
2206
+ list, _, item = val
2207
+ result = list << item.last
2208
+ }
2209
+
2210
+ f_kwarg: f_kw
2211
+ | f_kwarg tCOMMA f_kw
2212
+ {
2213
+ result = args val
2214
+ }
2215
+
2216
+ kwrest_mark: tPOW
2217
+ | tDSTAR
2218
+
2219
+ f_kwrest: kwrest_mark tIDENTIFIER
2220
+ {
2221
+ result = :"**#{val[1]}"
2222
+ }
2223
+ | kwrest_mark
2224
+ {
2225
+ result = :"**"
2226
+ }
2227
+
2228
+ f_opt: f_arg_asgn tEQL arg_value
2229
+ {
2230
+ result = self.assignable val[0], val[2]
2231
+ # TODO: detect duplicate names
2232
+ }
2233
+
2234
+ f_block_opt: f_arg_asgn tEQL primary_value
2235
+ {
2236
+ result = self.assignable val[0], val[2]
2237
+ }
2238
+
2239
+ f_block_optarg: f_block_opt
2240
+ {
2241
+ result = s(:block, val[0])
2242
+ }
2243
+ | f_block_optarg tCOMMA f_block_opt
2244
+ {
2245
+ result = val[0]
2246
+ result << val[2]
2247
+ }
2248
+
2249
+ f_optarg: f_opt
2250
+ {
2251
+ result = s(:block, val[0])
2252
+ }
2253
+ | f_optarg tCOMMA f_opt
2254
+ {
2255
+ result = self.block_append val[0], val[2]
2256
+ }
2257
+
2258
+ restarg_mark: tSTAR2 | tSTAR
2259
+
2260
+ f_rest_arg: restarg_mark tIDENTIFIER
2261
+ {
2262
+ # TODO: differs from parse.y - needs tests
2263
+ name = val[1].to_sym
2264
+ self.assignable name
2265
+ result = :"*#{name}"
2266
+ }
2267
+ | restarg_mark
2268
+ {
2269
+ name = :"*"
2270
+ self.env[name] = :lvar
2271
+ result = name
2272
+ }
2273
+
2274
+ blkarg_mark: tAMPER2 | tAMPER
2275
+
2276
+ f_block_arg: blkarg_mark tIDENTIFIER
2277
+ {
2278
+ identifier = val[1].to_sym
2279
+
2280
+ self.env[identifier] = :lvar
2281
+ result = "&#{identifier}".to_sym
2282
+ }
2283
+
2284
+ opt_f_block_arg: tCOMMA f_block_arg
2285
+ {
2286
+ result = val[1]
2287
+ }
2288
+ |
2289
+ {
2290
+ result = nil
2291
+ }
2292
+
2293
+ singleton: var_ref
2294
+ | tLPAREN2
2295
+ {
2296
+ lexer.lex_state = :expr_beg
2297
+ }
2298
+ expr rparen
2299
+ {
2300
+ result = val[2]
2301
+ yyerror "Can't define single method for literals." if
2302
+ result.sexp_type == :lit
2303
+ }
2304
+
2305
+ assoc_list: none # [!nil]
2306
+ {
2307
+ result = s(:array)
2308
+ }
2309
+ | assocs trailer # [!nil]
2310
+ {
2311
+ result = val[0]
2312
+ }
2313
+
2314
+ assocs: assoc
2315
+ | assocs tCOMMA assoc
2316
+ {
2317
+ list = val[0].dup
2318
+ more = val[2].sexp_body
2319
+ list.push(*more) unless more.empty?
2320
+ result = list
2321
+ result.sexp_type = :hash
2322
+ }
2323
+
2324
+ assoc: arg_value tASSOC arg_value
2325
+ {
2326
+ result = s(:array, val[0], val[2])
2327
+ }
2328
+ | tLABEL opt_nl arg_value
2329
+ {
2330
+ result = s(:array, s(:lit, val[0][0].to_sym), val.last)
2331
+ }
2332
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2333
+ {
2334
+ _, sym, _, value = val
2335
+ sym.sexp_type = :dsym
2336
+ result = s(:array, sym, value)
2337
+ }
2338
+ | tSYMBOL arg_value
2339
+ {
2340
+ raise "not yet: #{val.inspect}"
2341
+ # result = s(:array, s(:lit, val[1].to_sym), val[1])
2342
+ }
2343
+ | tDSTAR arg_value
2344
+ {
2345
+ result = s(:array, s(:kwsplat, val[1]))
2346
+ }
2347
+
2348
+ operation: tIDENTIFIER | tCONSTANT | tFID
2349
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2350
+ operation3: tIDENTIFIER | tFID | op
2351
+ dot_or_colon: tDOT | tCOLON2
2352
+ call_op: tDOT
2353
+ | tLONELY
2354
+ opt_terms: | terms
2355
+ opt_nl: | tNL
2356
+ rparen: opt_nl tRPAREN
2357
+ rbracket: opt_nl tRBRACK
2358
+ trailer: | tNL | tCOMMA
2359
+
2360
+ term: tSEMI { yyerrok }
2361
+ | tNL
2362
+
2363
+ terms: term
2364
+ | terms tSEMI { yyerrok }
2365
+
2366
+ none: { result = nil; }
2367
+ end
2368
+
2369
+ ---- inner
2370
+
2371
+ require "ruby_lexer"
2372
+ require "ruby_parser_extras"
2373
+
2374
+ # :stopdoc:
2375
+
2376
+ # Local Variables: **
2377
+ # racc-token-length-max:14 **
2378
+ # End: **