brakeman 5.4.1 → 6.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +14 -0
  3. data/README.md +2 -2
  4. data/bundle/load.rb +3 -4
  5. data/bundle/ruby/3.1.0/gems/parallel-1.23.0/lib/parallel/version.rb +4 -0
  6. data/bundle/ruby/3.1.0/gems/{parallel-1.22.1 → parallel-1.23.0}/lib/parallel.rb +43 -3
  7. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/History.rdoc +38 -0
  8. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/Manifest.txt +2 -0
  9. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/README.rdoc +2 -1
  10. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/compare/normalize.rb +1 -0
  11. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby20_parser.rb +4267 -4284
  12. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby20_parser.y +50 -26
  13. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby21_parser.rb +4241 -4240
  14. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby21_parser.y +50 -26
  15. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby22_parser.rb +4289 -4290
  16. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby22_parser.y +50 -26
  17. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby23_parser.rb +4274 -4243
  18. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby23_parser.y +50 -26
  19. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby24_parser.rb +4279 -4298
  20. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby24_parser.y +50 -26
  21. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby25_parser.rb +4270 -4289
  22. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby25_parser.y +50 -26
  23. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby26_parser.rb +4270 -4289
  24. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby26_parser.y +50 -26
  25. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby27_parser.rb +4173 -4206
  26. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby27_parser.y +50 -26
  27. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby30_parser.rb +6029 -5971
  28. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby30_parser.y +135 -86
  29. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby31_parser.rb +6195 -6184
  30. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby31_parser.y +136 -87
  31. data/bundle/ruby/3.1.0/gems/ruby_parser-3.20.3/lib/ruby32_parser.rb +13601 -0
  32. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2/lib/ruby3_parser.yy → ruby_parser-3.20.3/lib/ruby32_parser.y} +158 -163
  33. data/bundle/ruby/3.1.0/gems/ruby_parser-3.20.3/lib/ruby3_parser.yy +3635 -0
  34. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_lexer.rb +15 -7
  35. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_lexer.rex.rb +1 -1
  36. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_lexer_strings.rb +2 -2
  37. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_parser.rb +2 -0
  38. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_parser.yy +50 -26
  39. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_parser_extras.rb +25 -19
  40. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/tools/munge.rb +8 -2
  41. data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/tools/ripper.rb +14 -12
  42. data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/History.rdoc +13 -0
  43. data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/pt_testcase.rb +3 -3
  44. data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/sexp.rb +8 -2
  45. data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/sexp_processor.rb +1 -1
  46. data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/strict_sexp.rb +6 -5
  47. data/lib/brakeman/app_tree.rb +0 -1
  48. data/lib/brakeman/checks/check_content_tag.rb +8 -5
  49. data/lib/brakeman/checks/check_eol_ruby.rb +3 -1
  50. data/lib/brakeman/report/report_github.rb +1 -1
  51. data/lib/brakeman/scanner.rb +0 -1
  52. data/lib/brakeman/tracker/config.rb +15 -11
  53. data/lib/brakeman/version.rb +1 -1
  54. data/lib/brakeman.rb +6 -2
  55. metadata +56 -68
  56. data/bundle/ruby/3.1.0/gems/parallel-1.22.1/lib/parallel/processor_count.rb +0 -44
  57. data/bundle/ruby/3.1.0/gems/parallel-1.22.1/lib/parallel/version.rb +0 -4
  58. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/History.rdoc +0 -6
  59. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/Manifest.txt +0 -19
  60. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/README.rdoc +0 -54
  61. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby18_parser.rb +0 -5794
  62. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby18_parser.y +0 -1909
  63. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby19_parser.rb +0 -6186
  64. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby19_parser.y +0 -2117
  65. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rb +0 -1412
  66. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rex +0 -179
  67. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rex.rb +0 -323
  68. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_parser.rb +0 -30
  69. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_parser_extras.rb +0 -1388
  70. data/bundle/ruby/3.1.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy.rb +0 -5
  71. /data/bundle/ruby/3.1.0/gems/{parallel-1.22.1 → parallel-1.23.0}/MIT-LICENSE.txt +0 -0
  72. /data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/debugging.md +0 -0
  73. /data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/gauntlet.md +0 -0
  74. /data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/rp_extensions.rb +0 -0
  75. /data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/rp_stringscanner.rb +0 -0
  76. /data/bundle/ruby/3.1.0/gems/{ruby_parser-3.19.2 → ruby_parser-3.20.3}/lib/ruby_lexer.rex +0 -0
  77. /data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/Manifest.txt +0 -0
  78. /data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/README.rdoc +0 -0
  79. /data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/composite_sexp_processor.rb +0 -0
  80. /data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/sexp_matcher.rb +0 -0
  81. /data/bundle/ruby/3.1.0/gems/{sexp_processor-4.16.1 → sexp_processor-4.17.0}/lib/unique.rb +0 -0
@@ -0,0 +1,3635 @@
1
+ # -*- racc -*-
2
+
3
+ #if V == 30
4
+ class Ruby30Parser
5
+ #elif V == 31
6
+ class Ruby31Parser
7
+ #elif V == 32
8
+ class Ruby32Parser
9
+ #else
10
+ fail "version not specified or supported on code generation"
11
+ #endif
12
+
13
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
14
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
15
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
16
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
17
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
18
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
19
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
20
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
21
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
22
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
23
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
24
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
25
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
26
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
27
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
28
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
29
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
30
+ tRATIONAL tIMAGINARY
31
+ tLABEL_END
32
+ tLONELY
33
+ tBDOT2 tBDOT3
34
+
35
+ preclow
36
+ nonassoc tLOWEST
37
+ nonassoc tLBRACE_ARG
38
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
39
+ left kOR kAND
40
+ right kNOT
41
+ nonassoc kDEFINED
42
+ right tEQL tOP_ASGN
43
+ left kRESCUE_MOD
44
+ right tEH tCOLON
45
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
46
+ left tOROP
47
+ left tANDOP
48
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
49
+ left tGT tGEQ tLT tLEQ
50
+ left tPIPE tCARET
51
+ left tAMPER2
52
+ left tLSHFT tRSHFT
53
+ left tPLUS tMINUS
54
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
55
+ right tUMINUS_NUM tUMINUS
56
+ right tPOW
57
+ right tBANG tTILDE tUPLUS
58
+ prechigh
59
+
60
+ rule
61
+
62
+ program: {
63
+ self.lexer.lex_state = EXPR_BEG
64
+ }
65
+ top_compstmt
66
+ {
67
+ result = new_compstmt val
68
+
69
+ lexer.cond.pop # local_pop
70
+ lexer.cmdarg.pop
71
+ }
72
+
73
+ top_compstmt: top_stmts opt_terms
74
+ {
75
+ stmt, _ = val
76
+ result = stmt
77
+ }
78
+
79
+ top_stmts: none
80
+ | top_stmt
81
+ | top_stmts terms top_stmt
82
+ {
83
+ result = self.block_append val[0], val[2]
84
+ }
85
+ | error top_stmt
86
+
87
+ top_stmt: stmt
88
+ | klBEGIN
89
+ {
90
+ if (self.in_def || self.in_single > 0) then
91
+ debug 1
92
+ yyerror "BEGIN in method"
93
+ end
94
+ self.env.extend
95
+ }
96
+ begin_block
97
+ {
98
+ (_, lineno), _, iter = val
99
+ iter.line lineno
100
+
101
+ (_, preexe,) = iter
102
+ preexe.line lineno
103
+
104
+ result = iter
105
+ }
106
+
107
+ begin_block: tLCURLY top_compstmt tRCURLY
108
+ {
109
+ (_, line), stmt, _ = val
110
+ result = new_iter s(:preexe).line(line), 0, stmt
111
+ }
112
+
113
+ bodystmt: compstmt opt_rescue k_else
114
+ {
115
+ res = _values[-2]
116
+ yyerror "else without rescue is useless" unless res
117
+ }
118
+ compstmt
119
+ opt_ensure
120
+ {
121
+ body, resc, _, _, els, ens = val
122
+
123
+ result = new_body [body, resc, els, ens]
124
+ }
125
+ | compstmt opt_rescue opt_ensure
126
+ {
127
+ body, resc, ens = val
128
+
129
+ result = new_body [body, resc, nil, ens]
130
+ }
131
+
132
+ compstmt: stmts opt_terms
133
+ {
134
+ result = new_compstmt val
135
+ }
136
+
137
+ stmts: none
138
+ | stmt_or_begin # TODO: newline_node ?
139
+ | stmts terms stmt_or_begin
140
+ {
141
+ result = self.block_append val[0], val[2]
142
+ }
143
+ | error stmt
144
+ {
145
+ result = val[1]
146
+ debug 2
147
+ }
148
+
149
+ stmt_or_begin: stmt
150
+ | klBEGIN
151
+ {
152
+ yyerror "BEGIN is permitted only at toplevel"
153
+ }
154
+ begin_block
155
+ {
156
+ result = val[2] # wtf?
157
+ }
158
+
159
+ stmt: kALIAS fitem
160
+ {
161
+ lexer.lex_state = EXPR_FNAME
162
+ }
163
+ fitem
164
+ {
165
+ (_, line), lhs, _, rhs = val
166
+ result = s(:alias, lhs, rhs).line(line).line line
167
+ }
168
+ | kALIAS tGVAR tGVAR
169
+ {
170
+ (_, line), (lhs, _), (rhs, _) = val
171
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
172
+ }
173
+ | kALIAS tGVAR tBACK_REF
174
+ {
175
+ (_, line), (lhs, _), (rhs, _) = val
176
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
177
+ }
178
+ | kALIAS tGVAR tNTH_REF
179
+ {
180
+ yyerror "can't make alias for the number variables"
181
+ }
182
+ | kUNDEF undef_list
183
+ {
184
+ result = val[1]
185
+ }
186
+ | stmt kIF_MOD expr_value
187
+ {
188
+ t, _, c = val
189
+ result = new_if c, t, nil
190
+ }
191
+ | stmt kUNLESS_MOD expr_value
192
+ {
193
+ f, _, c = val
194
+ result = new_if c, nil, f
195
+ }
196
+ | stmt kWHILE_MOD expr_value
197
+ {
198
+ e, _, c = val
199
+ result = new_while e, c, true
200
+ }
201
+ | stmt kUNTIL_MOD expr_value
202
+ {
203
+ e, _, c = val
204
+ result = new_until e, c, true
205
+ }
206
+ | stmt kRESCUE_MOD stmt
207
+ {
208
+ body, _, resbody = val
209
+
210
+ resbody = new_resbody s(:array).line(resbody.line), resbody
211
+ result = new_rescue body, resbody
212
+ }
213
+ | klEND tLCURLY compstmt tRCURLY
214
+ {
215
+ (_, line), _, stmt, _ = val
216
+
217
+ if (self.in_def || self.in_single > 0) then
218
+ debug 3
219
+ yyerror "END in method; use at_exit"
220
+ end
221
+
222
+ result = new_iter s(:postexe).line(line), 0, stmt
223
+ }
224
+ | command_asgn
225
+ | mlhs tEQL command_call
226
+ {
227
+ result = new_masgn val[0], val[2], :wrap
228
+ }
229
+ | lhs tEQL mrhs
230
+ {
231
+ lhs, _, rhs = val
232
+
233
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
234
+ }
235
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
236
+ {
237
+ # unwraps s(:to_ary, rhs)
238
+ lhs, _, (_, rhs), _, resbody = val
239
+
240
+ resbody = new_resbody s(:array).line(resbody.line), resbody
241
+
242
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
243
+ }
244
+ | mlhs tEQL mrhs_arg
245
+ {
246
+ result = new_masgn val[0], val[2]
247
+ }
248
+ | expr
249
+
250
+ command_asgn: lhs tEQL command_rhs
251
+ {
252
+ result = new_assign val[0], val[2]
253
+ }
254
+ # | lhs tEQL command_asgn
255
+ # {
256
+ # result = new_assign val[0], val[2]
257
+ # }
258
+ | var_lhs tOP_ASGN command_rhs
259
+ {
260
+ result = new_op_asgn val
261
+ }
262
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
263
+ {
264
+ result = new_op_asgn1 val
265
+ }
266
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
267
+ {
268
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
269
+
270
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
271
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
272
+ result.line prim.line
273
+ }
274
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
275
+ {
276
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
277
+
278
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
279
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
280
+ result.line prim.line
281
+ }
282
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
283
+ {
284
+ lhs1, _, (lhs2, line), (id, _), rhs = val
285
+
286
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
287
+ }
288
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
289
+ {
290
+ lhs1, _, (lhs2, line), (id, _), rhs = val
291
+
292
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
293
+ }
294
+ #if V > 30
295
+ | defn_head f_opt_paren_args tEQL command
296
+ {
297
+ result = new_endless_defn val
298
+ }
299
+ | defn_head f_opt_paren_args tEQL command kRESCUE_MOD arg
300
+ {
301
+ result = new_endless_defn val
302
+ }
303
+ | defs_head f_opt_paren_args tEQL command
304
+ {
305
+ result = new_endless_defs val
306
+ }
307
+ | defs_head f_opt_paren_args tEQL command kRESCUE_MOD arg
308
+ {
309
+ result = new_endless_defs val
310
+ }
311
+ #endif
312
+ | backref tOP_ASGN command_rhs
313
+ {
314
+ self.backref_assign_error val[0]
315
+ }
316
+
317
+ command_rhs: command_call =tOP_ASGN
318
+ {
319
+ expr, = val
320
+ result = value_expr expr
321
+ }
322
+ | command_call kRESCUE_MOD stmt
323
+ {
324
+ expr, (_, line), resbody = val
325
+
326
+ expr = value_expr expr
327
+ ary = s(:array).line line
328
+ result = new_rescue(expr, new_resbody(ary, resbody))
329
+ }
330
+ | command_asgn
331
+
332
+ expr: command_call
333
+ | expr kAND expr
334
+ {
335
+ lhs, _, rhs = val
336
+ result = logical_op :and, lhs, rhs
337
+ }
338
+ | expr kOR expr
339
+ {
340
+ lhs, _, rhs = val
341
+ result = logical_op :or, lhs, rhs
342
+ }
343
+ | kNOT opt_nl expr
344
+ {
345
+ (_, line), _, expr = val
346
+ result = new_call(expr, :"!").line line
347
+ # REFACTOR: call_uni_op
348
+ }
349
+ | tBANG command_call
350
+ {
351
+ _, cmd = val
352
+ result = new_call(cmd, :"!").line cmd.line
353
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
354
+ # REFACTOR: call_uni_op -- see parse26.y
355
+ }
356
+ | arg tASSOC
357
+ {
358
+ # value_expr($1);
359
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
360
+ self.lexer.command_start = false
361
+ result = self.in_kwarg
362
+ self.in_kwarg = true
363
+ self.env.extend
364
+ }
365
+ #if V == 30
366
+ p_expr
367
+ #else
368
+ p_top_expr_body
369
+ #endif
370
+ {
371
+ lhs, _, in_kwarg, rhs = val
372
+
373
+ self.env.unextend
374
+ self.in_kwarg = in_kwarg
375
+
376
+ rhs = new_in rhs, nil, nil, rhs.line
377
+ result = new_case lhs, rhs, rhs.line
378
+ }
379
+ | arg
380
+ kIN
381
+ {
382
+ # TODO? value_expr($1);
383
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
384
+ self.lexer.command_start = false
385
+ result = self.in_kwarg
386
+ self.in_kwarg = true
387
+ self.env.extend
388
+ }
389
+ #if V == 30
390
+ p_expr
391
+ #else
392
+ p_top_expr_body
393
+ #endif
394
+ {
395
+ self.env.unextend
396
+
397
+ expr, _, old_kwarg, pat = val
398
+
399
+ expr = value_expr expr
400
+
401
+ self.in_kwarg = old_kwarg
402
+ pat_in = new_in pat, nil, nil, expr.line
403
+ result = new_case expr, pat_in, expr.line
404
+ }
405
+ | arg =tLBRACE_ARG
406
+
407
+ def_name: fname
408
+ {
409
+ # TODO: numparam_name(p, fname);
410
+
411
+ (id, line), = val
412
+ old_in_def = self.in_def
413
+
414
+ self.in_def = true # group = local_push
415
+ self.env.extend
416
+ lexer.cmdarg.push false
417
+ lexer.cond.push false
418
+
419
+ result = [id.to_sym, line, old_in_def]
420
+ }
421
+ defn_head: k_def def_name
422
+ {
423
+ _, name = val
424
+ result = name
425
+ }
426
+ defs_head: k_def singleton dot_or_colon
427
+ {
428
+ lexer.lex_state = EXPR_FNAME
429
+ self.in_argdef = true
430
+ }
431
+ def_name
432
+ {
433
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
434
+ self.in_single += 1 # TODO: remove?
435
+
436
+ # self.in_def = true # local_push
437
+ # self.env.extend
438
+ # lexer.cmdarg.push false
439
+ # lexer.cond.push false
440
+
441
+ _, recv, _, _, name = val
442
+
443
+ result = [recv, name]
444
+ }
445
+
446
+ expr_value: expr
447
+ {
448
+ result = value_expr(val[0])
449
+ }
450
+
451
+ expr_value_do: {
452
+ lexer.cond.push true
453
+ }
454
+ expr_value do
455
+ {
456
+ lexer.cond.pop
457
+ }
458
+ {
459
+ _, expr, _, _ = val
460
+ result = expr
461
+ }
462
+
463
+ command_call: command
464
+ | block_command
465
+
466
+ block_command: block_call
467
+ | block_call call_op2 operation2 command_args
468
+ {
469
+ blk, _, (msg, _line), args = val
470
+ result = new_call(blk, msg.to_sym, args).line blk.line
471
+ }
472
+
473
+ cmd_brace_block: tLBRACE_ARG
474
+ {
475
+ # self.env.extend(:dynamic)
476
+ result = self.lexer.lineno
477
+ }
478
+ brace_body tRCURLY
479
+ {
480
+ _, line, body, _ = val
481
+
482
+ result = body
483
+ result.line line
484
+
485
+ # self.env.unextend
486
+ }
487
+
488
+ fcall: operation
489
+ {
490
+ (msg, line), = val
491
+ result = new_call(nil, msg.to_sym).line line
492
+ }
493
+
494
+ command: fcall command_args =tLOWEST
495
+ {
496
+ call, args = val
497
+ result = call.concat args.sexp_body
498
+ }
499
+ | fcall command_args cmd_brace_block
500
+ {
501
+ call, args, block = val
502
+
503
+ result = call.concat args.sexp_body
504
+
505
+ if block then
506
+ block_dup_check result, block
507
+
508
+ result, operation = block, result
509
+ result.insert 1, operation
510
+ end
511
+ }
512
+ | primary_value call_op operation2 command_args =tLOWEST
513
+ {
514
+ lhs, callop, (op, _), args = val
515
+
516
+ result = new_call lhs, op.to_sym, args, callop
517
+ result.line lhs.line
518
+ }
519
+ | primary_value call_op operation2 command_args cmd_brace_block
520
+ {
521
+ recv, _, (msg, _line), args, block = val
522
+ call = new_call recv, msg.to_sym, args, val[1]
523
+
524
+ block_dup_check call, block
525
+
526
+ block.insert 1, call
527
+ result = block
528
+ }
529
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
530
+ {
531
+ lhs, _, (id, line), args = val
532
+
533
+ result = new_call lhs, id.to_sym, args
534
+ result.line line
535
+ }
536
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
537
+ {
538
+ recv, _, (msg, _line), args, block = val
539
+ call = new_call recv, msg.to_sym, args
540
+
541
+ block_dup_check call, block
542
+
543
+ block.insert 1, call
544
+ result = block
545
+ }
546
+ | kSUPER command_args
547
+ {
548
+ result = new_super val[1]
549
+ }
550
+ | kYIELD command_args
551
+ {
552
+ (_, line), args = val
553
+ result = new_yield args
554
+ result.line line # TODO: push to new_yield
555
+ }
556
+ | k_return call_args
557
+ {
558
+ line = val[0].last
559
+ result = s(:return, ret_args(val[1])).line(line)
560
+ }
561
+ | kBREAK call_args
562
+ {
563
+ (_, line), args = val
564
+ result = s(:break, ret_args(args)).line line
565
+ }
566
+ | kNEXT call_args
567
+ {
568
+ line = val[0].last
569
+ result = s(:next, ret_args(val[1])).line(line)
570
+ }
571
+
572
+ mlhs: mlhs_basic
573
+ | tLPAREN mlhs_inner rparen
574
+ {
575
+ result = val[1]
576
+ }
577
+
578
+ mlhs_inner: mlhs_basic
579
+ | tLPAREN mlhs_inner rparen
580
+ {
581
+ _, arg, _ = val
582
+ l = arg.line
583
+
584
+ result = s(:masgn, s(:array, arg).line(l)).line l
585
+ }
586
+
587
+ mlhs_basic: mlhs_head
588
+ {
589
+ head, = val
590
+ result = s(:masgn, head).line head.line
591
+ }
592
+ | mlhs_head mlhs_item
593
+ {
594
+ lhs, rhs = val
595
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
596
+ }
597
+ | mlhs_head tSTAR mlhs_node
598
+ {
599
+ head, _, tail = val
600
+ head << s(:splat, tail).line(tail.line)
601
+ result = s(:masgn, head).line head.line
602
+ }
603
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
604
+ {
605
+ ary1, _, splat, _, ary2 = val
606
+
607
+ result = list_append ary1, s(:splat, splat).line(splat.line)
608
+ result.concat ary2.sexp_body
609
+ result = s(:masgn, result).line result.line
610
+ }
611
+ | mlhs_head tSTAR
612
+ {
613
+ head, _ = val
614
+ l = head.line
615
+ result = s(:masgn, head << s(:splat).line(l)).line l
616
+ }
617
+ | mlhs_head tSTAR tCOMMA mlhs_post
618
+ {
619
+ head, _, _, post = val
620
+ ary = list_append head, s(:splat).line(head.line)
621
+ ary.concat post.sexp_body
622
+ result = s(:masgn, ary).line ary.line
623
+ }
624
+ | tSTAR mlhs_node
625
+ {
626
+ _, node = val
627
+ l = node.line
628
+ splat = s(:splat, node).line l
629
+ ary = s(:array, splat).line l
630
+ result = s(:masgn, ary).line l
631
+ }
632
+ | tSTAR mlhs_node tCOMMA mlhs_post
633
+ {
634
+ _, node, _, post = val
635
+
636
+ splat = s(:splat, node).line node.line
637
+ ary = s(:array, splat).line splat.line
638
+ ary.concat post.sexp_body
639
+ result = s(:masgn, ary).line ary.line
640
+ }
641
+ | tSTAR
642
+ {
643
+ (_, l), = val
644
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
645
+ }
646
+ | tSTAR tCOMMA mlhs_post
647
+ {
648
+ _, _, post = val
649
+ l = post.line
650
+
651
+ splat = s(:splat).line l
652
+ ary = s(:array, splat, *post.sexp_body).line l
653
+ result = s(:masgn, ary).line l
654
+ }
655
+
656
+ mlhs_item: mlhs_node
657
+ | tLPAREN mlhs_inner rparen
658
+ {
659
+ result = val[1]
660
+ }
661
+
662
+ mlhs_head: mlhs_item tCOMMA
663
+ {
664
+ lhs, _ = val
665
+ result = s(:array, lhs).line lhs.line
666
+ }
667
+ | mlhs_head mlhs_item tCOMMA
668
+ {
669
+ result = val[0] << val[1].compact
670
+ }
671
+
672
+ mlhs_post: mlhs_item
673
+ {
674
+ item, = val
675
+ result = s(:array, item).line item.line
676
+ }
677
+ | mlhs_post tCOMMA mlhs_item
678
+ {
679
+ result = list_append val[0], val[2]
680
+ }
681
+
682
+ mlhs_node: user_variable
683
+ {
684
+ result = self.assignable val[0]
685
+ }
686
+ | keyword_variable
687
+ {
688
+ result = self.assignable val[0]
689
+ }
690
+ | primary_value tLBRACK2 opt_call_args rbracket
691
+ {
692
+ result = self.aryset val[0], val[2]
693
+ }
694
+ | primary_value call_op tIDENTIFIER
695
+ {
696
+ lhs, call_op, (id, _line) = val
697
+
698
+ result = new_attrasgn lhs, id, call_op
699
+ }
700
+ | primary_value tCOLON2 tIDENTIFIER
701
+ {
702
+ recv, _, (id, _line) = val
703
+ result = new_attrasgn recv, id
704
+ }
705
+ | primary_value call_op tCONSTANT
706
+ {
707
+ lhs, call_op, (id, _line) = val
708
+
709
+ result = new_attrasgn lhs, id, call_op
710
+ }
711
+ | primary_value tCOLON2 tCONSTANT
712
+ {
713
+ if (self.in_def || self.in_single > 0) then
714
+ debug 4
715
+ yyerror "dynamic constant assignment"
716
+ end
717
+
718
+ expr, _, (id, _line) = val
719
+ l = expr.line
720
+
721
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
722
+ }
723
+ | tCOLON3 tCONSTANT
724
+ {
725
+ if (self.in_def || self.in_single > 0) then
726
+ debug 5
727
+ yyerror "dynamic constant assignment"
728
+ end
729
+
730
+ _, (id, l) = val
731
+
732
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
733
+ }
734
+ | backref
735
+ {
736
+ ref, = val
737
+
738
+ self.backref_assign_error ref
739
+ }
740
+
741
+ lhs: user_variable
742
+ {
743
+ var, = val
744
+
745
+ result = self.assignable var
746
+ }
747
+ | keyword_variable
748
+ {
749
+ var, = val
750
+
751
+ result = self.assignable var
752
+
753
+ debug 6
754
+ }
755
+ | primary_value tLBRACK2 opt_call_args rbracket
756
+ {
757
+ lhs, _, args, _ = val
758
+
759
+ result = self.aryset lhs, args
760
+ }
761
+ | primary_value call_op tIDENTIFIER # REFACTOR
762
+ {
763
+ lhs, op, (id, _line) = val
764
+
765
+ result = new_attrasgn lhs, id, op
766
+ }
767
+ | primary_value tCOLON2 tIDENTIFIER
768
+ {
769
+ lhs, _, (id, _line) = val
770
+
771
+ result = new_attrasgn lhs, id
772
+ }
773
+ | primary_value call_op tCONSTANT # REFACTOR?
774
+ {
775
+ lhs, call_op, (id, _line) = val
776
+
777
+ result = new_attrasgn lhs, id, call_op
778
+ }
779
+ | primary_value tCOLON2 tCONSTANT
780
+ {
781
+ expr, _, (id, _line) = val
782
+
783
+ if (self.in_def || self.in_single > 0) then
784
+ debug 7
785
+ yyerror "dynamic constant assignment"
786
+ end
787
+
788
+ l = expr.line
789
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
790
+ }
791
+ | tCOLON3 tCONSTANT
792
+ {
793
+ _, (id, l) = val
794
+
795
+ if (self.in_def || self.in_single > 0) then
796
+ debug 8
797
+ yyerror "dynamic constant assignment"
798
+ end
799
+
800
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
801
+ }
802
+ | backref
803
+ {
804
+ self.backref_assign_error val[0]
805
+ }
806
+
807
+ cname: tIDENTIFIER
808
+ {
809
+ yyerror "class/module name must be CONSTANT"
810
+ }
811
+ | tCONSTANT
812
+
813
+ cpath: tCOLON3 cname
814
+ {
815
+ result = wrap :colon3, val[1]
816
+ }
817
+ | cname
818
+ {
819
+ (id, line), = val
820
+ result = [id.to_sym, line] # TODO: sexp?
821
+ }
822
+ | primary_value tCOLON2 cname
823
+ {
824
+ pval, _, (name, _line) = val
825
+
826
+ result = s(:colon2, pval, name.to_sym)
827
+ result.line pval.line
828
+ }
829
+
830
+ fname: tIDENTIFIER | tCONSTANT | tFID
831
+ | op
832
+ {
833
+ lexer.lex_state = EXPR_END
834
+ }
835
+
836
+ | reswords
837
+
838
+ fitem: fname
839
+ {
840
+ result = wrap :lit, val[0]
841
+ }
842
+ | symbol
843
+
844
+ undef_list: fitem
845
+ {
846
+ result = new_undef val[0]
847
+ }
848
+ |
849
+ undef_list tCOMMA
850
+ {
851
+ lexer.lex_state = EXPR_FNAME
852
+ }
853
+ fitem
854
+ {
855
+ result = new_undef val[0], val[3]
856
+ }
857
+
858
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
859
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
860
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
861
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
862
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
863
+
864
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
865
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
866
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
867
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
868
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
869
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
870
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
871
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
872
+ | kUNTIL
873
+
874
+ arg: lhs tEQL arg_rhs
875
+ {
876
+ result = new_assign val[0], val[2]
877
+ }
878
+ | var_lhs tOP_ASGN arg_rhs
879
+ {
880
+ result = new_op_asgn val
881
+ }
882
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
883
+ {
884
+ result = new_op_asgn1 val
885
+ }
886
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
887
+ {
888
+ result = new_op_asgn2 val
889
+ }
890
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
891
+ {
892
+ result = new_op_asgn2 val
893
+ }
894
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
895
+ {
896
+ lhs, _, (id, _line), (op, _), rhs = val
897
+
898
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
899
+ }
900
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
901
+ {
902
+ lhs1, _, (lhs2, _line), op, rhs = val
903
+
904
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
905
+ result = new_const_op_asgn [lhs, op, rhs]
906
+ }
907
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
908
+ {
909
+ _, lhs, op, rhs = val
910
+
911
+ lhs = wrap :colon3, lhs
912
+ result = new_const_op_asgn [lhs, op, rhs]
913
+ }
914
+ | backref tOP_ASGN arg_rhs
915
+ {
916
+ # TODO: lhs = var_field val[0]
917
+ asgn = new_op_asgn val
918
+ result = self.backref_assign_error asgn
919
+ }
920
+ | arg tDOT2 arg
921
+ {
922
+ v1, v2 = val[0], val[2]
923
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
924
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
925
+ else
926
+ result = s(:dot2, v1, v2).line v1.line
927
+ end
928
+ }
929
+ | arg tDOT3 arg
930
+ {
931
+ v1, v2 = val[0], val[2]
932
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
933
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
934
+ else
935
+ result = s(:dot3, v1, v2).line v1.line
936
+ end
937
+ }
938
+ | arg tDOT2
939
+ {
940
+ v1, _ = val
941
+ v2 = nil
942
+
943
+ result = s(:dot2, v1, v2).line v1.line
944
+ }
945
+ | arg tDOT3
946
+ {
947
+ v1, _ = val
948
+ v2 = nil
949
+
950
+ result = s(:dot3, v1, v2).line v1.line
951
+ }
952
+
953
+ | tBDOT2 arg
954
+ {
955
+ _, v2, = val
956
+ v1 = nil
957
+
958
+ result = s(:dot2, v1, v2).line v2.line
959
+ }
960
+ | tBDOT3 arg
961
+ {
962
+ _, v2 = val
963
+ v1 = nil
964
+
965
+ result = s(:dot3, v1, v2).line v2.line
966
+ }
967
+
968
+ | arg tPLUS arg
969
+ {
970
+ result = new_call val[0], :+, argl(val[2])
971
+ }
972
+ | arg tMINUS arg
973
+ {
974
+ result = new_call val[0], :-, argl(val[2])
975
+ }
976
+ | arg tSTAR2 arg # TODO: rename
977
+ {
978
+ result = new_call val[0], :*, argl(val[2])
979
+ }
980
+ | arg tDIVIDE arg
981
+ {
982
+ result = new_call val[0], :"/", argl(val[2])
983
+ }
984
+ | arg tPERCENT arg
985
+ {
986
+ result = new_call val[0], :"%", argl(val[2])
987
+ }
988
+ | arg tPOW arg
989
+ {
990
+ result = new_call val[0], :**, argl(val[2])
991
+ }
992
+ | tUMINUS_NUM simple_numeric tPOW arg
993
+ {
994
+ _, num, _, arg = val
995
+ lit = wrap :lit, num
996
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
997
+
998
+ }
999
+ | tUPLUS arg
1000
+ {
1001
+ result = new_call val[1], :"+@"
1002
+ }
1003
+ | tUMINUS arg
1004
+ {
1005
+ result = new_call val[1], :"-@"
1006
+ }
1007
+ | arg tPIPE arg
1008
+ {
1009
+ result = new_call val[0], :"|", argl(val[2])
1010
+ }
1011
+ | arg tCARET arg
1012
+ {
1013
+ result = new_call val[0], :"^", argl(val[2])
1014
+ }
1015
+ | arg tAMPER2 arg
1016
+ {
1017
+ result = new_call val[0], :"&", argl(val[2])
1018
+ }
1019
+ | arg tCMP arg
1020
+ {
1021
+ result = new_call val[0], :"<=>", argl(val[2])
1022
+ }
1023
+ | rel_expr =tCMP
1024
+ | arg tEQ arg
1025
+ {
1026
+ result = new_call val[0], :"==", argl(val[2])
1027
+ }
1028
+ | arg tEQQ arg
1029
+ {
1030
+ result = new_call val[0], :"===", argl(val[2])
1031
+ }
1032
+ | arg tNEQ arg
1033
+ {
1034
+ result = new_call val[0], :"!=", argl(val[2])
1035
+ }
1036
+ | arg tMATCH arg
1037
+ {
1038
+ lhs, _, rhs = val
1039
+ result = new_match lhs, rhs
1040
+ }
1041
+ | arg tNMATCH arg
1042
+ {
1043
+ lhs, _, rhs = val
1044
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
1045
+ }
1046
+ | tBANG arg
1047
+ {
1048
+ _, arg = val
1049
+ result = new_call arg, :"!"
1050
+ result.line arg.line
1051
+ }
1052
+ | tTILDE arg
1053
+ {
1054
+ result = new_call value_expr(val[1]), :"~"
1055
+ }
1056
+ | arg tLSHFT arg
1057
+ {
1058
+ val[0] = value_expr val[0]
1059
+ val[2] = value_expr val[2]
1060
+ result = new_call val[0], :"\<\<", argl(val[2])
1061
+ }
1062
+ | arg tRSHFT arg
1063
+ {
1064
+ val[0] = value_expr val[0]
1065
+ val[2] = value_expr val[2]
1066
+ result = new_call val[0], :">>", argl(val[2])
1067
+ }
1068
+ | arg tANDOP arg
1069
+ {
1070
+ result = logical_op :and, val[0], val[2]
1071
+ }
1072
+ | arg tOROP arg
1073
+ {
1074
+ result = logical_op :or, val[0], val[2]
1075
+ }
1076
+ | kDEFINED opt_nl arg
1077
+ {
1078
+ (_, line), _, arg = val
1079
+ result = s(:defined, arg).line line
1080
+ }
1081
+ | arg tEH arg opt_nl tCOLON arg
1082
+ {
1083
+ c, _, t, _, _, f = val
1084
+ result = s(:if, c, t, f).line c.line
1085
+ }
1086
+ | defn_head f_opt_paren_args tEQL arg
1087
+ {
1088
+ result = new_endless_defn val
1089
+ }
1090
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1091
+ {
1092
+ result = new_endless_defn val
1093
+ }
1094
+ | defs_head f_opt_paren_args tEQL arg
1095
+ {
1096
+ result = new_endless_defs val
1097
+ }
1098
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1099
+ {
1100
+ result = new_endless_defs val
1101
+ }
1102
+ | primary
1103
+
1104
+ relop: tGT
1105
+ | tLT
1106
+ | tGEQ
1107
+ | tLEQ
1108
+
1109
+ rel_expr: arg relop arg =tGT
1110
+ {
1111
+ lhs, (op, _), rhs = val
1112
+ result = new_call lhs, op.to_sym, argl(rhs)
1113
+ }
1114
+ | rel_expr relop arg =tGT
1115
+ {
1116
+ lhs, (op, _), rhs = val
1117
+ warn "comparison '%s' after comparison", op
1118
+ result = new_call lhs, op.to_sym, argl(rhs)
1119
+ }
1120
+
1121
+ arg_value: arg
1122
+ {
1123
+ result = value_expr(val[0])
1124
+ }
1125
+
1126
+ aref_args: none
1127
+ | args trailer
1128
+ {
1129
+ result = args [val[0]]
1130
+ }
1131
+ | args tCOMMA assocs trailer
1132
+ {
1133
+ result = args [val[0], array_to_hash(val[2])]
1134
+ }
1135
+ | assocs trailer
1136
+ {
1137
+ result = args [array_to_hash(val[0])]
1138
+ }
1139
+
1140
+ arg_rhs: arg =tOP_ASGN
1141
+ | arg kRESCUE_MOD arg
1142
+ {
1143
+ body, (_, line), resbody = val
1144
+ body = value_expr body
1145
+ resbody = remove_begin resbody
1146
+
1147
+ ary = s(:array).line line
1148
+ result = new_rescue(body, new_resbody(ary, resbody))
1149
+ }
1150
+
1151
+ paren_args: tLPAREN2 opt_call_args rparen
1152
+ {
1153
+ _, args, (_, line_max) = val
1154
+
1155
+ result = args
1156
+ result.line_max = line_max if args
1157
+ }
1158
+ | tLPAREN2 args tCOMMA args_forward rparen
1159
+ {
1160
+ yyerror "Unexpected ..." unless
1161
+ self.lexer.is_local_id(:"*") &&
1162
+ self.lexer.is_local_id(:"**") &&
1163
+ self.lexer.is_local_id(:"&")
1164
+
1165
+ result = call_args val
1166
+ }
1167
+ | tLPAREN2 args_forward rparen
1168
+ {
1169
+ yyerror "Unexpected ..." unless
1170
+ self.lexer.is_local_id(:"*") &&
1171
+ self.lexer.is_local_id(:"**") &&
1172
+ self.lexer.is_local_id(:"&")
1173
+
1174
+ result = call_args val
1175
+ }
1176
+
1177
+ opt_paren_args: none
1178
+ | paren_args
1179
+
1180
+ opt_call_args: none
1181
+ | call_args
1182
+ | args tCOMMA
1183
+ {
1184
+ result = args val
1185
+ }
1186
+ | args tCOMMA assocs tCOMMA
1187
+ {
1188
+ result = args [val[0], array_to_hash(val[2])]
1189
+ }
1190
+ | assocs tCOMMA
1191
+ {
1192
+ result = args [array_to_hash(val[0])]
1193
+ }
1194
+
1195
+ call_args: command
1196
+ {
1197
+ warning "parenthesize argument(s) for future version"
1198
+ result = call_args val
1199
+ }
1200
+ | args opt_block_arg
1201
+ {
1202
+ result = call_args val
1203
+ }
1204
+ | assocs opt_block_arg
1205
+ {
1206
+ result = call_args [array_to_hash(val[0]), val[1]]
1207
+ }
1208
+ | args tCOMMA assocs opt_block_arg
1209
+ {
1210
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1211
+ }
1212
+ | block_arg
1213
+ {
1214
+ result = call_args val
1215
+ }
1216
+
1217
+ command_args: {
1218
+ # parse26.y line 2200
1219
+
1220
+ # If call_args starts with a open paren '(' or
1221
+ # '[', look-ahead reading of the letters calls
1222
+ # CMDARG_PUSH(0), but the push must be done
1223
+ # after CMDARG_PUSH(1). So this code makes them
1224
+ # consistent by first cancelling the premature
1225
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1226
+ # finally redoing CMDARG_PUSH(0).
1227
+
1228
+ result = yychar = self.last_token_type.first
1229
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1230
+ lexer.cmdarg.pop if lookahead
1231
+ lexer.cmdarg.push true
1232
+ lexer.cmdarg.push false if lookahead
1233
+ }
1234
+ call_args
1235
+ {
1236
+ yychar, args = val
1237
+
1238
+ # call_args can be followed by tLBRACE_ARG (that
1239
+ # does CMDARG_PUSH(0) in the lexer) but the push
1240
+ # must be done after CMDARG_POP() in the parser.
1241
+ # So this code does CMDARG_POP() to pop 0 pushed
1242
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1243
+ # by command_args, and CMDARG_PUSH(0) to restore
1244
+ # back the flag set by tLBRACE_ARG.
1245
+
1246
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1247
+ lexer.cmdarg.pop if lookahead
1248
+ lexer.cmdarg.pop
1249
+ lexer.cmdarg.push false if lookahead
1250
+ result = args
1251
+ }
1252
+
1253
+ block_arg: tAMPER arg_value
1254
+ {
1255
+ _, arg = val
1256
+ result = s(:block_pass, arg).line arg.line
1257
+ }
1258
+ #if V > 30
1259
+ | tAMPER
1260
+ {
1261
+ (_, line), = val
1262
+ result = s(:block_pass).line line
1263
+ }
1264
+ #endif
1265
+
1266
+ opt_block_arg: tCOMMA block_arg
1267
+ {
1268
+ result = val[1]
1269
+ }
1270
+ | none
1271
+
1272
+ args: arg_value
1273
+ {
1274
+ arg, = val
1275
+ lineno = arg.line
1276
+
1277
+ result = s(:array, arg).line lineno
1278
+ }
1279
+ | tSTAR arg_value
1280
+ {
1281
+ _, arg = val
1282
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1283
+ }
1284
+ #if V >= 32
1285
+ | tSTAR
1286
+ {
1287
+ (_, line), = val
1288
+ result = s(:array, s(:splat).line(line)).line line
1289
+ }
1290
+ #endif
1291
+ | args tCOMMA arg_value
1292
+ {
1293
+ args, _, id = val
1294
+ result = self.list_append args, id
1295
+ }
1296
+ | args tCOMMA tSTAR arg_value
1297
+ {
1298
+ args, _, (_, line), id = val
1299
+ result = self.list_append args, s(:splat, id).line(line)
1300
+ }
1301
+ #if V >= 32
1302
+ | args tCOMMA tSTAR
1303
+ {
1304
+ args, _, (_, line) = val
1305
+ result = self.list_append args, s(:splat).line(line)
1306
+ }
1307
+ #endif
1308
+
1309
+ mrhs_arg: mrhs
1310
+ {
1311
+ result = new_masgn_arg val[0]
1312
+ }
1313
+ | arg_value
1314
+ {
1315
+ result = new_masgn_arg val[0], :wrap
1316
+ }
1317
+
1318
+ mrhs: args tCOMMA arg_value
1319
+ {
1320
+ result = val[0] << val[2]
1321
+ }
1322
+ | args tCOMMA tSTAR arg_value
1323
+ {
1324
+ arg, _, _, splat = val
1325
+ result = self.arg_concat arg, splat
1326
+ }
1327
+ | tSTAR arg_value
1328
+ {
1329
+ _, arg = val
1330
+ result = s(:splat, arg).line arg.line
1331
+ }
1332
+
1333
+ primary: literal
1334
+ | strings
1335
+ | xstring
1336
+ | regexp
1337
+ | words
1338
+ | qwords
1339
+ | symbols
1340
+ | qsymbols
1341
+ | var_ref
1342
+ | backref
1343
+ | tFID
1344
+ {
1345
+ (msg, line), = val
1346
+ result = new_call nil, msg.to_sym
1347
+ result.line line
1348
+ }
1349
+ | k_begin
1350
+ {
1351
+ lexer.cmdarg.push false
1352
+ }
1353
+ bodystmt k_end
1354
+ {
1355
+ lexer.cmdarg.pop
1356
+ result = new_begin val
1357
+ }
1358
+ | tLPAREN_ARG
1359
+ {
1360
+ lexer.lex_state = EXPR_ENDARG
1361
+ }
1362
+ rparen
1363
+ {
1364
+ (_, line), _, _ = val
1365
+ result = s(:begin).line line
1366
+ }
1367
+ | tLPAREN_ARG
1368
+ stmt
1369
+ {
1370
+ lexer.lex_state = EXPR_ENDARG
1371
+ }
1372
+ rparen
1373
+ {
1374
+ _, stmt, _, _, = val
1375
+ # warning "(...) interpreted as grouped expression"
1376
+ result = stmt
1377
+ }
1378
+ | tLPAREN compstmt tRPAREN
1379
+ {
1380
+ (_, line), stmt, _ = val
1381
+ result = stmt || s(:nil).line(line)
1382
+ result.paren = true
1383
+ }
1384
+ | primary_value tCOLON2 tCONSTANT
1385
+ {
1386
+ expr, _, (id, _line) = val
1387
+
1388
+ result = s(:colon2, expr, id.to_sym).line expr.line
1389
+ }
1390
+ | tCOLON3 tCONSTANT
1391
+ {
1392
+ result = wrap :colon3, val[1]
1393
+ }
1394
+ | tLBRACK aref_args rbracket
1395
+ {
1396
+ (_, line), args, (_, line_max) = val
1397
+
1398
+ result = args || s(:array)
1399
+ result.sexp_type = :array # aref_args is :args
1400
+ result.line line
1401
+ result.line_max = line_max
1402
+ }
1403
+ | tLBRACE
1404
+ {
1405
+ result = self.lexer.lineno
1406
+ }
1407
+ assoc_list tRCURLY
1408
+ {
1409
+ result = new_hash val
1410
+ }
1411
+ | k_return
1412
+ {
1413
+ (_, line), = val
1414
+ result = s(:return).line line
1415
+ }
1416
+ | kYIELD tLPAREN2 call_args rparen
1417
+ {
1418
+ (_, line), _, args, _ = val
1419
+
1420
+ result = new_yield(args).line line
1421
+ }
1422
+ | kYIELD tLPAREN2 rparen
1423
+ {
1424
+ (_, line), _, _ = val
1425
+
1426
+ result = new_yield.line line
1427
+ }
1428
+ | kYIELD
1429
+ {
1430
+ (_, line), = val
1431
+
1432
+ result = new_yield.line line
1433
+ }
1434
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1435
+ {
1436
+ (_, line), _, _, arg, _ = val
1437
+
1438
+ result = s(:defined, arg).line line
1439
+ }
1440
+ | kNOT tLPAREN2 expr rparen
1441
+ {
1442
+ _, _, lhs, _ = val
1443
+ result = new_call lhs, :"!"
1444
+ }
1445
+ | kNOT tLPAREN2 rparen
1446
+ {
1447
+ debug 9
1448
+ }
1449
+ | fcall brace_block
1450
+ {
1451
+ call, iter = val
1452
+
1453
+ iter.insert 1, call
1454
+ result = iter
1455
+ # FIX: probably not: call.line = iter.line
1456
+ }
1457
+ | method_call
1458
+ | method_call brace_block
1459
+ {
1460
+ call, iter = val[0], val[1]
1461
+ block_dup_check call, iter
1462
+ iter.insert 1, call # FIX
1463
+ result = iter
1464
+ }
1465
+ | lambda
1466
+ {
1467
+ expr, = val
1468
+ result = expr
1469
+ }
1470
+ | k_if expr_value then compstmt if_tail k_end
1471
+ {
1472
+ _, c, _, t, f, _ = val
1473
+ result = new_if c, t, f
1474
+ }
1475
+ | k_unless expr_value then compstmt opt_else k_end
1476
+ {
1477
+ _, c, _, t, f, _ = val
1478
+ result = new_if c, f, t
1479
+ }
1480
+ | k_while expr_value_do compstmt k_end
1481
+ {
1482
+ _, cond, body, _ = val
1483
+ result = new_while body, cond, true
1484
+ }
1485
+ | k_until expr_value_do compstmt k_end
1486
+ {
1487
+ _, cond, body, _ = val
1488
+ result = new_until body, cond, true
1489
+ }
1490
+ | k_case expr_value opt_terms case_body k_end
1491
+ {
1492
+ (_, line), expr, _, body, _ = val
1493
+ result = new_case expr, body, line
1494
+ }
1495
+ | k_case opt_terms case_body k_end
1496
+ {
1497
+ (_, line), _, body, _ = val
1498
+ result = new_case nil, body, line
1499
+ }
1500
+ | k_case expr_value opt_terms p_case_body k_end
1501
+ {
1502
+ (_, line), expr, _, body, _ = val
1503
+
1504
+ result = new_case expr, body, line
1505
+ }
1506
+ | k_for for_var kIN expr_value_do compstmt k_end
1507
+ {
1508
+ _, var, _, iter, body, _ = val
1509
+ result = new_for iter, var, body
1510
+ }
1511
+ | k_class
1512
+ cpath superclass
1513
+ {
1514
+ if (self.in_def || self.in_single > 0) then
1515
+ yyerror "class definition in method body"
1516
+ end
1517
+ self.env.extend
1518
+ }
1519
+ bodystmt k_end
1520
+ {
1521
+ result = new_class val
1522
+ self.env.unextend
1523
+ self.lexer.ignore_body_comments
1524
+ }
1525
+ | k_class tLSHFT
1526
+ expr
1527
+ {
1528
+ result = self.in_def
1529
+ self.in_def = false
1530
+ }
1531
+ term
1532
+ {
1533
+ result = self.in_single
1534
+ self.in_single = 0
1535
+ self.env.extend
1536
+ }
1537
+ bodystmt
1538
+ k_end
1539
+ {
1540
+ result = new_sclass val
1541
+ self.env.unextend
1542
+ self.lexer.ignore_body_comments
1543
+ }
1544
+ | k_module
1545
+ cpath
1546
+ {
1547
+ yyerror "module definition in method body" if
1548
+ self.in_def or self.in_single > 0
1549
+
1550
+ self.env.extend
1551
+ }
1552
+ bodystmt k_end
1553
+ {
1554
+ result = new_module val
1555
+ self.env.unextend
1556
+ self.lexer.ignore_body_comments
1557
+ }
1558
+ | defn_head f_arglist bodystmt k_end
1559
+ {
1560
+ # [ [:f, 1, false], s(:args)...]
1561
+ # =>
1562
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1563
+ val.insert 1, val.first.pop
1564
+ val.insert 0, [:k_def, 666]
1565
+
1566
+ result, in_def = new_defn val
1567
+
1568
+ lexer.cond.pop # group = local_pop
1569
+ lexer.cmdarg.pop
1570
+ self.env.unextend
1571
+ self.in_def = in_def
1572
+
1573
+ self.lexer.ignore_body_comments
1574
+ }
1575
+ | defs_head f_arglist bodystmt k_end
1576
+ {
1577
+ # [ [recv, [:name, 1, false]], s(:args...]
1578
+ # =>
1579
+ # [ recv, [:name, 1, false], s(:args...]
1580
+ # =>
1581
+ # [ recv, [:name, 1], false, s(:args...]
1582
+ # =>
1583
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1584
+
1585
+ val.prepend(*val.shift)
1586
+ val.insert 2, val[1].pop
1587
+ val.insert 0, [:k_def, 666]
1588
+
1589
+ result, in_def = new_defs val
1590
+
1591
+ lexer.cond.pop # group = local_pop
1592
+ lexer.cmdarg.pop
1593
+ self.env.unextend
1594
+ self.in_def = in_def
1595
+
1596
+ self.in_single -= 1
1597
+
1598
+ # TODO: restore cur_arg ? what's cur_arg?
1599
+
1600
+ self.lexer.ignore_body_comments
1601
+ }
1602
+ | kBREAK
1603
+ {
1604
+ (_, line), = val
1605
+ result = s(:break).line line
1606
+ }
1607
+ | kNEXT
1608
+ {
1609
+ (_, line), = val
1610
+ result = s(:next).line line
1611
+ }
1612
+ | kREDO
1613
+ {
1614
+ (_, line), = val
1615
+ result = s(:redo).line line
1616
+ }
1617
+ | kRETRY
1618
+ {
1619
+ (_, line), = val
1620
+ result = s(:retry).line line
1621
+ }
1622
+
1623
+ primary_value: primary
1624
+ {
1625
+ result = value_expr(val[0])
1626
+ }
1627
+
1628
+ # These are really stupid
1629
+ k_begin: kBEGIN
1630
+ k_if: kIF
1631
+ k_unless: kUNLESS
1632
+ k_while: kWHILE
1633
+ k_until: kUNTIL
1634
+ k_case: kCASE
1635
+ k_for: kFOR
1636
+ k_class: kCLASS
1637
+ {
1638
+ self.comments.push self.lexer.comments
1639
+ }
1640
+ k_module: kMODULE
1641
+ {
1642
+ self.comments.push self.lexer.comments
1643
+ }
1644
+ k_def: kDEF
1645
+ {
1646
+ self.comments.push self.lexer.comments
1647
+ self.in_argdef = true
1648
+ }
1649
+ k_do: kDO
1650
+ k_do_block: kDO_BLOCK
1651
+ k_rescue: kRESCUE
1652
+ k_ensure: kENSURE
1653
+ k_when: kWHEN
1654
+ k_else: kELSE
1655
+ k_elsif: kELSIF
1656
+ k_end: kEND
1657
+ k_return: kRETURN
1658
+
1659
+ then: term
1660
+ | kTHEN
1661
+ | term kTHEN
1662
+
1663
+ do: term
1664
+ | kDO_COND
1665
+
1666
+ if_tail: opt_else
1667
+ | k_elsif expr_value then compstmt if_tail
1668
+ {
1669
+ (_, line), c, _, t, rest = val
1670
+
1671
+ result = s(:if, c, t, rest).line line
1672
+ }
1673
+
1674
+ opt_else: none
1675
+ | kELSE compstmt
1676
+ {
1677
+ result = val[1]
1678
+ }
1679
+
1680
+ for_var: lhs
1681
+ | mlhs
1682
+ {
1683
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1684
+ }
1685
+
1686
+ f_marg: f_norm_arg
1687
+ {
1688
+ (sym, line), = val
1689
+
1690
+ result = s(:dummy, sym).line line
1691
+ }
1692
+ | tLPAREN f_margs rparen
1693
+ {
1694
+ _, args, _ = val
1695
+ result = args
1696
+ }
1697
+
1698
+ f_marg_list: f_marg
1699
+ {
1700
+ arg, = val
1701
+ line = arg.line
1702
+
1703
+ arg = arg.last if arg.sexp_type == :dummy
1704
+
1705
+ result = s(:array, arg).line line
1706
+ }
1707
+ | f_marg_list tCOMMA f_marg
1708
+ {
1709
+ args, _, arg = val
1710
+
1711
+ arg = arg.last if arg.sexp_type == :dummy
1712
+
1713
+ result = list_append args, arg
1714
+ }
1715
+
1716
+ f_margs: f_marg_list
1717
+ {
1718
+ args, = val
1719
+
1720
+ result = block_var args
1721
+ }
1722
+ | f_marg_list tCOMMA f_rest_marg
1723
+ {
1724
+ args, _, rest = val
1725
+
1726
+ result = block_var args, rest
1727
+ }
1728
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1729
+ {
1730
+ lhs, _, splat, _, rhs = val
1731
+
1732
+ result = block_var lhs, splat, rhs
1733
+ }
1734
+ | f_rest_marg
1735
+ {
1736
+ rest, = val
1737
+
1738
+ result = block_var rest
1739
+ }
1740
+ | f_rest_marg tCOMMA f_marg_list
1741
+ {
1742
+ splat, _, rest = val
1743
+
1744
+ result = block_var splat, rest
1745
+ }
1746
+
1747
+ f_rest_marg: tSTAR f_norm_arg
1748
+ {
1749
+ _, (id, line) = val
1750
+
1751
+ result = args ["*#{id}".to_sym]
1752
+ result.line line
1753
+ }
1754
+ | tSTAR
1755
+ {
1756
+ (_, line), = val
1757
+ result = args([:*]).line line
1758
+ }
1759
+
1760
+ f_any_kwrest: f_kwrest
1761
+ | f_no_kwarg
1762
+
1763
+ #if V > 30
1764
+ f_eq: { self.in_argdef = false } tEQL
1765
+ #endif
1766
+
1767
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1768
+ {
1769
+ result = call_args val
1770
+ }
1771
+ | f_block_kwarg opt_f_block_arg
1772
+ {
1773
+ result = call_args val
1774
+ }
1775
+ | f_any_kwrest opt_f_block_arg
1776
+ {
1777
+ result = call_args val
1778
+ }
1779
+ | f_block_arg
1780
+ {
1781
+ (id, line), = val
1782
+ result = call_args [id]
1783
+ result.line line
1784
+ }
1785
+
1786
+ opt_block_args_tail: tCOMMA block_args_tail
1787
+ {
1788
+ result = args val
1789
+ }
1790
+ | none
1791
+
1792
+ excessed_comma: tCOMMA
1793
+ {
1794
+ result = s(:WTF_COMMA!)
1795
+ }
1796
+
1797
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1798
+ {
1799
+ result = args val
1800
+ }
1801
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1802
+ {
1803
+ result = args val
1804
+ }
1805
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1806
+ {
1807
+ result = args val
1808
+ }
1809
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1810
+ {
1811
+ result = args val
1812
+ }
1813
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1814
+ {
1815
+ result = args val
1816
+ }
1817
+ | f_arg excessed_comma
1818
+ {
1819
+ arg, _ = val
1820
+ result = arg << nil
1821
+ }
1822
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1823
+ {
1824
+ result = args val
1825
+ }
1826
+ | f_arg opt_block_args_tail
1827
+ {
1828
+ result = args val
1829
+ }
1830
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1831
+ {
1832
+ result = args val
1833
+ }
1834
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1835
+ {
1836
+ result = args val
1837
+ }
1838
+ | f_block_optarg opt_block_args_tail
1839
+ {
1840
+ result = args val
1841
+ }
1842
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1843
+ {
1844
+ result = args val
1845
+ }
1846
+ | f_rest_arg opt_block_args_tail
1847
+ {
1848
+ result = args val
1849
+ }
1850
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1851
+ {
1852
+ result = args val
1853
+ }
1854
+ | block_args_tail
1855
+ {
1856
+ result = args val
1857
+ }
1858
+
1859
+ opt_block_param: none { result = 0 }
1860
+ | block_param_def
1861
+ {
1862
+ self.lexer.command_start = true
1863
+ }
1864
+
1865
+ block_param_def: tPIPE opt_bv_decl tPIPE
1866
+ {
1867
+ # TODO: current_arg = 0
1868
+ result = args val
1869
+ self.in_argdef = false
1870
+ }
1871
+ | tOROP
1872
+ {
1873
+ (_, line), = val
1874
+
1875
+ result = s(:args).line line
1876
+ }
1877
+ | tPIPE block_param opt_bv_decl tPIPE
1878
+ {
1879
+ # TODO: current_arg = 0
1880
+ result = args val
1881
+ self.in_argdef = false
1882
+ }
1883
+
1884
+ opt_bv_decl: opt_nl
1885
+ | opt_nl tSEMI bv_decls opt_nl
1886
+ {
1887
+ result = args val
1888
+ }
1889
+
1890
+ bv_decls: bvar
1891
+ {
1892
+ result = args val
1893
+ }
1894
+ | bv_decls tCOMMA bvar
1895
+ {
1896
+ result = args val
1897
+ }
1898
+
1899
+ bvar: tIDENTIFIER
1900
+ {
1901
+ result = wrap :shadow, val[0]
1902
+ }
1903
+ | f_bad_arg
1904
+
1905
+ lambda: tLAMBDA
1906
+ {
1907
+ self.env.extend :dynamic
1908
+ result = lexer.lpar_beg
1909
+ lexer.paren_nest += 1
1910
+ lexer.lpar_beg = lexer.paren_nest
1911
+ }
1912
+ f_larglist
1913
+ {
1914
+ lexer.cmdarg.push false
1915
+ }
1916
+ lambda_body
1917
+ {
1918
+ (_, line), lpar, args, _cmdarg, body = val
1919
+ lexer.lpar_beg = lpar
1920
+
1921
+ lexer.cmdarg.pop
1922
+
1923
+ call = s(:lambda).line line
1924
+ result = new_iter call, args, body
1925
+ result.line line
1926
+ self.env.unextend # TODO: dynapush & dynapop
1927
+ }
1928
+
1929
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1930
+ {
1931
+ self.in_argdef = false
1932
+ result = args val
1933
+ }
1934
+ | f_args
1935
+ {
1936
+ self.in_argdef = false
1937
+ result = val[0]
1938
+ result = 0 if result == s(:args)
1939
+ }
1940
+
1941
+ lambda_body: tLAMBEG compstmt tRCURLY
1942
+ {
1943
+ result = val[1]
1944
+ }
1945
+ | kDO_LAMBDA bodystmt kEND
1946
+ {
1947
+ result = val[1]
1948
+ }
1949
+
1950
+ do_block: k_do_block do_body kEND
1951
+ {
1952
+ (_, line), iter, _ = val
1953
+ result = iter.line line
1954
+ }
1955
+
1956
+ block_call: command do_block
1957
+ {
1958
+ # TODO:
1959
+ ## if (nd_type($1) == NODE_YIELD) {
1960
+ ## compile_error(PARSER_ARG "block given to yield");
1961
+
1962
+ cmd, blk = val
1963
+
1964
+ syntax_error "Both block arg and actual block given." if
1965
+ cmd.block_pass?
1966
+
1967
+ if inverted? val then
1968
+ val = invert_block_call val
1969
+ cmd, blk = val
1970
+ end
1971
+
1972
+ result = blk
1973
+ result.insert 1, cmd
1974
+ }
1975
+ | block_call call_op2 operation2 opt_paren_args
1976
+ {
1977
+ lhs, _, (id, _line), args = val
1978
+
1979
+ result = new_call lhs, id.to_sym, args
1980
+ }
1981
+ | block_call call_op2 operation2 opt_paren_args brace_block
1982
+ {
1983
+ iter1, _, (name, _line), args, iter2 = val
1984
+
1985
+ call = new_call iter1, name.to_sym, args
1986
+ iter2.insert 1, call
1987
+
1988
+ result = iter2
1989
+ }
1990
+ | block_call call_op2 operation2 command_args do_block
1991
+ {
1992
+ iter1, _, (name, _line), args, iter2 = val
1993
+
1994
+ call = new_call iter1, name.to_sym, args
1995
+ iter2.insert 1, call
1996
+
1997
+ result = iter2
1998
+ }
1999
+
2000
+ method_call: fcall paren_args
2001
+ {
2002
+ call, args = val
2003
+
2004
+ result = call
2005
+
2006
+ if args then
2007
+ call.concat args.sexp_body
2008
+ result.line_max = args.line_max
2009
+ end
2010
+ }
2011
+ | primary_value call_op operation2 opt_paren_args
2012
+ {
2013
+ recv, call_op, (op, op_line), args = val
2014
+
2015
+ result = new_call recv, op.to_sym, args, call_op
2016
+ result.line_max = op_line unless args
2017
+ }
2018
+ | primary_value tCOLON2 operation2 paren_args
2019
+ {
2020
+ recv, _, (op, _line), args = val
2021
+
2022
+ result = new_call recv, op.to_sym, args
2023
+ }
2024
+ | primary_value tCOLON2 operation3
2025
+ {
2026
+ lhs, _, (id, _line) = val
2027
+
2028
+ result = new_call lhs, id.to_sym
2029
+ }
2030
+ | primary_value call_op paren_args
2031
+ {
2032
+ result = new_call val[0], :call, val[2], val[1]
2033
+ }
2034
+ | primary_value tCOLON2 paren_args
2035
+ {
2036
+ result = new_call val[0], :call, val[2]
2037
+ }
2038
+ | kSUPER paren_args
2039
+ {
2040
+ result = new_super val[1]
2041
+ }
2042
+ | kSUPER
2043
+ {
2044
+ (_, line), = val
2045
+ result = s(:zsuper).line line
2046
+ }
2047
+ | primary_value tLBRACK2 opt_call_args rbracket
2048
+ {
2049
+ result = new_aref val
2050
+ }
2051
+
2052
+ brace_block: tLCURLY
2053
+ {
2054
+ self.env.extend :dynamic
2055
+ }
2056
+ brace_body
2057
+ tRCURLY
2058
+ {
2059
+ (_, line), _, body, _ = val
2060
+
2061
+ result = body
2062
+ result.line line
2063
+
2064
+ self.env.unextend
2065
+ }
2066
+ | k_do
2067
+ {
2068
+ self.env.extend :dynamic
2069
+ }
2070
+ do_body
2071
+ kEND
2072
+ {
2073
+ (_, line), _, body, _ = val
2074
+
2075
+ result = body
2076
+ result.line line
2077
+
2078
+ self.env.unextend
2079
+ }
2080
+
2081
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2082
+ { result = lexer.cmdarg.store(false) }
2083
+ opt_block_param compstmt
2084
+ {
2085
+ line, cmdarg, param, cmpstmt = val
2086
+
2087
+ result = new_brace_body param, cmpstmt, line
2088
+ self.env.unextend
2089
+ lexer.cmdarg.restore cmdarg
2090
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
2091
+ }
2092
+
2093
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2094
+ { lexer.cmdarg.push false }
2095
+ opt_block_param
2096
+ bodystmt
2097
+ {
2098
+ line, _cmdarg, param, cmpstmt = val
2099
+
2100
+ result = new_do_body param, cmpstmt, line
2101
+ lexer.cmdarg.pop
2102
+ self.env.unextend
2103
+ }
2104
+
2105
+ case_args: arg_value
2106
+ {
2107
+ arg, = val
2108
+
2109
+ result = s(:array, arg).line arg.line
2110
+ }
2111
+ | tSTAR arg_value
2112
+ {
2113
+ _, arg = val
2114
+
2115
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2116
+ }
2117
+ | case_args tCOMMA arg_value
2118
+ {
2119
+ args, _, id = val
2120
+
2121
+ result = self.list_append args, id
2122
+ }
2123
+ | case_args tCOMMA tSTAR arg_value
2124
+ {
2125
+ args, _, _, id = val
2126
+
2127
+ result = self.list_append args, s(:splat, id).line(id.line)
2128
+ }
2129
+
2130
+ case_body: k_when
2131
+ case_args then compstmt cases
2132
+ {
2133
+ (_, line), case_args, _then, body, cases = val
2134
+
2135
+ result = new_when case_args, body
2136
+ result.line line
2137
+ result << cases if cases
2138
+ }
2139
+
2140
+ cases: opt_else | case_body
2141
+ ######################################################################
2142
+
2143
+ p_case_body: kIN
2144
+ {
2145
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2146
+ self.lexer.command_start = false
2147
+ result = self.in_kwarg
2148
+ self.in_kwarg = true
2149
+ push_pvtbl
2150
+ push_pktbl
2151
+ }
2152
+ p_top_expr then
2153
+ {
2154
+ pop_pktbl
2155
+ pop_pvtbl
2156
+ old_kwargs = _values[-3]
2157
+ self.in_kwarg = old_kwargs
2158
+ }
2159
+ compstmt
2160
+ p_cases
2161
+ {
2162
+ (_, line), _, pat, _, _, body, cases = val
2163
+
2164
+ result = new_in pat, body, cases, line
2165
+ }
2166
+
2167
+ p_cases: opt_else
2168
+ | p_case_body
2169
+
2170
+ p_top_expr: p_top_expr_body
2171
+ | p_top_expr_body kIF_MOD expr_value
2172
+ {
2173
+ body, _, cond = val
2174
+ body = remove_begin body
2175
+
2176
+ result = s(:if, cond, body, nil).line body.line
2177
+ }
2178
+ | p_top_expr_body kUNLESS_MOD expr_value
2179
+ {
2180
+ body, _, cond = val
2181
+ body = remove_begin body
2182
+
2183
+ result = s(:if, cond, nil, body).line body.line
2184
+ }
2185
+
2186
+ p_top_expr_body: p_expr
2187
+ | p_expr tCOMMA
2188
+ {
2189
+ expr, _ = val
2190
+
2191
+ tail = new_array_pattern_tail nil, true, nil, nil
2192
+ result = new_array_pattern nil, expr, tail, expr.line
2193
+ }
2194
+ | p_expr tCOMMA p_args
2195
+ {
2196
+ expr, _, args = val
2197
+
2198
+ result = new_array_pattern nil, expr, args, expr.line
2199
+ }
2200
+ | p_find
2201
+ {
2202
+ find, = val
2203
+
2204
+ result = new_find_pattern nil, find
2205
+ }
2206
+ | p_args_tail
2207
+ {
2208
+ args, = val
2209
+ result = new_array_pattern nil, nil, args, args.line
2210
+ }
2211
+ | p_kwargs
2212
+ {
2213
+ kwargs, = val
2214
+ result = new_hash_pattern nil, kwargs, kwargs.line
2215
+ }
2216
+
2217
+ p_expr: p_as
2218
+
2219
+ p_as: p_expr tASSOC p_variable
2220
+ {
2221
+ # NODE *n = NEW_LIST($1, &@$);
2222
+ # n = list_append(p, n, $3);
2223
+ # $$ = new_hash(p, n, &@$);
2224
+
2225
+ expr, _, var = val
2226
+
2227
+ id = var.last
2228
+
2229
+ self.env[id] = :lvar # HACK: need to extend env
2230
+ lhs = s(:lasgn, id).line var.line
2231
+
2232
+ result = new_assign lhs, expr
2233
+ }
2234
+ | p_alt
2235
+
2236
+ p_alt: p_alt tPIPE p_expr_basic
2237
+ {
2238
+ lhs, _, rhs = val
2239
+
2240
+ result = s(:or, lhs, rhs).line lhs.line
2241
+ }
2242
+ | p_expr_basic
2243
+
2244
+ p_lparen: tLPAREN2 { push_pktbl }
2245
+ p_lbracket: tLBRACK2 { push_pktbl }
2246
+
2247
+ p_expr_basic: p_value
2248
+ #if V > 30
2249
+ | p_variable
2250
+ #endif
2251
+ | p_const p_lparen p_args tRPAREN
2252
+ {
2253
+ lhs, _, args, _ = val
2254
+
2255
+ pop_pktbl
2256
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2257
+ }
2258
+ | p_const p_lparen p_find tRPAREN
2259
+ {
2260
+ const, _, find, _ = val
2261
+
2262
+ pop_pktbl
2263
+ result = new_find_pattern(const, find).line const.line
2264
+ }
2265
+ | p_const p_lparen p_kwargs tRPAREN
2266
+ {
2267
+ lhs, _, kwargs, _ = val
2268
+
2269
+ pop_pktbl
2270
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2271
+ }
2272
+ | p_const tLPAREN2 tRPAREN
2273
+ {
2274
+ const, _, _ = val
2275
+
2276
+ tail = new_array_pattern_tail nil, nil, nil, nil
2277
+ result = new_array_pattern const, nil, tail, const.line
2278
+ }
2279
+ | p_const p_lbracket p_args rbracket
2280
+ {
2281
+ const, _, pre_arg, _ = val
2282
+
2283
+ pop_pktbl
2284
+ result = new_array_pattern const, nil, pre_arg, const.line
2285
+ }
2286
+ | p_const p_lbracket p_find rbracket
2287
+ {
2288
+ const, _, find, _ = val
2289
+
2290
+ pop_pktbl
2291
+ result = new_find_pattern(const, find).line const.line
2292
+ }
2293
+ | p_const p_lbracket p_kwargs rbracket
2294
+ {
2295
+ const, _, kwargs, _ = val
2296
+
2297
+ result = new_hash_pattern const, kwargs, const.line
2298
+ }
2299
+ | p_const tLBRACK2 rbracket
2300
+ {
2301
+ const, _, _ = val
2302
+
2303
+ tail = new_array_pattern_tail nil, nil, nil, nil
2304
+ result = new_array_pattern const, nil, tail, const.line
2305
+ }
2306
+ | tLBRACK p_args rbracket
2307
+ {
2308
+ _, pat, _ = val
2309
+
2310
+ result = new_array_pattern nil, nil, pat, pat.line
2311
+ }
2312
+ | tLBRACK p_find rbracket
2313
+ {
2314
+ _, find, _ = val
2315
+
2316
+ result = new_find_pattern nil, find
2317
+ }
2318
+ | tLBRACK rbracket
2319
+ {
2320
+ (_, line), _ = val
2321
+
2322
+ result = s(:array_pat).line line
2323
+ }
2324
+ | tLBRACE
2325
+ {
2326
+ push_pktbl
2327
+ result = self.in_kwarg
2328
+ self.in_kwarg = false
2329
+ }
2330
+ p_kwargs rbrace
2331
+ {
2332
+ _, in_kwarg, kwargs, _ = val
2333
+
2334
+ pop_pktbl
2335
+ self.in_kwarg = in_kwarg
2336
+
2337
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2338
+ }
2339
+ | tLBRACE rbrace
2340
+ {
2341
+ (_, line), _ = val
2342
+
2343
+ tail = new_hash_pattern_tail nil, nil, line
2344
+ result = new_hash_pattern nil, tail, line
2345
+ }
2346
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2347
+ {
2348
+ _, _, expr, _ = val
2349
+
2350
+ pop_pktbl
2351
+ result = expr
2352
+ }
2353
+
2354
+ p_args: p_expr
2355
+ {
2356
+ expr, = val
2357
+
2358
+ ary = s(:array_TAIL, expr).line expr.line
2359
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2360
+ }
2361
+ | p_args_head
2362
+ {
2363
+ head, = val
2364
+
2365
+ result = new_array_pattern_tail head, true, nil, nil
2366
+ }
2367
+ | p_args_head p_arg
2368
+ {
2369
+ head, tail = val
2370
+
2371
+ both = array_pat_concat head, tail
2372
+
2373
+ result = new_array_pattern_tail both, nil, nil, nil
2374
+ result.line head.line
2375
+ }
2376
+ #if V < 32
2377
+ | p_args_head tSTAR tIDENTIFIER
2378
+ {
2379
+ head, _, (id, _line) = val
2380
+
2381
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2382
+ result.line head.line
2383
+ }
2384
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2385
+ {
2386
+ head, _, (id, _line), _, post = val
2387
+
2388
+ result = new_array_pattern_tail head, true, id.to_sym, post
2389
+ result.line head.line
2390
+ }
2391
+ | p_args_head tSTAR
2392
+ {
2393
+ expr, _ = val
2394
+
2395
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2396
+ }
2397
+ | p_args_head tSTAR tCOMMA p_args_post
2398
+ {
2399
+ head, _, _, post = val
2400
+
2401
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2402
+ }
2403
+ #else
2404
+ | p_args_head p_rest
2405
+ {
2406
+ head, (rest, _) = val
2407
+
2408
+ result = new_array_pattern_tail(head, true, rest, nil).line head.line
2409
+ }
2410
+ | p_args_head p_rest tCOMMA p_args_post
2411
+ {
2412
+ head, (rest, _), _, post = val
2413
+
2414
+ result = new_array_pattern_tail(head, true, rest, post).line head.line
2415
+ }
2416
+ #endif
2417
+ | p_args_tail
2418
+
2419
+ p_args_head: p_arg tCOMMA
2420
+ {
2421
+ arg, _ = val
2422
+ result = arg
2423
+ }
2424
+ | p_args_head p_arg tCOMMA
2425
+ {
2426
+ head, tail, _ = val
2427
+
2428
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2429
+ result.line head.line
2430
+ }
2431
+
2432
+ p_args_tail: p_rest
2433
+ {
2434
+ (id, line), = val
2435
+
2436
+ result = new_array_pattern_tail nil, true, id, nil
2437
+ result.line line
2438
+ }
2439
+ | p_rest tCOMMA p_args_post
2440
+ {
2441
+ (id, line), _, rhs = val
2442
+
2443
+ result = new_array_pattern_tail nil, true, id, rhs
2444
+ result.line line
2445
+ }
2446
+
2447
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2448
+ {
2449
+ lhs, _, mid, _, rhs = val
2450
+
2451
+ result = new_find_pattern_tail lhs, mid, rhs
2452
+ }
2453
+
2454
+ p_rest: tSTAR tIDENTIFIER
2455
+ {
2456
+ _, (id, line) = val
2457
+
2458
+ result = [id.to_sym, line]
2459
+ }
2460
+ | tSTAR
2461
+ {
2462
+ (_id, line), = val
2463
+
2464
+ result = [nil, line]
2465
+ }
2466
+
2467
+ p_args_post: p_arg
2468
+ | p_args_post tCOMMA p_arg
2469
+ {
2470
+ lhs, _, rhs = val
2471
+
2472
+ result = array_pat_concat lhs, rhs
2473
+ }
2474
+
2475
+ p_arg: p_expr
2476
+ {
2477
+ expr, = val
2478
+ expr = s(:array_TAIL, expr).line expr.line unless
2479
+ expr.sexp_type == :array_TAIL
2480
+ result = expr
2481
+ }
2482
+
2483
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2484
+ {
2485
+ kw_arg, _, rest = val
2486
+ # TODO? new_unique_key_hash(p, $1, &@$)
2487
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2488
+ }
2489
+ | p_kwarg
2490
+ {
2491
+ kwarg, = val
2492
+ # TODO? new_unique_key_hash(p, $1, &@$)
2493
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2494
+ }
2495
+ | p_kwarg tCOMMA
2496
+ {
2497
+ kwarg, _ = val
2498
+ # TODO? new_unique_key_hash(p, $1, &@$)
2499
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2500
+ }
2501
+ | p_any_kwrest
2502
+ {
2503
+ rest, = val
2504
+
2505
+ result = new_hash_pattern_tail nil, rest, rest.line
2506
+ }
2507
+
2508
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2509
+ | p_kwarg tCOMMA p_kw
2510
+ {
2511
+ kwarg, _, kw = val
2512
+ kwarg.concat kw.sexp_body
2513
+ result = kwarg
2514
+ }
2515
+
2516
+ p_kw: p_kw_label p_expr
2517
+ {
2518
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2519
+ lhs, rhs = val
2520
+
2521
+ result = s(:PAIR, lhs, rhs).line lhs.line
2522
+ }
2523
+ | p_kw_label
2524
+ {
2525
+ lhs, = val
2526
+
2527
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2528
+
2529
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2530
+ # yyerror1(&@1, "key must be valid as local variables");
2531
+ # }
2532
+
2533
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2534
+ # assignable(p, $1, 0, &@$));
2535
+
2536
+ case lhs.sexp_type
2537
+ when :lit then
2538
+ assignable [lhs.value, lhs.line]
2539
+ else
2540
+ # TODO or done?
2541
+ debug 10
2542
+ end
2543
+
2544
+ # TODO PAIR -> LIST ?
2545
+ result = s(:PAIR, lhs, nil).line lhs.line
2546
+ }
2547
+
2548
+ p_kw_label: tLABEL
2549
+ {
2550
+ result = wrap :lit, val[0]
2551
+ }
2552
+ #if V > 30
2553
+ | tSTRING_BEG string_contents tLABEL_END
2554
+ {
2555
+ # you can't actually get here the way I lex labels
2556
+ debug 11
2557
+ }
2558
+ #endif
2559
+
2560
+ p_kwrest: kwrest_mark tIDENTIFIER
2561
+ {
2562
+ _, (id, line) = val
2563
+
2564
+ name = id.to_sym
2565
+ self.assignable [name, line]
2566
+ result = s(:kwrest, :"**#{name}").line line
2567
+ }
2568
+ | kwrest_mark
2569
+ {
2570
+ (_, line), = val
2571
+
2572
+ result = s(:kwrest, :"**").line line
2573
+ }
2574
+
2575
+ p_kwnorest: kwrest_mark kNIL
2576
+ {
2577
+ (_, line), _ = val
2578
+
2579
+ # TODO: or s(:norest)? s(:**nil)?
2580
+ result = s(:kwrest, :"**nil").line line
2581
+ }
2582
+
2583
+ p_any_kwrest: p_kwrest
2584
+ | p_kwnorest
2585
+
2586
+ p_value: p_primitive
2587
+ | p_primitive tDOT2 p_primitive
2588
+ {
2589
+ lhs, _, rhs = val
2590
+
2591
+ lhs = value_expr lhs
2592
+ rhs = value_expr rhs
2593
+
2594
+ result = s(:dot2, lhs, rhs).line lhs.line
2595
+ }
2596
+ | p_primitive tDOT3 p_primitive
2597
+ {
2598
+ lhs, _, rhs = val
2599
+
2600
+ lhs = value_expr lhs
2601
+ rhs = value_expr rhs
2602
+
2603
+ result = s(:dot3, lhs, rhs).line lhs.line
2604
+ }
2605
+ | p_primitive tDOT2
2606
+ {
2607
+ v1, _ = val
2608
+
2609
+ result = s(:dot2, v1, nil).line v1.line
2610
+ }
2611
+ | p_primitive tDOT3
2612
+ {
2613
+ v1, _ = val
2614
+
2615
+ result = s(:dot3, v1, nil).line v1.line
2616
+ }
2617
+ #if V == 30
2618
+ | p_variable
2619
+ #endif
2620
+ | p_var_ref
2621
+ #if V > 30
2622
+ | p_expr_ref
2623
+ #endif
2624
+ | p_const
2625
+ | tBDOT2 p_primitive
2626
+ {
2627
+ _, v1 = val
2628
+
2629
+ result = s(:dot2, nil, v1).line v1.line
2630
+ }
2631
+ | tBDOT3 p_primitive
2632
+ {
2633
+ _, v1 = val
2634
+
2635
+ result = s(:dot3, nil, v1).line v1.line
2636
+ }
2637
+
2638
+ p_primitive: literal
2639
+ | strings
2640
+ | xstring
2641
+ | regexp
2642
+ | words
2643
+ {
2644
+ result = ary_to_pat val[0]
2645
+ }
2646
+ | qwords
2647
+ {
2648
+ result = ary_to_pat val[0]
2649
+ }
2650
+ | symbols
2651
+ {
2652
+ result = ary_to_pat val[0]
2653
+ }
2654
+ | qsymbols
2655
+ {
2656
+ result = ary_to_pat val[0]
2657
+ }
2658
+ | keyword_variable
2659
+ {
2660
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2661
+ var, = val
2662
+
2663
+ result = var
2664
+ }
2665
+ | lambda
2666
+
2667
+ p_variable: tIDENTIFIER
2668
+ {
2669
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2670
+ # TODO: assignable(p, $1, 0, &@$);
2671
+ result = wrap :lasgn, val[0]
2672
+ }
2673
+
2674
+ p_var_ref: tCARET tIDENTIFIER
2675
+ {
2676
+ # TODO: check id against env for lvar or dvar
2677
+ result = wrap :lvar, val[1]
2678
+ }
2679
+ #if V > 30
2680
+ | tCARET nonlocal_var
2681
+ {
2682
+ _, var = val
2683
+ result = var
2684
+ }
2685
+ #endif
2686
+
2687
+ #if V > 30
2688
+ p_expr_ref: tCARET tLPAREN expr_value rparen
2689
+ {
2690
+ _, _, expr, _ = val
2691
+ result = expr # TODO? s(:begin, expr).line expr.line
2692
+ }
2693
+ #endif
2694
+
2695
+ p_const: tCOLON3 cname
2696
+ {
2697
+ result = wrap :colon3, val[1]
2698
+ }
2699
+ | p_const tCOLON2 cname
2700
+ {
2701
+ lhs, _, (id, _line) = val
2702
+
2703
+ l = lhs.line
2704
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2705
+ }
2706
+ | tCONSTANT
2707
+ {
2708
+ # TODO $$ = gettable(p, $1, &@$);
2709
+ result = wrap :const, val[0]
2710
+ }
2711
+ ######################################################################
2712
+
2713
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2714
+ {
2715
+ (_, line), klasses, var, _, body, rest = val
2716
+
2717
+ klasses ||= s(:array)
2718
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2719
+ klasses.line line
2720
+
2721
+ result = new_resbody(klasses, body)
2722
+ result << rest if rest # UGH, rewritten above
2723
+ }
2724
+ |
2725
+ {
2726
+ result = nil
2727
+ }
2728
+
2729
+ exc_list: arg_value
2730
+ {
2731
+ arg, = val
2732
+ result = s(:array, arg).line arg.line
2733
+ }
2734
+ | mrhs
2735
+ | none
2736
+
2737
+ exc_var: tASSOC lhs
2738
+ {
2739
+ result = val[1]
2740
+ }
2741
+ | none
2742
+
2743
+ opt_ensure: k_ensure compstmt
2744
+ {
2745
+ (_, line), body = val
2746
+
2747
+ result = body || s(:nil).line(line)
2748
+ }
2749
+ | none
2750
+
2751
+ literal: numeric
2752
+ {
2753
+ (lit, line), = val
2754
+ result = s(:lit, lit).line line
2755
+ }
2756
+ | symbol
2757
+
2758
+ strings: string
2759
+ {
2760
+ str, = val
2761
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2762
+ result = str
2763
+ }
2764
+
2765
+ string: tCHAR
2766
+ {
2767
+ debug 12
2768
+ }
2769
+ | string1
2770
+ | string string1
2771
+ {
2772
+ result = self.literal_concat val[0], val[1]
2773
+ }
2774
+
2775
+ string1: tSTRING_BEG string_contents tSTRING_END
2776
+ {
2777
+ (_, line), str, (_, func) = val
2778
+
2779
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2780
+
2781
+ result = str.line line
2782
+ }
2783
+ | tSTRING
2784
+ {
2785
+ result = new_string val
2786
+ }
2787
+
2788
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2789
+ {
2790
+ result = new_xstring val
2791
+ # TODO: dedent?!?! SERIOUSLY?!?
2792
+ }
2793
+
2794
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2795
+ {
2796
+ result = new_regexp val
2797
+ }
2798
+
2799
+ words: tWORDS_BEG tSPACE tSTRING_END
2800
+ {
2801
+ (_, line), _, (_, line_max) = val
2802
+
2803
+ result = s(:array).line line
2804
+ result.line_max = line_max
2805
+ }
2806
+ | tWORDS_BEG word_list tSTRING_END
2807
+ {
2808
+ (_, line), list, (_, line_max) = val
2809
+
2810
+ result = list.line line
2811
+ result.line_max = line_max
2812
+ }
2813
+
2814
+ word_list: none
2815
+ {
2816
+ result = new_word_list
2817
+ }
2818
+ | word_list word tSPACE
2819
+ {
2820
+ result = val[0].dup << new_word_list_entry(val)
2821
+ }
2822
+
2823
+ word: string_content
2824
+ | word string_content
2825
+ {
2826
+ result = self.literal_concat val[0], val[1]
2827
+ }
2828
+
2829
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2830
+ {
2831
+ (_, line), _, (_, line_max) = val
2832
+
2833
+ result = s(:array).line line
2834
+ result.line_max = line_max
2835
+ }
2836
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2837
+ {
2838
+ (_, line), list, (_, line_max), = val
2839
+
2840
+ result = list.line line
2841
+ result.line_max = line_max
2842
+ }
2843
+
2844
+ symbol_list: none
2845
+ {
2846
+ result = new_symbol_list
2847
+ }
2848
+ | symbol_list word tSPACE
2849
+ {
2850
+ list, * = val
2851
+ result = list.dup << new_symbol_list_entry(val)
2852
+ }
2853
+
2854
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2855
+ {
2856
+ (_, line), _, (_, line_max) = val
2857
+
2858
+ result = s(:array).line line
2859
+ result.line_max = line_max
2860
+ }
2861
+ | tQWORDS_BEG qword_list tSTRING_END
2862
+ {
2863
+ (_, line), list, (_, line_max) = val
2864
+
2865
+ result = list.line line
2866
+ result.line_max = line_max
2867
+ }
2868
+
2869
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2870
+ {
2871
+ (_, line), _, (_, line_max) = val
2872
+
2873
+ result = s(:array).line line
2874
+ result.line_max = line_max
2875
+ }
2876
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2877
+ {
2878
+ (_, line), list, (_, line_max) = val
2879
+
2880
+ result = list.line line
2881
+ result.line_max = line_max
2882
+ }
2883
+
2884
+ qword_list: none
2885
+ {
2886
+ result = new_qword_list
2887
+ }
2888
+ | qword_list tSTRING_CONTENT tSPACE
2889
+ {
2890
+ result = val[0].dup << new_qword_list_entry(val)
2891
+ }
2892
+
2893
+ qsym_list: none
2894
+ {
2895
+ result = new_qsym_list
2896
+ }
2897
+ | qsym_list tSTRING_CONTENT tSPACE
2898
+ {
2899
+ result = val[0].dup << new_qsym_list_entry(val)
2900
+ }
2901
+
2902
+ string_contents: none
2903
+ {
2904
+ line = prev_value_to_lineno _values.last
2905
+ result = s(:str, +"").line line
2906
+ }
2907
+ | string_contents string_content
2908
+ {
2909
+ v1, v2 = val
2910
+ result = literal_concat v1, v2
2911
+ }
2912
+
2913
+ xstring_contents: none
2914
+ {
2915
+ result = nil
2916
+ }
2917
+ | xstring_contents string_content
2918
+ {
2919
+ v1, v2 = val
2920
+ result = literal_concat v1, v2
2921
+ }
2922
+
2923
+ regexp_contents: none
2924
+ {
2925
+ result = nil
2926
+ }
2927
+ | regexp_contents string_content
2928
+ {
2929
+ v1, v2 = val
2930
+ result = literal_concat v1, v2
2931
+ }
2932
+
2933
+ string_content: tSTRING_CONTENT
2934
+ {
2935
+ result = new_string val
2936
+ }
2937
+ | tSTRING_DVAR
2938
+ {
2939
+ result = lexer.lex_strterm
2940
+
2941
+ lexer.lex_strterm = nil
2942
+ lexer.lex_state = EXPR_BEG
2943
+ }
2944
+ string_dvar
2945
+ {
2946
+ _, strterm, str = val
2947
+ lexer.lex_strterm = strterm
2948
+ result = s(:evstr, str).line str.line
2949
+ }
2950
+ | tSTRING_DBEG
2951
+ {
2952
+ result = [lexer.lex_strterm,
2953
+ lexer.brace_nest,
2954
+ lexer.string_nest, # TODO: remove
2955
+ lexer.lex_state,
2956
+ ]
2957
+
2958
+ lexer.cmdarg.push false
2959
+ lexer.cond.push false
2960
+
2961
+ lexer.lex_strterm = nil
2962
+ lexer.brace_nest = 0
2963
+ lexer.string_nest = 0
2964
+
2965
+ lexer.lex_state = EXPR_BEG
2966
+ }
2967
+ compstmt
2968
+ tSTRING_DEND
2969
+ {
2970
+ (_, line), memo, stmt, _ = val
2971
+
2972
+ lex_strterm, brace_nest, string_nest, oldlex_state = memo
2973
+ # TODO: heredoc_indent
2974
+
2975
+ lexer.lex_strterm = lex_strterm
2976
+ lexer.brace_nest = brace_nest
2977
+ lexer.string_nest = string_nest
2978
+
2979
+ lexer.cond.pop
2980
+ lexer.cmdarg.pop
2981
+
2982
+ lexer.lex_state = oldlex_state
2983
+
2984
+ case stmt
2985
+ when Sexp then
2986
+ case stmt.sexp_type
2987
+ when :str, :dstr, :evstr then
2988
+ result = stmt
2989
+ else
2990
+ result = s(:evstr, stmt).line line
2991
+ end
2992
+ when nil then
2993
+ result = s(:evstr).line line
2994
+ else
2995
+ debug 13
2996
+ raise "unknown string body: #{stmt.inspect}"
2997
+ end
2998
+ }
2999
+
3000
+ string_dvar: tGVAR
3001
+ {
3002
+ result = wrap :gvar, val[0]
3003
+ }
3004
+ | tIVAR
3005
+ {
3006
+ result = wrap :ivar, val[0]
3007
+ }
3008
+ | tCVAR
3009
+ {
3010
+ result = wrap :cvar, val[0]
3011
+ }
3012
+ | backref
3013
+
3014
+ symbol: ssym
3015
+ | dsym
3016
+
3017
+ ssym: tSYMBEG sym
3018
+ {
3019
+ lexer.lex_state = EXPR_END
3020
+ result = wrap :lit, val[1]
3021
+ }
3022
+ | tSYMBOL
3023
+ {
3024
+ lexer.lex_state = EXPR_END
3025
+ result = wrap :lit, val[0]
3026
+ }
3027
+
3028
+ sym: fname | tIVAR | tGVAR | tCVAR
3029
+
3030
+ dsym: tSYMBEG string_contents tSTRING_END
3031
+ {
3032
+ (_, line), result, _ = val
3033
+
3034
+ lexer.lex_state = EXPR_END
3035
+
3036
+ result ||= s(:str, "").line line
3037
+
3038
+ case result.sexp_type
3039
+ when :dstr then
3040
+ result.sexp_type = :dsym
3041
+ when :str then
3042
+ result = s(:lit, result.last.to_sym).line result.line
3043
+ when :evstr then
3044
+ result = s(:dsym, "", result).line result.line
3045
+ else
3046
+ debug 14
3047
+ end
3048
+ }
3049
+
3050
+ numeric: simple_numeric
3051
+ | tUMINUS_NUM simple_numeric =tLOWEST
3052
+ {
3053
+ _, (num, line) = val
3054
+ result = [-num, line]
3055
+ }
3056
+
3057
+ simple_numeric: tINTEGER
3058
+ | tFLOAT
3059
+ | tRATIONAL
3060
+ | tIMAGINARY
3061
+
3062
+ #if V > 30
3063
+ nonlocal_var: tIVAR { result = wrap :ivar, val[0] }
3064
+ | tGVAR { result = wrap :gvar, val[0] }
3065
+ | tCVAR { result = wrap :cvar, val[0] }
3066
+ #endif
3067
+
3068
+ user_variable: tIDENTIFIER
3069
+ | tIVAR
3070
+ | tGVAR
3071
+ | tCONSTANT
3072
+ | tCVAR
3073
+
3074
+ keyword_variable: kNIL { (_, line), = val; result = s(:nil).line line }
3075
+ | kSELF { (_, line), = val; result = s(:self).line line }
3076
+ | kTRUE { (_, line), = val; result = s(:true).line line }
3077
+ | kFALSE { (_, line), = val; result = s(:false).line line }
3078
+ | k__FILE__ { (_, line), = val; result = s(:str, self.file).line line }
3079
+ | k__LINE__ { (_, line), = val; result = s(:lit, line).line line }
3080
+ | k__ENCODING__
3081
+ {
3082
+ (_, l), = val
3083
+ result =
3084
+ if defined? Encoding then
3085
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
3086
+ else
3087
+ s(:str, "Unsupported!").line l
3088
+ end
3089
+ }
3090
+
3091
+ var_ref: user_variable
3092
+ {
3093
+ raise "NO: #{val.inspect}" if Sexp === val.first
3094
+ (var, line), = val
3095
+ result = Sexp === var ? var : self.gettable(var)
3096
+
3097
+ result.line line
3098
+ }
3099
+ | keyword_variable
3100
+ {
3101
+ var = val[0]
3102
+ result = Sexp === var ? var : self.gettable(var)
3103
+ }
3104
+
3105
+ var_lhs: user_variable
3106
+ {
3107
+ result = self.assignable val[0]
3108
+ }
3109
+ | keyword_variable
3110
+ {
3111
+ result = self.assignable val[0]
3112
+ debug 15
3113
+ }
3114
+
3115
+ backref: tNTH_REF
3116
+ {
3117
+ (ref, line), = val
3118
+ result = s(:nth_ref, ref).line line
3119
+ }
3120
+ | tBACK_REF
3121
+ {
3122
+ (ref, line), = val
3123
+ result = s(:back_ref, ref).line line
3124
+ }
3125
+
3126
+ superclass: tLT
3127
+ {
3128
+ lexer.lex_state = EXPR_BEG
3129
+ lexer.command_start = true
3130
+ }
3131
+ expr_value term
3132
+ {
3133
+ result = val[2]
3134
+ }
3135
+ | none
3136
+ {
3137
+ result = nil
3138
+ }
3139
+
3140
+ f_opt_paren_args: f_paren_args
3141
+ | none
3142
+ {
3143
+ self.in_argdef = false
3144
+ result = end_args val
3145
+ }
3146
+
3147
+ f_paren_args: tLPAREN2 f_args rparen
3148
+ {
3149
+ self.in_argdef = false
3150
+ result = end_args val
3151
+ }
3152
+ #if V == 30
3153
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3154
+ {
3155
+ result = end_args val
3156
+ }
3157
+ | tLPAREN2 args_forward rparen
3158
+ {
3159
+ result = end_args val
3160
+ }
3161
+ #endif
3162
+
3163
+ f_arglist: f_paren_args
3164
+ | {
3165
+ result = self.in_kwarg
3166
+ self.in_kwarg = true
3167
+ self.in_argdef = true
3168
+ self.lexer.lex_state |= EXPR_LABEL
3169
+ }
3170
+ f_args term
3171
+ {
3172
+ self.in_argdef = false
3173
+ result = end_args val
3174
+ }
3175
+
3176
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
3177
+ {
3178
+ result = args val
3179
+ }
3180
+ | f_kwarg opt_f_block_arg
3181
+ {
3182
+ result = args val
3183
+ }
3184
+ | f_any_kwrest opt_f_block_arg
3185
+ {
3186
+ result = args val
3187
+ }
3188
+ | f_block_arg
3189
+ #if V > 30
3190
+ | args_forward
3191
+ #endif
3192
+
3193
+ opt_args_tail: tCOMMA args_tail
3194
+ {
3195
+ result = val[1]
3196
+ }
3197
+ |
3198
+ {
3199
+ result = nil
3200
+ }
3201
+
3202
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
3203
+ {
3204
+ result = args val
3205
+ }
3206
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3207
+ {
3208
+ result = args val
3209
+ }
3210
+ | f_arg tCOMMA f_optarg opt_args_tail
3211
+ {
3212
+ result = args val
3213
+ }
3214
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
3215
+ {
3216
+ result = args val
3217
+ }
3218
+ | f_arg tCOMMA f_rest_arg opt_args_tail
3219
+ {
3220
+ result = args val
3221
+ }
3222
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3223
+ {
3224
+ result = args val
3225
+ }
3226
+ | f_arg opt_args_tail
3227
+ {
3228
+ result = args val
3229
+ }
3230
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
3231
+ {
3232
+ result = args val
3233
+ }
3234
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3235
+ {
3236
+ result = args val
3237
+ }
3238
+ | f_optarg opt_args_tail
3239
+ {
3240
+ result = args val
3241
+ }
3242
+ | f_optarg tCOMMA f_arg opt_args_tail
3243
+ {
3244
+ result = args val
3245
+ }
3246
+ | f_rest_arg opt_args_tail
3247
+ {
3248
+ result = args val
3249
+ }
3250
+ | f_rest_arg tCOMMA f_arg opt_args_tail
3251
+ {
3252
+ result = args val
3253
+ }
3254
+ | args_tail
3255
+ {
3256
+ result = args val
3257
+ }
3258
+ |
3259
+ {
3260
+ result = args val
3261
+ }
3262
+
3263
+ args_forward: tBDOT3
3264
+ {
3265
+ (_, line), = val
3266
+ result = s(:forward_args).line line
3267
+ }
3268
+
3269
+ f_bad_arg: tCONSTANT
3270
+ {
3271
+ yyerror "formal argument cannot be a constant"
3272
+ }
3273
+ | tIVAR
3274
+ {
3275
+ yyerror "formal argument cannot be an instance variable"
3276
+ }
3277
+ | tGVAR
3278
+ {
3279
+ yyerror "formal argument cannot be a global variable"
3280
+ }
3281
+ | tCVAR
3282
+ {
3283
+ yyerror "formal argument cannot be a class variable"
3284
+ }
3285
+
3286
+ f_norm_arg: f_bad_arg
3287
+ | tIDENTIFIER
3288
+ {
3289
+ (id, line), = val
3290
+ identifier = id.to_sym
3291
+ self.env[identifier] = :lvar
3292
+
3293
+ result = [identifier, line]
3294
+ }
3295
+
3296
+ f_arg_asgn: f_norm_arg
3297
+
3298
+ f_arg_item: f_arg_asgn
3299
+ | tLPAREN f_margs rparen
3300
+ {
3301
+ _, margs, _ = val
3302
+
3303
+ result = margs
3304
+ }
3305
+
3306
+ f_arg: f_arg_item
3307
+ {
3308
+ result = new_arg val
3309
+ }
3310
+ | f_arg tCOMMA f_arg_item
3311
+ {
3312
+ list, _, item = val
3313
+
3314
+ if list.sexp_type == :args then
3315
+ result = list
3316
+ else
3317
+ result = s(:args, list).line list.line
3318
+ end
3319
+
3320
+ if Sexp === item then
3321
+ line_max = item.line_max
3322
+ else
3323
+ item, line_max = item
3324
+ end
3325
+
3326
+ result << item
3327
+ result.line_max = line_max
3328
+ }
3329
+
3330
+ f_label: tLABEL
3331
+ {
3332
+ label, = val
3333
+ # arg_var(p, formal_argument(p, $1));
3334
+ # p->cur_arg = get_id($1);
3335
+ # p->max_numparam = ORDINAL_PARAM;
3336
+ self.in_argdef = false
3337
+ result = label
3338
+ }
3339
+
3340
+ f_kw: f_label arg_value
3341
+ {
3342
+ # TODO: new_kw_arg
3343
+ (label, line), arg = val
3344
+
3345
+ identifier = label.to_sym
3346
+ self.env[identifier] = :lvar
3347
+ self.in_argdef = true
3348
+
3349
+ kwarg = s(:kwarg, identifier, arg).line line
3350
+ result = s(:array, kwarg).line line
3351
+ }
3352
+ | f_label
3353
+ {
3354
+ (label, line), = val
3355
+
3356
+ id = label.to_sym
3357
+ self.env[id] = :lvar
3358
+ self.in_argdef = true
3359
+
3360
+ result = s(:array, s(:kwarg, id).line(line)).line line
3361
+ }
3362
+
3363
+ f_block_kw: f_label primary_value
3364
+ {
3365
+ # TODO: new_kw_arg
3366
+ (label, line), expr = val
3367
+ id = label.to_sym
3368
+ self.env[id] = :lvar
3369
+ self.in_argdef = true
3370
+
3371
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
3372
+ }
3373
+ | f_label
3374
+ {
3375
+ # TODO: new_kw_arg
3376
+ (label, line), = val
3377
+ id = label.to_sym
3378
+ self.env[id] = :lvar
3379
+ self.in_argdef = true
3380
+
3381
+ result = s(:array, s(:kwarg, id).line(line)).line line
3382
+ }
3383
+
3384
+ f_block_kwarg: f_block_kw
3385
+ | f_block_kwarg tCOMMA f_block_kw
3386
+ {
3387
+ list, _, item = val
3388
+ result = list << item.last
3389
+ }
3390
+
3391
+ f_kwarg: f_kw
3392
+ | f_kwarg tCOMMA f_kw
3393
+ {
3394
+ result = args val
3395
+ }
3396
+
3397
+ kwrest_mark: tPOW
3398
+ | tDSTAR
3399
+
3400
+ f_no_kwarg: kwrest_mark kNIL
3401
+ {
3402
+ (_, line), _ = val
3403
+ result = [:"**nil", line]
3404
+ }
3405
+
3406
+ f_kwrest: kwrest_mark tIDENTIFIER
3407
+ {
3408
+ _, (id, line) = val
3409
+
3410
+ name = id.to_sym
3411
+ self.assignable [name, line]
3412
+ result = [:"**#{name}", line]
3413
+ }
3414
+ | kwrest_mark
3415
+ {
3416
+ (_, line), = val
3417
+ id = :"**"
3418
+ self.env[id] = :lvar
3419
+ result = [id, line]
3420
+ }
3421
+
3422
+ f_opt: f_arg_asgn
3423
+ #if V > 30
3424
+ f_eq
3425
+ #else
3426
+ tEQL
3427
+ #endif
3428
+ arg_value
3429
+ {
3430
+ lhs, _, rhs = val
3431
+ self.in_argdef = true
3432
+ result = self.assignable lhs, rhs
3433
+ # TODO: detect duplicate names
3434
+ # TODO? p->cur_arg = 0;
3435
+ }
3436
+
3437
+ f_block_opt: f_arg_asgn
3438
+ #if V > 30
3439
+ f_eq
3440
+ #else
3441
+ tEQL
3442
+ #endif
3443
+ primary_value
3444
+ {
3445
+ lhs, _, rhs = val
3446
+ self.in_argdef = true
3447
+ result = self.assignable lhs, rhs
3448
+ # TODO? p->cur_arg = 0;
3449
+ }
3450
+
3451
+ f_block_optarg: f_block_opt
3452
+ {
3453
+ optblk, = val
3454
+ result = s(:block, optblk).line optblk.line
3455
+ }
3456
+ | f_block_optarg tCOMMA f_block_opt
3457
+ {
3458
+ optarg, _, optblk = val
3459
+ result = optarg
3460
+ result << optblk
3461
+ }
3462
+
3463
+ f_optarg: f_opt
3464
+ {
3465
+ opt, = val
3466
+ result = s(:block, opt).line opt.line
3467
+ }
3468
+ | f_optarg tCOMMA f_opt
3469
+ {
3470
+ result = self.block_append val[0], val[2]
3471
+ }
3472
+
3473
+ restarg_mark: tSTAR2 | tSTAR
3474
+
3475
+ f_rest_arg: restarg_mark tIDENTIFIER
3476
+ {
3477
+ # TODO: differs from parse.y - needs tests
3478
+ _, (id, line) = val
3479
+ name = id.to_sym
3480
+ self.assignable [name, line]
3481
+ result = [:"*#{name}", line]
3482
+ }
3483
+ | restarg_mark
3484
+ {
3485
+ (_, line), = val
3486
+ name = :"*"
3487
+ self.env[name] = :lvar
3488
+ result = [name, line]
3489
+ }
3490
+
3491
+ blkarg_mark: tAMPER2 | tAMPER
3492
+
3493
+ f_block_arg: blkarg_mark tIDENTIFIER
3494
+ {
3495
+ _, (id, line) = val
3496
+ identifier = id.to_sym
3497
+
3498
+ self.env[identifier] = :lvar
3499
+ result = ["&#{identifier}".to_sym, line]
3500
+ }
3501
+ | blkarg_mark
3502
+ {
3503
+ (_, line), = val
3504
+
3505
+ result = [:&, line]
3506
+ }
3507
+
3508
+ opt_f_block_arg: tCOMMA f_block_arg
3509
+ {
3510
+ _, arg = val
3511
+ result = arg
3512
+ }
3513
+ |
3514
+ {
3515
+ result = nil
3516
+ }
3517
+
3518
+ singleton: var_ref
3519
+ | tLPAREN2
3520
+ {
3521
+ lexer.lex_state = EXPR_BEG
3522
+ }
3523
+ expr rparen
3524
+ {
3525
+ result = val[2]
3526
+ yyerror "Can't define single method for literals." if
3527
+ result.sexp_type == :lit
3528
+ }
3529
+
3530
+ assoc_list: none
3531
+ {
3532
+ result = s(:array).line lexer.lineno
3533
+ }
3534
+ | assocs trailer
3535
+
3536
+ assocs: assoc
3537
+ | assocs tCOMMA assoc
3538
+ {
3539
+ list = val[0].dup
3540
+ more = val[2].sexp_body
3541
+ list.push(*more) unless more.empty?
3542
+ result = list
3543
+ result.sexp_type = :hash
3544
+ }
3545
+
3546
+ assoc: arg_value tASSOC arg_value
3547
+ {
3548
+ v1, _, v2 = val
3549
+ result = s(:array, v1, v2).line v1.line
3550
+ }
3551
+ | tLABEL arg_value
3552
+ {
3553
+ label, arg = val
3554
+
3555
+ lit = wrap :lit, label
3556
+ result = s(:array, lit, arg).line lit.line
3557
+ }
3558
+ | tLABEL
3559
+ {
3560
+ lit = wrap :lit, val[0]
3561
+ arg = nil
3562
+
3563
+ result = s(:array, lit, arg).line lit.line
3564
+ }
3565
+ | tSTRING_BEG string_contents tLABEL_END arg_value
3566
+ {
3567
+ (_, line), sym, _, value = val
3568
+
3569
+ sym.sexp_type = :dsym
3570
+
3571
+ result = s(:array, sym, value).line line
3572
+ }
3573
+ | tDSTAR arg_value
3574
+ {
3575
+ _, arg = val
3576
+ line = arg.line
3577
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
3578
+ }
3579
+ #if V >= 32
3580
+ | tDSTAR
3581
+ {
3582
+ (_, line), = val
3583
+ result = s(:array, s(:kwsplat).line(line)).line line
3584
+ }
3585
+ #endif
3586
+
3587
+ operation: tIDENTIFIER | tCONSTANT | tFID
3588
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
3589
+ operation3: tIDENTIFIER | tFID | op
3590
+ dot_or_colon: tDOT | tCOLON2
3591
+ call_op: tDOT
3592
+ | tLONELY # TODO: rename tANDDOT?
3593
+
3594
+ call_op2: call_op
3595
+ | tCOLON2
3596
+
3597
+ opt_terms: | terms
3598
+ opt_nl: | tNL
3599
+ rparen: opt_nl tRPAREN
3600
+ {
3601
+ _, close = val # TODO: include lineno in close?
3602
+ result = [close, lexer.lineno]
3603
+ }
3604
+ rbracket: opt_nl tRBRACK
3605
+ {
3606
+ _, close = val
3607
+ result = [close, lexer.lineno]
3608
+ }
3609
+ rbrace: opt_nl tRCURLY
3610
+ {
3611
+ _, close = val
3612
+ result = [close, lexer.lineno]
3613
+ }
3614
+ trailer: | tNL | tCOMMA
3615
+
3616
+ term: tSEMI { yyerrok }
3617
+ | tNL
3618
+
3619
+ terms: term
3620
+ | terms tSEMI { yyerrok }
3621
+
3622
+ none: { result = nil; }
3623
+ end
3624
+
3625
+ ---- inner
3626
+
3627
+ require "ruby_lexer"
3628
+ require "ruby_parser_extras"
3629
+ include RubyLexer::State::Values
3630
+
3631
+ # :stopdoc:
3632
+
3633
+ # Local Variables: **
3634
+ # racc-token-length-max:14 **
3635
+ # End: **