ruby_parser 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby_parser might be problematic. Click here for more details.

data/lib/ruby_parser.y CHANGED
@@ -15,1634 +15,1776 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
15
15
  tLBRACK tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2
16
16
  tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET
17
17
  tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
18
- tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
19
- tLAST_TOKEN
18
+ tWORDS_BEG tAWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
19
+ tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAST_TOKEN
20
20
 
21
- preclow
22
- nonassoc tLOWEST
23
- nonassoc tLBRACE_ARG
24
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
25
- left kOR kAND
26
- right kNOT
27
- nonassoc kDEFINED
28
- right '=' tOP_ASGN
29
- left kRESCUE_MOD
30
- right '?' ':'
31
- nonassoc tDOT2 tDOT3
32
- left tOROP
33
- left tANDOP
34
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
35
- left tGT tGEQ tLT tLEQ
36
- left tPIPE tCARET
37
- left tAMPER2
38
- left tLSHFT tRSHFT
39
- left tPLUS tMINUS
40
- left tSTAR2 tDIVIDE tPERCENT
41
- right tUMINUS_NUM tUMINUS
42
- right tPOW
43
- right tBANG tTILDE tUPLUS
44
21
  prechigh
22
+ right tBANG tTILDE tUPLUS
23
+ right tPOW
24
+ right tUMINUS_NUM tUMINUS
25
+ left tSTAR2 tDIVIDE tPERCENT
26
+ left tPLUS tMINUS
27
+ left tLSHFT tRSHFT
28
+ left tAMPER2
29
+ left tPIPE tCARET
30
+ left tGT tGEQ tLT tLEQ
31
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
32
+ left tANDOP
33
+ left tOROP
34
+ nonassoc tDOT2 tDOT3
35
+ right tEH tCOLON
36
+ left kRESCUE_MOD
37
+ right tEQL tOP_ASGN
38
+ nonassoc kDEFINED
39
+ right kNOT
40
+ left kOR kAND
41
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
42
+ nonassoc tLBRACE_ARG
43
+ nonassoc tLOWEST
44
+ preclow
45
45
 
46
46
  rule
47
47
 
48
- program : {
49
- self.lexer.state = :expr_beg
50
- } compstmt {
51
- result = val[1]
52
- }
53
-
54
- bodystmt : compstmt opt_rescue opt_else opt_ensure {
55
- result = val[0]
56
-
57
- if val[1] then
58
- result = s(:rescue)
59
- result << val[0] if val[0]
60
- result << val[1] if val[1]
61
- result << val[2] if val[2]
62
- elsif not val[2].nil? then
63
- warning("else without rescue is useless")
64
- result = block_append(result, val[2])
65
- end
66
-
67
- result = s(:ensure, result, val[3]).compact if val[3]
68
- }
69
-
70
- compstmt : stmts opt_terms {
71
- result = void_stmts(val[0])
72
- }
73
-
74
- stmts : none
75
- | stmt # TODO: wrap in newline node
76
- | stmts terms stmt {
77
- result = self.block_append(val[0], val[2])
78
- }
79
- | error stmt {
80
- result = val[1];
81
- }
82
-
83
- stmt : kALIAS fitem { lexer.state = :expr_fname } fitem {
84
- result = s(:alias, val[1], val[3])
85
- }
86
- | kALIAS tGVAR tGVAR {
87
- result = s(:valias, val[1].value.to_sym, val[2].value.to_sym)
88
- }
89
- | kALIAS tGVAR tBACK_REF {
90
- result = s(:valias, val[1].value.to_sym, :"$#{val[2].last}")
91
- }
92
- | kALIAS tGVAR tNTH_REF {
93
- yyerror("can't make alias for the number variables");
94
- }
95
- | kUNDEF undef_list {
96
- result = val[1]
97
- }
98
- | stmt kIF_MOD expr_value {
99
- val[2] = cond val[2]
100
- if val[2][0] == :not then
101
- result = s(:if, val[2].last, nil, val[0])
102
- else
103
- result = s(:if, val[2], val[0], nil)
104
- end
105
- }
106
- | stmt kUNLESS_MOD expr_value {
107
- val[2] = cond val[2]
108
- if val[2][0] == :not then
109
- result = s(:if, val[2].last, val[0], nil)
110
- else
111
- result = s(:if, val[2], nil, val[0])
112
- end
113
- }
114
- | stmt kWHILE_MOD expr_value {
115
- block, pre = val[0], true
116
- block, pre = block.last, false if block[0] == :begin
117
-
118
- val[2] = cond val[2]
119
- if val[2][0] == :not then
120
- result = s(:until, val[2].last, block, pre)
121
- else
122
- result = s(:while, val[2], block, pre)
123
- end
124
- }
125
- | stmt kUNTIL_MOD expr_value { # REFACTOR
126
- block, pre = val[0], true
127
- block, pre = block.last, false if block[0] == :begin
128
-
129
- val[2] = cond val[2]
130
- if val[2][0] == :not then
131
- result = s(:while, val[2].last, block, pre)
132
- else
133
- result = s(:until, val[2], block, pre)
134
- end
135
- }
136
- | stmt kRESCUE_MOD stmt {
137
- result = s(:rescue, val[0], s(:resbody, nil, val[2]))
138
- }
139
- | klBEGIN {
140
- if (self.in_def || self.in_single > 0) then
141
- # yyerror("BEGIN in method"); HACK
142
- end
143
- self.env.extend;
144
- } tLCURLY compstmt tRCURLY {
145
- result = s(:iter, s(:preexe), nil)
146
- result << val[3] if val[3]
147
- result = nil # TODO: since it isn't supposed to go in the AST
148
- }
149
- | klEND tLCURLY compstmt tRCURLY {
150
- if (self.in_def || self.in_single > 0) then
151
- # yyerror("END in method; use at_exit"); HACK
152
- end
153
- result = s(:iter, s(:postexe), nil)
154
- result << val[2] if val[2]
155
- }
156
- | lhs '=' command_call {
157
- result = self.node_assign(val[0], val[2])
158
- }
159
- | mlhs '=' command_call {
160
- val[2] = value_expr(val[2])
161
- result = val[0] << if val[0][1] then
162
- s(:to_ary, val[2])
163
- else
164
- val[0].delete_at 1 # remove the nil
165
- s(:array, val[2])
166
- end
167
- }
168
- | var_lhs tOP_ASGN command_call {
169
- name = val[0].last
170
- asgn_op = val[1].value.to_sym
171
- val[2] = value_expr(val[2])
172
-
173
- case asgn_op
174
- when :"||" then
175
- val[0][2] = (val[2]);
176
- result = s(:op_asgn_or, self.gettable(name), val[0])
177
- when :"&&" then
178
- val[0][2] = (val[2]);
179
- result = s(:op_asgn_and, self.gettable(name), val[0])
180
- else
181
- result = val[0]
182
- result << s(:call, self.gettable(name), asgn_op, s(:array, val[2]))
183
- end
184
- }
185
- | primary_value '[' aref_args tRBRACK tOP_ASGN command_call {
186
- result = s(:op_asgn1, val[0], val[2], val[4].value.to_sym, val[5]);
187
- }
188
- | primary_value tDOT tIDENTIFIER tOP_ASGN command_call {
189
- result = s(:op_asgn, val[0], val[4], val[2].value, val[3].value);
190
- }
191
- | primary_value tDOT tCONSTANT tOP_ASGN command_call {
192
- result = s(:op_asgn, val[0], val[4], val[2].value, val[3].value);
193
- }
194
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call {
195
- result = s(:op_asgn, val[0], val[4], val[2].value, val[3].value);
196
- }
197
- | backref tOP_ASGN command_call {
198
- self.backref_assign_error(val[0]);
199
- }
200
- | lhs '=' mrhs {
201
- result = self.node_assign(val[0], s(:svalue, val[2]))
202
- }
203
- | mlhs '=' arg_value {
204
- result = val[0] << if val[0][1] then
205
- s(:to_ary, val[2])
206
- else
207
- val[0].delete_at 1 if val[0][1].nil?
208
- s(:array, val[2])
209
- end
210
- }
211
- | mlhs '=' mrhs {
212
- val[0].delete_at 1 if val[0][1].nil?
213
- result = val[0] << val[2]
214
- }
215
- | expr
216
-
217
-
218
- expr : command_call
219
- | expr kAND expr {
220
- result = logop(:and, val[0], val[2])
221
- }
222
- | expr kOR expr {
223
- result = logop(:or, val[0], val[2])
224
- }
225
- | kNOT expr {
226
- result = s(:not, val[1])
227
- }
228
- | tBANG command_call {
229
- result = s(:not, val[1])
230
- }
231
- | arg
232
-
233
- expr_value : expr {
234
- result = value_expr(val[0])
235
- }
236
-
237
- command_call : command
238
- | block_command
239
- | kRETURN call_args {
240
- result = s(:return, ret_args(val[1]))
241
- }
242
- | kBREAK call_args {
243
- result = s(:break, ret_args(val[1]))
244
- }
245
- | kNEXT call_args {
246
- result = s(:next, ret_args(val[1]))
247
- }
248
-
249
- block_command : block_call
250
- | block_call tDOT operation2 command_args {
251
- result = s(:call, val[0], val[2], val[3]);
252
- }
253
- | block_call tCOLON2 operation2 command_args {
254
- result = s(:call, val[0], val[2], val[3]);
255
- }
256
-
257
- cmd_brace_block : tLBRACE_ARG {
258
- self.env.extend :dynamic
259
- } opt_block_var { result = self.env.dynamic.keys }
260
- compstmt tRCURLY {
261
- result = s(:iter, val[2], dyna_init(val[4], val[3]))
262
- self.env.unextend;
263
- }
264
-
265
- command : operation command_args = tLOWEST {
266
- result = new_fcall(val[0].value.to_sym, val[1])
267
- }
268
- | operation command_args cmd_brace_block {
269
- result = new_fcall(val[0].value.to_sym, val[1])
270
- if val[2] then
271
- if result[0] == :block_pass then
272
- raise "both block arg and actual block given"
273
- end
274
- val[2] << result
275
- result = val[2]
276
- end
277
- }
278
- | primary_value tDOT operation2 command_args = tLOWEST {
279
- result = new_call(val[0], val[2].to_sym, val[3])
280
- }
281
- | primary_value tDOT operation2 command_args cmd_brace_block {
282
- result = new_call(val[0], val[2].to_sym, val[3])
283
- }
284
- | primary_value tCOLON2 operation2 command_args = tLOWEST {
285
- result = new_call(val[0], val[2].to_sym, val[3])
286
- }
287
- | primary_value tCOLON2 operation2 command_args cmd_brace_block {
288
- result = new_call(val[0], val[2].to_sym, val[3])
289
- if val[4] then
290
- if result[0] == :block_pass then # REFACTOR
291
- raise "both block arg and actual block given"
292
- end
293
- val[2] << result
294
- result = val[2]
295
- end
296
- }
297
- | kSUPER command_args {
298
- result = self.new_super(val[1]);
299
- }
300
- | kYIELD command_args {
301
- result = self.new_yield(val[1]);
302
- }
303
-
304
- mlhs : mlhs_basic
305
- | tLPAREN mlhs_entry tRPAREN {
306
- result = val[1];
307
- }
308
-
309
- mlhs_entry : mlhs_basic
310
- | tLPAREN mlhs_entry tRPAREN {
311
- result = s(:masgn, s(:array, val[1]));
312
- }
313
-
314
- mlhs_basic : mlhs_head {
315
- result = s(:masgn, val[0]);
316
- }
317
- | mlhs_head mlhs_item {
318
- result = s(:masgn, val[0] << val[1].compact);
319
- }
320
- | mlhs_head tSTAR mlhs_node {
321
- result = s(:masgn, val[0], val[2]);
322
- }
323
- | mlhs_head tSTAR {
324
- result = s(:masgn, val[0], s(:splat))
325
- }
326
- | tSTAR mlhs_node {
327
- result = s(:masgn, nil, val[1]);
328
- }
329
- | tSTAR {
330
- result = s(:masgn, nil, s(:splat))
331
- }
332
-
333
- mlhs_item : mlhs_node
334
- | tLPAREN mlhs_entry tRPAREN {
335
- result = val[1];
336
- }
337
-
338
- mlhs_head : mlhs_item ',' {
339
- result = s(:array, val[0])
340
- }
341
- | mlhs_head mlhs_item ',' {
342
- result = val[0] << val[1].compact
343
- }
344
-
345
- mlhs_node : variable {
346
- result = self.assignable(val[0])
347
- }
348
- | primary_value '[' aref_args tRBRACK {
349
- result = self.aryset(val[0], val[2]);
350
- }
351
- | primary_value tDOT tIDENTIFIER {
352
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
353
- }
354
- | primary_value tCOLON2 tIDENTIFIER {
355
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
356
- }
357
- | primary_value tDOT tCONSTANT {
358
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
359
- }
360
- | primary_value tCOLON2 tCONSTANT {
361
- if (self.in_def || self.in_single > 0) then
362
- yyerror("dynamic constant assignment");
363
- end
364
-
365
- result = s(:constdecl, nil,
366
- s(:colon2, val[0], val[2].value), nil)
367
- }
368
- | tCOLON3 tCONSTANT {
369
- if (self.in_def || self.in_single > 0) then
370
- yyerror("dynamic constant assignment");
371
- end
372
-
373
- result = s(:const, nil, s(:colon3, val[1].value.to_sym))
374
- }
375
- | backref {
376
- self.backref_assign_error(val[0]);
377
- }
378
-
379
- lhs : variable {
380
- result = self.assignable(val[0])
381
- }
382
- | primary_value '[' aref_args tRBRACK {
383
- result = self.aryset(val[0], val[2]);
384
- }
385
- | primary_value tDOT tIDENTIFIER {
386
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
387
- }
388
- | primary_value tCOLON2 tIDENTIFIER {
389
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
390
- }
391
- | primary_value tDOT tCONSTANT {
392
- result = s(:attrasgn, val[0], :"#{val[2].value}=");
393
- }
394
- | primary_value tCOLON2 tCONSTANT {
395
- if (self.in_def || self.in_single > 0) then
396
- yyerror("dynamic constant assignment");
397
- end
398
-
399
- result = s(:constdecl, nil, s(:colon2, val[0], val[2].value), nil);
400
- }
401
- | tCOLON3 tCONSTANT {
402
- if (self.in_def || self.in_single > 0) then
403
- yyerror("dynamic constant assignment");
404
- end
405
-
406
- result = s(:const, nil, s(:colon3, val[1].value.to_sym))
407
- }
408
- | backref {
409
- self.backref_assign_error(val[0]);
410
- }
411
-
412
- cname : tIDENTIFIER {
413
- yyerror("class/module name must be CONSTANT");
414
- }
415
- | tCONSTANT
416
-
417
- cpath : tCOLON3 cname {
418
- result = s(:colon3, val[1].value.to_sym)
419
- }
420
- | cname {
421
- result = s(:colon2, nil, val[0].value);
422
- }
423
- | primary_value tCOLON2 cname {
424
- result = s(:colon2, val[0], val[2].value);
425
- }
426
-
427
- fname : tIDENTIFIER | tCONSTANT | tFID
428
- | op {
429
- lexer.state = :expr_end
430
- result = val[0];
431
- }
432
-
433
- | reswords {
434
- lexer.state = :expr_end
435
- result = val[0];
436
- }
437
-
438
- fitem : fname { result = s(:lit, val[0].value.to_sym) } # TODO: cruby has fsym and dsym
439
- | symbol { result = s(:lit, val[0]) }
440
-
441
- undef_list : fitem {
442
- result = s(:undef, val[0])
443
- }
444
- | undef_list ',' {
445
- lexer.state = :expr_fname
446
- } fitem {
447
- result = self.block_append(val[0], s(:undef, val[3]))
448
- }
449
-
450
- op : tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ | tMATCH
451
- | tGT | tGEQ | tLT | tLEQ | tLSHFT | tRSHFT | tPLUS
452
- | tMINUS | tSTAR2 | tSTAR | tDIVIDE | tPERCENT | tPOW | tTILDE
453
- | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
454
-
455
- reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND
456
- | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED
457
- | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
458
- | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
459
- | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF
460
- | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
461
- | kIF_MOD | kUNLESS_MOD | kWHILE_MOD | kUNTIL_MOD | kRESCUE_MOD
462
-
463
- arg : lhs '=' arg {
464
- result = self.node_assign(val[0], val[2])
465
- }
466
- | lhs '=' arg kRESCUE_MOD arg {
467
- result = self.node_assign(val[0],
468
- s(:rescue, val[2], s(:resbody, nil, val[4])))
469
- }
470
- | var_lhs tOP_ASGN arg {
471
- name = val[0].value
472
- asgn_op = val[1].value.to_sym
473
-
474
- val[2] = remove_begin(val[2])
475
-
476
- case asgn_op
477
- when :"||" then
478
- val[0] << val[2]
479
- result = s(:op_asgn_or, self.gettable(name), val[0]);
480
- when :"&&" then
481
- val[0] << val[2]
482
- result = s(:op_asgn_and, self.gettable(name), val[0]);
483
- else
484
- val[0][2] = s(:call, self.gettable(name), asgn_op, s(:array, val[2]))
485
- result = val[0];
486
- end
487
- }
488
- | primary_value '[' aref_args tRBRACK tOP_ASGN arg {
489
- result = s(:op_asgn1, val[0], val[2], val[4].value.to_sym, val[5]);
490
- }
491
- | primary_value tDOT tIDENTIFIER tOP_ASGN arg {
492
- result = s(:op_asgn2, val[0], :"#{val[2].value}=", val[3].value.to_sym, val[4]);
493
- }
494
- | primary_value tDOT tCONSTANT tOP_ASGN arg {
495
- result = s(:op_asgn2, val[0], :"#{val[2].value}=", val[3].value.to_sym, val[4])
496
- }
497
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg {
498
- result = s(:op_asgn, val[0], val[4], val[2].value, val[3].value);
499
- }
500
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg {
501
- yyerror("constant re-assignment");
502
- }
503
- | tCOLON3 tCONSTANT tOP_ASGN arg {
504
- yyerror("constant re-assignment");
505
- }
506
- | backref tOP_ASGN arg {
507
- self.backref_assign_error(val[0]);
508
- }
509
- | arg tDOT2 arg {
510
- v1, v2 = val[0], val[2]
511
- if v1.first == :lit and v2.first == :lit and Fixnum === v1.last and Fixnum === v2.last then
512
- result = s(:lit, (v1.last)..(v2.last))
513
- else
514
- result = s(:dot2, v1, v2)
515
- end
516
- }
517
- | arg tDOT3 arg {
518
- v1, v2 = val[0], val[2]
519
- if v1.first == :lit and v2.first == :lit and Fixnum === v1.last and Fixnum === v2.last then
520
- result = s(:lit, (v1.last)...(v2.last))
521
- else
522
- result = s(:dot3, v1, v2)
523
- end
524
- }
525
- | arg tPLUS arg {
526
- result = s(:call, val[0], :+, s(:array, val[2]))
527
- }
528
- | arg tMINUS arg {
529
- result = s(:call, val[0], :-, s(:array, val[2]))
530
- }
531
- | arg tSTAR2 arg {
532
- result = s(:call, val[0], :*, s(:array, val[2]))
533
- }
534
- | arg tDIVIDE arg {
535
- result = s(:call, val[0], :"/", s(:array, val[2]))
536
- }
537
- | arg tPERCENT arg {
538
- result = s(:call, val[0], :%, s(:array, val[2]))
539
- }
540
- | arg tPOW arg {
541
- result = s(:call, val[0], :**, s(:array, val[2]))
542
- }
543
- | tUMINUS_NUM tINTEGER tPOW arg {
544
- result = s(:call, s(:call, s(:lit, val[1]), :"**", s(:array, val[3])), :"-@");
545
- }
546
- | tUMINUS_NUM tFLOAT tPOW arg {
547
- result = s(:call, s(:call, s(:lit, val[1]), :"**", s(:array, val[3])), :"-@");
548
- }
549
- | tUPLUS arg {
550
- if val[1][0] == :lit then
551
- result = val[1]
552
- else
553
- result = s(:call, val[1], :"+@")
554
- end
555
- }
556
- | tUMINUS arg {
557
- result = s(:call, val[1], :"-@");
558
- }
559
- | arg tPIPE arg {
560
- result = s(:call, val[0], :"|", s(:array, val[2]));
561
- }
562
- | arg tCARET arg {
563
- result = s(:call, val[0], :"^", s(:array, val[2]));
564
- }
565
- | arg tAMPER2 arg {
566
- result = s(:call, val[0], :"&", s(:array, val[2]));
567
- }
568
- | arg tCMP arg {
569
- result = s(:call, val[0], :"<=>", s(:array, val[2]));
570
- }
571
- | arg tGT arg {
572
- result = s(:call, val[0], :">", s(:array, val[2]));
573
- }
574
- | arg tGEQ arg {
575
- result = s(:call, val[0], :">=", s(:array, val[2]));
576
- }
577
- | arg tLT arg {
578
- result = s(:call, val[0], :"<", s(:array, val[2]));
579
- }
580
- | arg tLEQ arg {
581
- result = s(:call, val[0], :"<=", s(:array, val[2]));
582
- }
583
- | arg tEQ arg {
584
- result = s(:call, val[0], :"==", s(:array, val[2]));
585
- }
586
- | arg tEQQ arg {
587
- result = s(:call, val[0], :"===", s(:array, val[2]));
588
- }
589
- | arg tNEQ arg {
590
- val[0] = value_expr val[0] # TODO: port call_op and clean these
591
- val[2] = value_expr val[2]
592
- result = s(:not, s(:call, val[0], :"==", s(:array, val[2])));
593
- }
594
- | arg tMATCH arg {
595
- result = self.get_match_node(val[0], val[2])
596
- }
597
- | arg tNMATCH arg {
598
- result = s(:not, self.get_match_node(val[0], val[2]))
599
- }
600
- | tBANG arg {
601
- result = s(:not, val[1])
602
- }
603
- | tTILDE arg {
604
- val[2] = value_expr val[2]
605
- result = s(:call, val[1], :"~");
606
- }
607
- | arg tLSHFT arg {
608
- val[0] = value_expr val[0]
609
- val[2] = value_expr val[2]
610
- result = s(:call, val[0], :"<<", s(:array, val[2])) # " stupid emacs
611
- }
612
- | arg tRSHFT arg {
613
- val[0] = value_expr val[0]
614
- val[2] = value_expr val[2]
615
- result = s(:call, val[0], :">>", s(:array, val[2]))
616
- }
617
- | arg tANDOP arg {
618
- result = logop(:and, val[0], val[2])
619
- }
620
- | arg tOROP arg {
621
- result = logop(:or, val[0], val[2])
622
- }
623
- | kDEFINED opt_nl arg {
624
- result = s(:defined, val[2]);
625
- }
626
- | arg '?' arg ':' arg {
627
- result = s(:if, val[0], val[2], val[4]);
628
- }
629
- | primary
630
-
631
- arg_value : arg {
632
- result = value_expr(val[0])
633
- }
634
-
635
- aref_args : none
636
- | command opt_nl {
637
- warning("parenthesize argument(s) for future version");
638
- result = s(:array, val[0]);
639
- }
640
- | args trailer {
641
- result = val[0];
642
- }
643
- | args ',' tSTAR arg opt_nl {
644
- result = self.arg_concat(val[0], val[3])
645
- }
646
- | assocs trailer {
647
- result = s(:array, s(:hash, *val[0].values))
648
- }
649
- | tSTAR arg opt_nl {
650
- result = s(:splat, val[1])
651
- result.paren = true
652
- }
653
-
654
- paren_args : tLPAREN2 none tRPAREN {
655
- result = val[1]
656
- }
657
- | tLPAREN2 call_args opt_nl tRPAREN {
658
- result = val[1];
659
- }
660
- | tLPAREN2 block_call opt_nl tRPAREN {
661
- warning("parenthesize argument(s) for future version");
662
- result = s(:array, val[1]);
663
- }
664
- | tLPAREN2 args ',' block_call opt_nl tRPAREN {
665
- warning("parenthesize argument(s) for future version");
666
- result = val[1].add(val[3]);
667
- }
668
-
669
- opt_paren_args: none | paren_args
670
-
671
- call_args : command {
672
- warning("parenthesize argument(s) for future version");
673
- result = s(:array, val[0])
674
- }
675
- | args opt_block_arg {
676
- result = self.arg_blk_pass(val[0], val[1]);
677
- }
678
- | args ',' tSTAR arg_value opt_block_arg {
679
- result = self.arg_concat(val[0], val[3]);
680
- result = self.arg_blk_pass(result, val[4]);
681
- }
682
- | assocs opt_block_arg {
683
- result = s(:array, s(:hash, *val[0].values))
684
- result = self.arg_blk_pass(result, val[1]);
685
- }
686
- | assocs ',' tSTAR arg_value opt_block_arg {
687
- result = self.arg_concat(s(:array, s(:hash, *val[0].values)), val[3])
688
- result = self.arg_blk_pass(result, val[4]);
689
- }
690
- | args ',' assocs opt_block_arg {
691
- result = val[0] << s(:hash, *val[2].values)
692
- result = self.arg_blk_pass(result, val[3]);
693
- }
694
- | args ',' assocs ',' tSTAR arg opt_block_arg {
695
- val[0] << s(:hash, *val[2].values)
696
- result = self.arg_concat(val[0], val[5])
697
- result = self.arg_blk_pass(result, val[6]);
698
- }
699
- | tSTAR arg_value opt_block_arg {
700
- result = self.arg_blk_pass(s(:splat, val[1]), val[2])
701
- }
702
- | block_arg
703
-
704
- call_args2 : arg_value ',' args opt_block_arg {
705
- result = self.arg_blk_pass(s(:array, val[0], val[2]), val[3])
706
- }
707
- | arg_value ',' block_arg {
708
- result = self.arg_blk_pass(val[0], val[2]);
709
- }
710
- | arg_value ',' tSTAR arg_value opt_block_arg {
711
- result = self.arg_concat(s(:array, val[0]), val[3]);
712
- result = self.arg_blk_pass(result, val[4]);
713
- }
714
- | arg_value ',' args ',' tSTAR arg_value opt_block_arg {
715
- result = self.arg_concat(s(:array, val[0], s(:hash, *val[2].values)), val[5])
716
- result = self.arg_blk_pass(result, val[6]);
717
- }
718
- | assocs opt_block_arg {
719
- result = s(:array, s(:hash, *val[0].values));
720
- result = self.arg_blk_pass(result, val[1]);
721
- }
722
- | assocs ',' tSTAR arg_value opt_block_arg {
723
- result = s(:array, s(:hash, *val[0].values), val[3])
724
- result = self.arg_blk_pass(result, val[4])
725
- }
726
- | arg_value ',' assocs opt_block_arg {
727
- result = s(:array, val[0], s(:hash, *val[2].values))
728
- result = self.arg_blk_pass(result, val[3])
729
- }
730
- | arg_value ',' args ',' assocs opt_block_arg {
731
- result = s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values));
732
- result = self.arg_blk_pass(result, val[5]);
733
- }
734
- | arg_value ',' assocs ',' tSTAR arg_value opt_block_arg {
735
- result = self.arg_concat(s(:array, val[0]).add(s(:hash, *val[2].values)), val[5]);
736
- result = self.arg_blk_pass(result, val[6]);
737
- }
738
- | arg_value ',' args ',' assocs ',' tSTAR arg_value opt_block_arg {
739
- result = self.arg_concat(s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values)), val[7]);
740
- result = self.arg_blk_pass(result, val[8]);
741
- }
742
- | tSTAR arg_value opt_block_arg {
743
- result = self.arg_blk_pass(s(:splat, val[1]), val[2]);
744
- }
745
- | block_arg
746
-
747
- command_args : {
748
- result = lexer.cmdarg.stack.dup
749
- lexer.cmdarg.push true
750
- } open_args {
751
- lexer.cmdarg.stack.replace val[0]
752
- result = val[1]
753
- }
754
-
755
- open_args : call_args
756
- | tLPAREN_ARG {
757
- lexer.state = :expr_endarg
758
- } tRPAREN {
759
- warning("don't put space before argument parentheses");
760
- result = nil;
761
- }
762
- | tLPAREN_ARG call_args2 {
763
- lexer.state = :expr_endarg
764
- } tRPAREN {
765
- warning("don't put space before argument parentheses");
766
- result = val[1];
767
- }
768
-
769
- block_arg : tAMPER arg_value {
770
- result = s(:block_pass, val[1]);
771
- }
772
-
773
- opt_block_arg : ',' block_arg {
774
- result = val[1];
775
- }
776
- | none_block_pass
777
-
778
- args : arg_value {
779
- result = s(:array, val[0])
780
- }
781
- | args ',' arg_value {
782
- result = val[0] << val[2]
783
- # result = self.list_append(val[0], val[2]) # TODO? breaks stuff
784
- }
785
-
786
- mrhs : args ',' arg_value {
787
- result = val[0] << val[2]
788
- # result = self.list_append(val[0], val[2]) # TODO? breaks stuff
789
- }
790
- | args ',' tSTAR arg_value {
791
- result = self.arg_concat(val[0], val[3])
792
- }
793
- | tSTAR arg_value {
794
- result = s(:splat, val[1])
795
- }
796
-
797
- primary : literal
798
- | strings
799
- | xstring
800
- | regexp
801
- | words
802
- | qwords
803
- | var_ref
804
- | backref
805
- | tFID {
806
- result = s(:fcall, val[0].value.to_sym)
807
- }
808
- | kBEGIN bodystmt kEND {
809
- unless val[1] then
810
- result = s(:nil)
811
- else
812
- result = s(:begin, val[1])
813
- end
814
- }
815
- | tLPAREN_ARG expr {
816
- lexer.state = :expr_endarg
817
- } opt_nl tRPAREN {
818
- warning("(...) interpreted as grouped expression");
819
- result = val[1];
820
- }
821
- | tLPAREN compstmt tRPAREN {
822
- result = val[1];
823
- result.paren = true
824
- }
825
- | primary_value tCOLON2 tCONSTANT {
826
- result = s(:colon2, val[0], val[2].value.to_sym)
827
- }
828
- | tCOLON3 tCONSTANT {
829
- result = s(:colon3, val[1].value.to_sym)
830
- }
831
- | primary_value '[' aref_args tRBRACK {
832
- if val[0].first == :self then
833
- result = s(:fcall, :"[]")
834
- else
835
- result = s(:call, val[0], :"[]")
836
- end
837
- result << val[2] if val[2]
838
- }
839
- | tLBRACK aref_args tRBRACK {
840
- result = val[1] || s(:zarray)
841
- }
842
- | tLBRACE assoc_list tRCURLY {
843
- result = s(:hash, *val[1].values)
844
- }
845
- | kRETURN {
846
- result = s(:return)
847
- }
848
- | kYIELD tLPAREN2 call_args tRPAREN {
849
- result = self.new_yield(val[2]);
850
- }
851
- | kYIELD tLPAREN2 tRPAREN {
852
- result = s(:yield)
853
- }
854
- | kYIELD {
855
- result = s(:yield)
856
- }
857
- | kDEFINED opt_nl tLPAREN2 expr tRPAREN {
858
- result = s(:defined, val[3]);
859
- }
860
- | operation brace_block {
861
- name = val[0].value.to_sym
862
- iter = val[1]
863
- # iter[2] = iter[2][1] if iter[2][0] == :block and iter[2].size == 2 # HACK
864
- iter.insert 1, s(:fcall, name)
865
- result = iter
866
- }
867
- | method_call
868
- | method_call brace_block {
869
- call = val[0]
870
- iter = val[1]
871
- # iter[2] = iter[2][1] if iter[2][0] == :block and iter[2].size == 2 # HACK
872
- iter.insert 1, call
873
- result = iter
874
- }
875
- | kIF expr_value then compstmt if_tail kEND {
876
- val[1] = cond val[1]
877
- if val[1][0] == :not then
878
- result = s(:if, val[1].last, val[4], val[3])
879
- else
880
- result = s(:if, val[1], val[3], val[4])
881
- end
882
- }
883
- | kUNLESS expr_value then compstmt opt_else kEND {
884
- val[1] = cond val[1]
885
- if val[1][0] == :not then
886
- result = s(:if, val[1].last, val[3], val[4])
887
- else
888
- result = s(:if, val[1], val[4], val[3])
889
- end
890
- }
891
- | kWHILE {
892
- lexer.cond.push true
893
- } expr_value do {
894
- lexer.cond.pop
895
- } compstmt kEND {
896
- block = val[5]
897
- val[2] = cond val[2]
898
- if val[2][0] == :not then
899
- result = s(:until, val[2].last, block, true);
900
- else
901
- result = s(:while, val[2], block, true);
902
- end
903
- }
904
- | kUNTIL {
905
- lexer.cond.push true
906
- } expr_value do {
907
- lexer.cond.pop
908
- } compstmt kEND {
909
- block = val[5]
910
- val[2] = cond val[2]
911
- if val[2][0] == :not then
912
- result = s(:while, val[2].last, block, true);
913
- else
914
- result = s(:until, val[2], block, true);
915
- end
916
- }
917
- | kCASE expr_value opt_terms case_body kEND {
918
- result = s(:case, val[1]);
919
-
920
- body = val[3]
921
- while body and body.first == :when
922
- result << body
923
- body = body.delete_at 3
924
- end
925
-
926
- els = body
927
-
928
- if els and els != s(:block) then
929
- result << els
930
- else
931
- result << nil
932
- end
933
- }
934
- | kCASE opt_terms case_body kEND {
935
- result = s(:case, nil); # REFACTOR
936
-
937
- body = val[2]
938
- while body and body.first == :when
939
- result << body
940
- body = body.delete_at 3
941
- end
942
-
943
- els = body
944
-
945
- if els and els != s(:block) then
946
- result << els
947
- else
948
- result << nil
949
- end
950
- }
951
- | kCASE opt_terms kELSE compstmt kEND { # TODO: need a test
952
- result = s(:case, nil, val[3])
953
- }
954
- | kFOR block_var kIN {
955
- lexer.cond.push true
956
- } expr_value do {
957
- lexer.cond.pop;
958
- } compstmt kEND {
959
- result = s(:for, val[4], val[1])
960
- result << val[7] if val[7]
961
- }
962
- | kCLASS cpath superclass {
963
- if (self.in_def || self.in_single > 0) then
964
- yyerror("class definition in method body");
965
- end
966
- self.env.extend
967
- } bodystmt kEND {
968
- scope = s(:scope, val[4]).compact
969
- result = s(:class, val[1].last.to_sym, val[2], scope)
970
- self.env.unextend
971
- }
972
- | kCLASS tLSHFT expr {
973
- result = self.in_def
974
- self.in_def = false
975
- } term {
976
- result = self.in_single
977
- self.in_single = 0
978
- self.env.extend;
979
- } bodystmt kEND {
980
- scope = s(:scope, val[6]).compact
981
- result = s(:sclass, val[2], scope)
982
- self.env.unextend;
983
- self.in_def = val[3]
984
- self.in_single = val[5]
985
- }
986
- | kMODULE cpath {
987
- yyerror("module definition in method body") if
988
- self.in_def or self.in_single > 0
989
-
990
- self.env.extend;
991
- } bodystmt kEND {
992
- body = val[3] ? s(:scope, val[3]) : s(:scope)
993
- result = s(:module, val[1].last.to_sym, body)
994
- self.env.unextend;
995
- }
996
- | kDEF fname {
997
- self.in_def = true
998
- self.env.extend
999
- } f_arglist bodystmt kEND {
1000
- name, args, body = val[1], val[3], val[4] # TODO: refactor
1001
- name = name.value.to_sym
1002
- body ||= s(:nil)
1003
-
1004
- block_arg = args.block_arg(:remove)
1005
- body = self.block_append(args, body, body && body[0] == :block)
1006
- body.insert 2, block_arg if block_arg
1007
- result = s(:defn, name, s(:scope, body))
1008
-
1009
- self.env.unextend
1010
- self.in_def = false
1011
- }
1012
- | kDEF singleton dot_or_colon { # 0-2, 3
1013
- lexer.state = :expr_fname
1014
- } fname { # 4, 5
1015
- self.in_single += 1
1016
- self.env.extend;
1017
- lexer.state = :expr_end # force for args
1018
- } f_arglist bodystmt kEND { # 6-8
1019
- recv, name, args, body = val[1], val[4], val[6], val[7]
1020
-
1021
- block_arg = args.block_arg(:remove)
1022
- body = self.block_append(args, body, body && body[0] == :block)
1023
- body.insert 2, block_arg if block_arg
1024
-
1025
- result = s(:defs, recv, name.value.to_sym, s(:scope, body))
1026
-
1027
- self.env.unextend;
1028
- self.in_single -= 1
1029
- }
1030
- | kBREAK {
1031
- result = s(:break)
1032
- }
1033
- | kNEXT {
1034
- result = s(:next)
1035
- }
1036
- | kREDO {
1037
- result = s(:redo)
1038
- }
1039
- | kRETRY {
1040
- result = s(:retry)
1041
- }
1042
-
1043
- primary_value : primary {
1044
- result = value_expr(val[0])
1045
- }
1046
-
1047
- then : term
1048
- | ":"
1049
- | kTHEN
1050
- | term kTHEN
1051
-
1052
- do : term
1053
- | ":"
1054
- | kDO_COND
1055
-
1056
- if_tail : opt_else
1057
- | kELSIF expr_value then compstmt if_tail {
1058
- result = s(:if, val[1], val[3], val[4]);
1059
- }
1060
-
1061
- opt_else : none
1062
- | kELSE compstmt {
1063
- result = val[1];
1064
- }
1065
-
1066
- block_var : lhs
1067
- | mlhs { val[0].delete_at 1 if val[0][1].nil? } # HACK
1068
-
1069
- opt_block_var : none
1070
- | tPIPE tPIPE {
1071
- result = 0
1072
- }
1073
- | tOROP {
1074
- result = 0
1075
- }
1076
- | tPIPE block_var tPIPE {
1077
- result = val[1];
1078
- }
1079
-
1080
- do_block : kDO_BLOCK {
1081
- self.env.extend :dynamic
1082
- } opt_block_var { result = self.env.dynamic.keys }
1083
- compstmt kEND {
1084
-
1085
- vars = val[2]
1086
- body = self.dyna_init(val[4], val[3])
1087
-
1088
- result = s(:iter)
1089
- result << vars
1090
- result << val[1] if val[1]
1091
- result << body if body
1092
-
1093
- self.env.unextend;
1094
- }
1095
-
1096
- block_call : command do_block {
1097
- raise SyntaxError, "Both block arg and actual block given." if
1098
- val[0] && val[0][0] == :blockpass
1099
-
1100
- result = val[1]
1101
- result.insert 1, val[0]
1102
- }
1103
- | block_call tDOT operation2 opt_paren_args {
1104
- result = s(:call, val[0], val[2]);
1105
- result << val[3] if val[3]
1106
- }
1107
- | block_call tCOLON2 operation2 opt_paren_args {
1108
- result = s(:call, val[0], val[2]);
1109
- result << val[3] if val[3]
1110
- }
1111
-
1112
- method_call : operation paren_args {
1113
- result = new_fcall(val[0].value.to_sym, val[1])
1114
- }
1115
- | primary_value tDOT operation2 opt_paren_args {
1116
- result = new_call(val[0], val[2].value.to_sym, val[3])
1117
- }
1118
- | primary_value tCOLON2 operation2 paren_args {
1119
- result = new_call(val[0], val[2].value.to_sym, val[3])
1120
- }
1121
- | primary_value tCOLON2 operation3 {
1122
- result = new_call(val[0], val[2].value.to_sym)
1123
- }
1124
- | kSUPER paren_args {
1125
- result = self.new_super(val[1]);
1126
- }
1127
- | kSUPER {
1128
- result = s(:zsuper)
1129
- }
1130
-
1131
- brace_block : tLCURLY {
1132
- self.env.extend :dynamic
1133
- } opt_block_var { result = self.env.dynamic.keys }
1134
- compstmt tRCURLY { # REFACTOR
1135
- args = val[2]
1136
- body = self.dyna_init(val[4], val[3])
1137
- result = s(:iter)
1138
- result << args
1139
- result << body if body
1140
- self.env.unextend
1141
- }
1142
- | kDO {
1143
- self.env.extend :dynamic
1144
- } opt_block_var { result = self.env.dynamic.keys }
1145
- compstmt kEND {
1146
- args = val[2]
1147
- body = self.dyna_init(val[4], val[3])
1148
- result = s(:iter)
1149
- result << args
1150
- result << body if body
1151
- self.env.unextend
1152
- }
1153
-
1154
- case_body : kWHEN when_args then compstmt cases {
1155
- result = s(:when, val[1], val[3])
1156
- result << val[4] if val[4]
1157
- }
1158
-
1159
- when_args : args
1160
- | args ',' tSTAR arg_value {
1161
- result = self.list_append(val[0], s(:when, val[3], nil))
1162
- }
1163
- | tSTAR arg_value {
1164
- result = s(:array, s(:when, val[1], nil));
1165
- }
1166
-
1167
- cases : opt_else | case_body
1168
-
1169
- opt_rescue : kRESCUE exc_list exc_var then compstmt opt_rescue {
1170
- result = s(:resbody, val[1])
1171
- if val[2] then
1172
- val[2] = node_assign(val[2], s(:gvar, :"$!"))
1173
-
1174
- strip = val[4] && val[4][0] == :block
1175
- val[4] = block_append(val[2], val[4])
1176
- val[4].push(*val[4].pop[1..-1]) if strip # HACK removes nested block from block_append
1177
- end
1178
-
1179
- result << val[4] if val[4]
1180
- result << val[5] if val[5]
1181
- }
1182
- | {result = nil;}
1183
-
1184
- exc_list : arg_value {
1185
- result = s(:array, val[0]);
1186
- }
1187
- | mrhs
1188
- | none
1189
-
1190
- exc_var : tASSOC lhs {
1191
- result = val[1];
1192
- }
1193
- | none
1194
-
1195
- opt_ensure : kENSURE compstmt {
1196
- if (val[1] != nil) then
1197
- result = val[1];
1198
- else
1199
- result = s(:nil)
1200
- end
1201
- }
1202
- | none
1203
-
1204
- literal : numeric { result = s(:lit, val[0]) }
1205
- | symbol { result = s(:lit, val[0]) }
1206
- | dsym
1207
-
1208
- strings : string {
1209
- val[0] = s(:dstr, val[0].value) if val[0][0] == :evstr
1210
- result = val[0];
1211
- }
1212
-
1213
- string : string1
1214
- | string string1 {
1215
- result = self.literal_concat(val[0], val[1]);
1216
- }
1217
-
1218
- string1 : tSTRING_BEG string_contents tSTRING_END {
1219
- result = val[1];
1220
- }
1221
-
1222
- xstring : tXSTRING_BEG xstring_contents tSTRING_END {
1223
- node = val[1]
1224
-
1225
- unless node then
1226
- node = s(:xstr, '')
1227
- else
1228
- case node[0]
1229
- when :str
1230
- node[0] = :xstr
1231
- when :dstr
1232
- node[0] = :dxstr
1233
- else
1234
- node = s(:dxstr, '', node)
1235
- end
1236
- end
1237
-
1238
- result = node
1239
- }
1240
-
1241
- regexp : tREGEXP_BEG xstring_contents tREGEXP_END {
1242
- node = val[1] || s(:str, '')
1243
- options = val[2]
1244
-
1245
- o, k = 0, nil
1246
- options.split(//).each do |c| # FIX: this has a better home
1247
- v = {
1248
- 'x' => Regexp::EXTENDED,
1249
- 'i' => Regexp::IGNORECASE,
1250
- 'm' => Regexp::MULTILINE,
1251
- 'n' => 16,
1252
- 'e' => 32,
1253
- 's' => 48, # TODO: really?!?
1254
- 'u' => 64,
1255
- 'o' => 0, # ignore for now
1256
- }[c]
1257
- raise "unknown regexp option: #{c}" unless v
1258
- o += v
1259
- k = c if c =~ /[nesu]/
1260
- end
1261
-
1262
- case node[0]
1263
- when :str then
1264
- node[0] = :lit
1265
- node[1] = if k then
1266
- Regexp.new(node[1], o, k)
1267
- else
1268
- Regexp.new(node[1], o)
1269
- end
1270
- when :dstr then
1271
- if options =~ /o/ then
1272
- node[0] = :dregx_once
1273
- else
1274
- node[0] = :dregx
1275
- end
1276
- node << o if o and o != 0
1277
- else
1278
- node = s(:dregx, '', node);
1279
- node[0] = :dregx_once if options =~ /o/
1280
- node << o if o and o != 0
1281
- end
1282
-
1283
- result = node
1284
- }
1285
-
1286
- words : tWORDS_BEG ' ' tSTRING_END {
1287
- result = s(:zarray);
1288
- }
1289
- | tWORDS_BEG word_list tSTRING_END {
1290
- result = val[1];
1291
- }
1292
-
1293
- word_list : {
1294
- result = s(:array)
1295
- }
1296
- | word_list word ' ' {
1297
- word = val[1][0] == :evstr ? s(:dstr, '', val[1]) : val[1]
1298
- result = val[0] << word
1299
- }
1300
-
1301
- word : string_content
1302
- | word string_content {
1303
- result = self.literal_concat(val[0], val[1]);
1304
- }
1305
-
1306
- qwords : tQWORDS_BEG ' ' tSTRING_END {
1307
- result = s(:zarray)
1308
- }
1309
- | tQWORDS_BEG qword_list tSTRING_END {
1310
- result = val[1]
1311
- }
1312
-
1313
- qword_list : {
1314
- result = s(:array)
1315
- }
1316
- | qword_list tSTRING_CONTENT ' ' {
1317
- result = val[0] << val[1]
1318
- }
1319
-
1320
- string_contents: { result = s(:str, "") }
1321
- | string_contents string_content {
1322
- result = literal_concat(val[0], val[1])
1323
- }
1324
-
1325
- xstring_contents: { result = nil }
1326
- | xstring_contents string_content {
1327
- result = literal_concat(val[0], val[1])
1328
- }
1329
-
1330
- string_content : tSTRING_CONTENT
1331
- | tSTRING_DVAR {
1332
- result = lexer.str_term;
1333
- lexer.str_term = nil
1334
- lexer.state = :expr_beg
1335
- } string_dvar {
1336
- lexer.str_term = val[1]
1337
- result = s(:evstr, val[2]);
1338
- }
1339
- | tSTRING_DBEG {
1340
- result = lexer.str_term;
1341
- lexer.str_term = nil
1342
- lexer.state = :expr_beg
1343
- lexer.cond.push false
1344
- lexer.cmdarg.push false
1345
- } compstmt tRCURLY {
1346
- lexer.str_term = val[1]
1347
- lexer.cond.lexpop
1348
- lexer.cmdarg.lexpop
1349
- case val[2][0]
1350
- when :str, :dstr, :evstr then
1351
- result = val[2]
1352
- else
1353
- result = s(:evstr, val[2])
1354
- end
1355
- }
1356
-
1357
- string_dvar : tGVAR {
1358
- result = s(:gvar, val[0].value.to_sym);
1359
- }
1360
- | tIVAR {
1361
- result = s(:ivar, val[0].value.to_sym);
1362
- }
1363
- | tCVAR {
1364
- result = s(:cvar, val[0].value.to_sym);
1365
- }
1366
- | backref
1367
-
1368
-
1369
- symbol : tSYMBEG sym {
1370
- lexer.state = :expr_end
1371
- result = val[1].value.to_sym
1372
- }
1373
-
1374
- sym : fname | tIVAR | tGVAR | tCVAR
1375
-
1376
- dsym : tSYMBEG xstring_contents tSTRING_END {
1377
- lexer.state = :expr_end
1378
- result = val[1]
1379
-
1380
- yyerror("empty symbol literal") if result.nil? or result.empty?
1381
-
1382
- case result[0]
1383
- when :dstr then
1384
- result[0] = :dsym
1385
- when :str then
1386
- result = s(:lit, result.last.intern)
1387
- else
1388
- result = s(:dsym, '', result)
1389
- end
1390
-
1391
- }
1392
-
1393
- numeric : tINTEGER
1394
- | tFLOAT
1395
- | tUMINUS_NUM tINTEGER = tLOWEST {
1396
- result = -val[1] # TODO: pt_testcase
1397
- }
1398
- | tUMINUS_NUM tFLOAT = tLOWEST {
1399
- result = -val[1] # TODO: pt_testcase
1400
- }
1401
-
1402
- variable : tIDENTIFIER
1403
- | tIVAR
1404
- | tGVAR
1405
- | tCONSTANT
1406
- | tCVAR
1407
- | kNIL {
1408
- result = s(:nil)
1409
- }
1410
- | kSELF {
1411
- result = s(:self)
1412
- }
1413
- | kTRUE {
1414
- result = s(:true)
1415
- }
1416
- | kFALSE {
1417
- result = s(:false)
1418
- }
1419
- | k__FILE__ {
1420
- result = :"__FILE__"
1421
- }
1422
- | k__LINE__ {
1423
- result = :"__LINE__"
1424
- }
1425
-
1426
- var_ref : variable {
1427
- result = self.gettable(val[0])
1428
- }
1429
-
1430
- var_lhs : variable {
1431
- result = self.assignable(val[0]);
1432
- }
1433
-
1434
- backref : tNTH_REF | tBACK_REF
1435
-
1436
- superclass : term {
1437
- result = nil;
1438
- }
1439
- | tLT {
1440
- lexer.state = :expr_beg
1441
- } expr_value term {
1442
- result = val[2];
1443
- }
1444
- | error term {
1445
- yyerrok;
1446
- result = nil;
1447
- }
1448
-
1449
- f_arglist : tLPAREN2 f_args opt_nl tRPAREN {
1450
- result = val[1];
1451
- lexer.state = :expr_beg
1452
- }
1453
- | f_args term {
1454
- result = val[0];
1455
- }
1456
-
1457
- f_args : f_arg ',' f_optarg ',' f_rest_arg opt_f_block_arg {
1458
- result = val[0]
1459
- if val[2] then
1460
- val[2][1..-1].each do |lasgn| # FIX clean sexp iter
1461
- raise "wtf? #{lasgn.inspect}" unless lasgn[0] == :lasgn
1462
- result << lasgn[1]
1463
- end
1464
- end
1465
- result << val[4] if val[4]
1466
- result << val[2] if val[2]
1467
- result << val[5] if val[5]
1468
- }
1469
- | f_arg ',' f_optarg opt_f_block_arg {
1470
- result = val[0]
1471
- if val[2] then
1472
- val[2][1..-1].each do |lasgn| # FIX clean sexp iter
1473
- raise "wtf? #{lasgn.inspect}" unless lasgn[0] == :lasgn
1474
- result << lasgn[1]
1475
- end
1476
- end
1477
- result << val[2] if val[2]
1478
- result << val[3] if val[3]
1479
- }
1480
- | f_arg ',' f_rest_arg opt_f_block_arg {
1481
- result = val[0]
1482
- result << val[2] if val[2]
1483
- result << val[3] if val[3]
1484
- }
1485
- | f_arg opt_f_block_arg {
1486
- result = val[0]
1487
- result << val[1] if val[1]
1488
- }
1489
- | f_optarg ',' f_rest_arg opt_f_block_arg {
1490
- result = s(:args)
1491
- if val[0] then
1492
- val[0][1..-1].each do |lasgn| # FIX clean sexp iter
1493
- raise "wtf? #{lasgn.inspect}" unless lasgn[0] == :lasgn
1494
- result << lasgn[1]
1495
- end
1496
- end
1497
-
1498
- result << val[2] if val[2]
1499
- result << val[0] if val[0]
1500
- result << val[3] if val[3]
1501
- }
1502
- | f_optarg opt_f_block_arg {
1503
- result = s(:args)
1504
- if val[0] then
1505
- val[0][1..-1].each do |lasgn| # FIX clean sexp iter
1506
- raise "wtf? #{lasgn.inspect}" unless lasgn[0] == :lasgn
1507
- result << lasgn[1]
1508
- end
1509
- end
1510
-
1511
- result << val[0] if val[0]
1512
- result << val[1] if val[1]
1513
- }
1514
- | f_rest_arg opt_f_block_arg {
1515
- result = s(:args, val[0], val[1]).compact
1516
- }
1517
- | f_block_arg {
1518
- result = s(:args, val[0]).compact
1519
- }
1520
- | {
1521
- result = s(:args)
1522
- }
1523
-
1524
- f_norm_arg : tCONSTANT {
1525
- yyerror("formal argument cannot be a constant");
1526
- }
1527
- | tIVAR {
1528
- yyerror("formal argument cannot be an instance variable");
1529
- }
1530
- | tCVAR {
1531
- yyerror("formal argument cannot be a class variable");
1532
- }
1533
- | tIDENTIFIER {
1534
- identifier = val[0].value.to_sym
1535
- self.env[identifier] = :lvar
1536
-
1537
- result = val[0];
1538
- }
1539
-
1540
- f_arg : f_norm_arg {
1541
- result = s(:args)
1542
- result << val[0].value.to_sym
1543
- }
1544
- | f_arg ',' f_norm_arg {
1545
- val[0] << val[2].value.to_sym
1546
- result = val[0]
1547
- }
1548
-
1549
- f_opt : tIDENTIFIER '=' arg_value {
1550
- result = self.assignable(val[0], val[2]);
1551
- # TODO: detect duplicate names
1552
- }
1553
-
1554
- f_optarg : f_opt {
1555
- result = s(:block, val[0])
1556
- }
1557
- | f_optarg ',' f_opt {
1558
- result = self.append_to_block(val[0], val[2]);
1559
- }
1560
-
1561
- restarg_mark : tSTAR2 | tSTAR
1562
-
1563
- f_rest_arg : restarg_mark tIDENTIFIER { # TODO: differs from parse.y - needs tests
1564
- name = val[1].value.to_sym
1565
- self.assignable(name)
1566
- result = :"*#{name}"
1567
- }
1568
- | restarg_mark {
1569
- name = :"*"
1570
- self.env[name] = self.env.dynamic? ? :dvar : :lvar # FIX
1571
- result = name
1572
- }
1573
-
1574
- blkarg_mark : tAMPER2 | tAMPER
1575
-
1576
- f_block_arg : blkarg_mark tIDENTIFIER {
1577
- identifier = val[1].value.to_sym
1578
-
1579
- self.env[identifier] = self.env.dynamic? ? :dvar : :lvar
1580
- result = s(:block_arg, identifier.to_sym)
1581
- }
1582
-
1583
- opt_f_block_arg: ',' f_block_arg {
1584
- result = val[1];
1585
- }
1586
- | {
1587
- result = nil;
1588
- }
1589
-
1590
- singleton : var_ref
1591
- | tLPAREN2 {
1592
- lexer.state = :expr_beg
1593
- } expr opt_nl tRPAREN {
1594
- if (val[2].instanceof ILiteralNode) then
1595
- yyerror("Can't define single method for literals.");
1596
- end
1597
- result = val[2];
1598
- }
1599
-
1600
- assoc_list : none { # [!nil]
1601
- result = s(:array)
1602
- }
1603
- | assocs trailer { # [!nil]
1604
- result = val[0];
1605
- }
1606
- | args trailer {
1607
- size = val[0].size
1608
- if (size % 2 != 1) then # != 1 because of leading :array
1609
- yyerror("Odd number (#{size}) list for Hash. #{val[0].inspect}");
1610
- end
1611
- result = val[0];
1612
- }
1613
-
1614
- assocs : assoc
1615
- | assocs ',' assoc {
1616
- list = val[0].dup
1617
- more = val[2][1..-1]
1618
- list.push(*more) unless more.empty?
1619
- result = list
1620
- }
1621
-
1622
- assoc : arg_value tASSOC arg_value {
1623
- result = s(:array, val[0], val[2])
1624
- }
1625
-
1626
- operation : tIDENTIFIER | tCONSTANT | tFID
1627
- operation2 : tIDENTIFIER | tCONSTANT | tFID | op
1628
- operation3 : tIDENTIFIER | tFID | op
1629
- dot_or_colon : tDOT | tCOLON2
1630
- opt_terms : | terms
1631
- opt_nl : | "\n"
1632
- trailer : | "\n" | ','
1633
-
1634
- term : ';' { yyerrok }
1635
- | "\n"
1636
-
1637
- terms : term
1638
- | terms ';' { yyerrok }
1639
-
1640
- none : { result = nil }
1641
-
1642
- none_block_pass: { result = nil }
48
+ program: {
49
+ self.lexer.lex_state = :expr_beg
50
+ }
51
+ compstmt
52
+ {
53
+ result = val[1]
54
+ }
55
+
56
+ bodystmt: compstmt opt_rescue opt_else opt_ensure
57
+ {
58
+ result = new_body val
59
+ }
60
+
61
+ compstmt: stmts opt_terms
62
+ {
63
+ result = new_compstmt val
64
+ }
65
+
66
+ stmts: none
67
+ | stmt
68
+ | stmts terms stmt
69
+ {
70
+ result = self.block_append val[0], val[2]
71
+ }
72
+ | error stmt
73
+ {
74
+ result = val[1]
75
+ }
76
+
77
+ stmt: kALIAS fitem
78
+ {
79
+ lexer.lex_state = :expr_fname
80
+ result = self.lexer.lineno
81
+ }
82
+ fitem
83
+ {
84
+ result = s(:alias, val[1], val[3]).line(val[2])
85
+ }
86
+ | kALIAS tGVAR tGVAR
87
+ {
88
+ result = s(:valias, val[1].to_sym, val[2].to_sym)
89
+ }
90
+ | kALIAS tGVAR tBACK_REF
91
+ {
92
+ result = s(:valias, val[1].to_sym, :"$#{val[2]}")
93
+ }
94
+ | kALIAS tGVAR tNTH_REF
95
+ {
96
+ yyerror "can't make alias for the number variables"
97
+ }
98
+ | kUNDEF undef_list
99
+ {
100
+ result = val[1]
101
+ }
102
+ | stmt kIF_MOD expr_value
103
+ {
104
+ result = new_if val[2], val[0], nil
105
+ }
106
+ | stmt kUNLESS_MOD expr_value
107
+ {
108
+ result = new_if val[2], nil, val[0]
109
+ }
110
+ | stmt kWHILE_MOD expr_value
111
+ {
112
+ result = new_while val[0], val[2], true
113
+ }
114
+ | stmt kUNTIL_MOD expr_value
115
+ {
116
+ result = new_until val[0], val[2], true
117
+ }
118
+ | stmt kRESCUE_MOD stmt
119
+ {
120
+ result = s(:rescue, val[0], s(:resbody, s(:array), val[2]))
121
+ }
122
+ | klBEGIN
123
+ {
124
+ if (self.in_def || self.in_single > 0) then
125
+ yyerror "BEGIN in method"
126
+ end
127
+ self.env.extend
128
+ }
129
+ tLCURLY compstmt tRCURLY
130
+ {
131
+ result = new_iter s(:preexe), nil, val[3] # TODO: add test?
132
+ result = nil # TODO: since it isn't supposed to go in the AST
133
+ }
134
+ | klEND tLCURLY compstmt tRCURLY
135
+ {
136
+ if (self.in_def || self.in_single > 0) then
137
+ yyerror "END in method; use at_exit"
138
+ end
139
+ result = new_iter s(:postexe), nil, val[2]
140
+ }
141
+ | lhs tEQL command_call
142
+ {
143
+ result = self.node_assign val[0], val[2]
144
+ }
145
+ | mlhs tEQL command_call
146
+ {
147
+ result = new_masgn val[0], val[2], :wrap
148
+ }
149
+ | var_lhs tOP_ASGN command_call
150
+ {
151
+ result = new_op_asgn val
152
+ }
153
+ | primary_value "[" aref_args tRBRACK tOP_ASGN command_call
154
+ {
155
+ result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
156
+ }
157
+ | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
158
+ {
159
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
160
+ }
161
+ | primary_value tDOT tCONSTANT tOP_ASGN command_call
162
+ {
163
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
164
+ }
165
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
166
+ {
167
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
168
+ }
169
+ | backref tOP_ASGN command_call
170
+ {
171
+ self.backref_assign_error val[0]
172
+ }
173
+ | lhs tEQL mrhs
174
+ {
175
+ result = self.node_assign val[0], s(:svalue, val[2])
176
+ }
177
+ | mlhs tEQL arg_value
178
+ {
179
+ result = new_masgn val[0], val[2], :wrap
180
+ }
181
+ | mlhs tEQL mrhs
182
+ {
183
+ result = new_masgn val[0], val[2]
184
+ }
185
+ | expr
186
+
187
+ expr: command_call
188
+ | expr kAND expr
189
+ {
190
+ result = logop(:and, val[0], val[2])
191
+ }
192
+ | expr kOR expr
193
+ {
194
+ result = logop(:or, val[0], val[2])
195
+ }
196
+ | kNOT expr
197
+ {
198
+ result = s(:not, val[1])
199
+ }
200
+ | tBANG command_call
201
+ {
202
+ result = s(:not, val[1])
203
+ }
204
+ | arg
205
+
206
+ expr_value: expr
207
+ {
208
+ result = value_expr(val[0])
209
+ }
210
+
211
+ command_call: command
212
+ | block_command
213
+ | kRETURN call_args
214
+ {
215
+ result = s(:return, ret_args(val[1]))
216
+ }
217
+ | kBREAK call_args
218
+ {
219
+ result = s(:break, ret_args(val[1]))
220
+ }
221
+ | kNEXT call_args
222
+ {
223
+ result = s(:next, ret_args(val[1]))
224
+ }
225
+
226
+ block_command: block_call
227
+ | block_call tDOT operation2 command_args
228
+ {
229
+ result = new_call val[0], val[2], val[3]
230
+ }
231
+ | block_call tCOLON2 operation2 command_args
232
+ {
233
+ result = new_call val[0], val[2], val[3]
234
+ }
235
+
236
+ cmd_brace_block: tLBRACE_ARG
237
+ {
238
+ self.env.extend(:dynamic)
239
+ result = self.lexer.lineno
240
+ }
241
+ opt_block_var
242
+ {
243
+ result = self.env.dynamic.keys
244
+ }
245
+ compstmt tRCURLY
246
+ {
247
+ result = new_iter nil, val[2], val[4]
248
+ self.env.unextend
249
+ }
250
+
251
+ command: operation command_args =tLOWEST
252
+ {
253
+ result = new_call nil, val[0].to_sym, val[1]
254
+ }
255
+ | operation command_args cmd_brace_block
256
+ {
257
+ result = new_call nil, val[0].to_sym, val[1]
258
+ if val[2] then
259
+ if result[0] == :block_pass then
260
+ raise "both block arg and actual block given"
261
+ end
262
+ result, operation = val[2], result
263
+ result.insert 1, operation
264
+ end
265
+ }
266
+ | primary_value tDOT operation2 command_args =tLOWEST
267
+ {
268
+ result = new_call val[0], val[2].to_sym, val[3]
269
+ }
270
+ | primary_value tDOT operation2 command_args cmd_brace_block
271
+ {
272
+ result = new_call val[0], val[2].to_sym, val[3]
273
+ }
274
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
275
+ {
276
+ result = new_call val[0], val[2].to_sym, val[3]
277
+ }
278
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
279
+ {
280
+ result = new_call val[0], val[2].to_sym, val[3]
281
+ if val[4] then
282
+ if result[0] == :block_pass then # REFACTOR
283
+ raise "both block arg and actual block given"
284
+ end
285
+ val[2] << result
286
+ result = val[2]
287
+ end
288
+ }
289
+ | kSUPER command_args
290
+ {
291
+ result = new_super val[1]
292
+ }
293
+ | kYIELD command_args
294
+ {
295
+ result = new_yield val[1]
296
+ }
297
+
298
+ mlhs: mlhs_basic
299
+ | tLPAREN mlhs_entry tRPAREN
300
+ {
301
+ result = val[1]
302
+ }
303
+
304
+ mlhs_entry: mlhs_basic
305
+ | tLPAREN mlhs_entry tRPAREN
306
+ {
307
+ result = s(:masgn, s(:array, val[1]))
308
+ }
309
+
310
+ mlhs_basic: mlhs_head
311
+ {
312
+ result = s(:masgn, val[0])
313
+ }
314
+ | mlhs_head mlhs_item
315
+ {
316
+ result = s(:masgn, val[0] << val[1].compact)
317
+ }
318
+ | mlhs_head tSTAR mlhs_node
319
+ {
320
+ result = s(:masgn, val[0] << s(:splat, val[2]))
321
+ }
322
+ | mlhs_head tSTAR
323
+ {
324
+ result = s(:masgn, val[0] << s(:splat))
325
+ }
326
+ | tSTAR mlhs_node
327
+ {
328
+ result = s(:masgn, s(:array, s(:splat, val[1])))
329
+ }
330
+ | tSTAR
331
+ {
332
+ result = s(:masgn, s(:array, s(:splat)))
333
+ }
334
+
335
+ mlhs_item: mlhs_node
336
+ | tLPAREN mlhs_entry tRPAREN
337
+ {
338
+ result = val[1]
339
+ }
340
+
341
+ mlhs_head: mlhs_item tCOMMA
342
+ {
343
+ result = s(:array, val[0])
344
+ }
345
+ | mlhs_head mlhs_item tCOMMA
346
+ {
347
+ result = val[0] << val[1].compact
348
+ }
349
+
350
+ mlhs_node: variable
351
+ {
352
+ result = self.assignable val[0]
353
+ }
354
+ | primary_value "[" aref_args tRBRACK
355
+ {
356
+ result = self.aryset val[0], val[2]
357
+ }
358
+ | primary_value tDOT tIDENTIFIER
359
+ {
360
+ result = s(:attrasgn, val[0], :"#{val[2]}=", s(:arglist))
361
+ }
362
+ | primary_value tCOLON2 tIDENTIFIER
363
+ {
364
+ result = s(:attrasgn, val[0], :"#{val[2]}=", s(:arglist))
365
+ }
366
+ | primary_value tDOT tCONSTANT
367
+ {
368
+ result = s(:attrasgn, val[0], :"#{val[2]}=", s(:arglist))
369
+ }
370
+ | primary_value tCOLON2 tCONSTANT
371
+ {
372
+ if (self.in_def || self.in_single > 0) then
373
+ yyerror "dynamic constant assignment"
374
+ end
375
+
376
+ result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
377
+ }
378
+ | tCOLON3 tCONSTANT
379
+ {
380
+ if (self.in_def || self.in_single > 0) then
381
+ yyerror "dynamic constant assignment"
382
+ end
383
+
384
+ result = s(:const, nil, s(:colon3, val[1].to_sym))
385
+ }
386
+ | backref
387
+ {
388
+ self.backref_assign_error val[0]
389
+ }
390
+
391
+ lhs: variable
392
+ {
393
+ result = self.assignable val[0]
394
+ }
395
+ | primary_value "[" aref_args tRBRACK
396
+ {
397
+ result = self.aryset val[0], val[2]
398
+ }
399
+ | primary_value tDOT tIDENTIFIER
400
+ {
401
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
402
+ }
403
+ | primary_value tCOLON2 tIDENTIFIER
404
+ {
405
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
406
+ }
407
+ | primary_value tDOT tCONSTANT
408
+ {
409
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
410
+ }
411
+ | primary_value tCOLON2 tCONSTANT
412
+ {
413
+ if (self.in_def || self.in_single > 0) then
414
+ yyerror "dynamic constant assignment"
415
+ end
416
+
417
+ result = s(:const, s(:colon2, val[0], val[2].to_sym))
418
+ }
419
+ | tCOLON3 tCONSTANT
420
+ {
421
+ if (self.in_def || self.in_single > 0) then
422
+ yyerror "dynamic constant assignment"
423
+ end
424
+
425
+ result = s(:const, s(:colon3, val[1].to_sym))
426
+ }
427
+ | backref
428
+ {
429
+ self.backref_assign_error val[0]
430
+ }
431
+
432
+ cname: tIDENTIFIER
433
+ {
434
+ yyerror "class/module name must be CONSTANT"
435
+ }
436
+ | tCONSTANT
437
+
438
+ cpath: tCOLON3 cname
439
+ {
440
+ result = s(:colon3, val[1].to_sym)
441
+ }
442
+ | cname
443
+ {
444
+ result = val[0].to_sym
445
+ }
446
+ | primary_value tCOLON2 cname
447
+ {
448
+ result = s(:colon2, val[0], val[2].to_sym)
449
+ }
450
+
451
+ fname: tIDENTIFIER | tCONSTANT | tFID
452
+ | op
453
+ {
454
+ lexer.lex_state = :expr_end
455
+ result = val[0]
456
+ }
457
+
458
+ | reswords
459
+ {
460
+ lexer.lex_state = :expr_end
461
+ result = val[0]
462
+ }
463
+
464
+ # TODO: cruby has fsym and dsym
465
+ fitem: fname { result = s(:lit, val[0].to_sym) }
466
+ | symbol { result = s(:lit, val[0]) }
467
+
468
+ undef_list: fitem
469
+ {
470
+ result = new_undef val[0]
471
+ }
472
+ |
473
+ undef_list tCOMMA
474
+ {
475
+ lexer.lex_state = :expr_fname
476
+ }
477
+ fitem
478
+ {
479
+ result = new_undef val[0], val[3]
480
+ }
481
+
482
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
483
+ | tMATCH | tGT | tGEQ | tLT | tLEQ | tLSHFT
484
+ | tRSHFT | tPLUS | tMINUS | tSTAR2 | tSTAR | tDIVIDE
485
+ | tPERCENT | tPOW | tTILDE | tUPLUS | tUMINUS | tAREF
486
+ | tASET | tBACK_REF2
487
+
488
+ reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND
489
+ | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED
490
+ | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
491
+ | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
492
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF
493
+ | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
494
+ | kIF_MOD | kUNLESS_MOD | kWHILE_MOD | kUNTIL_MOD | kRESCUE_MOD
495
+
496
+ arg: lhs tEQL arg
497
+ {
498
+ result = self.node_assign val[0], val[2]
499
+ }
500
+ | lhs tEQL arg kRESCUE_MOD arg
501
+ {
502
+ result = self.node_assign val[0], s(:rescue, val[2], s(:resbody, s(:array), val[4]))
503
+ # result.line = val[0].line
504
+ }
505
+ | var_lhs tOP_ASGN arg
506
+ {
507
+ result = new_op_asgn val
508
+ }
509
+ | primary_value "[" aref_args tRBRACK tOP_ASGN arg
510
+ {
511
+ result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
512
+ val[2][0] = :arglist
513
+ }
514
+ | primary_value tDOT tIDENTIFIER tOP_ASGN arg
515
+ {
516
+ result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
517
+ }
518
+ | primary_value tDOT tCONSTANT tOP_ASGN arg
519
+ {
520
+ result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
521
+ }
522
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
523
+ {
524
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
525
+ }
526
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
527
+
528
+ {
529
+ yyerror "constant re-assignment"
530
+ }
531
+ | tCOLON3 tCONSTANT tOP_ASGN arg
532
+ {
533
+ yyerror "constant re-assignment"
534
+ }
535
+ | backref tOP_ASGN arg
536
+ {
537
+ self.backref_assign_error val[0]
538
+ }
539
+ | arg tDOT2 arg
540
+ {
541
+ v1, v2 = val[0], val[2]
542
+ if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
543
+ result = s(:lit, (v1.last)..(v2.last))
544
+ else
545
+ result = s(:dot2, v1, v2)
546
+ end
547
+ }
548
+ | arg tDOT3 arg
549
+ {
550
+ v1, v2 = val[0], val[2]
551
+ if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
552
+ result = s(:lit, (v1.last)...(v2.last))
553
+ else
554
+ result = s(:dot3, v1, v2)
555
+ end
556
+ }
557
+ | arg tPLUS arg
558
+ {
559
+ result = new_call val[0], :+, s(:arglist, val[2])
560
+ }
561
+ | arg tMINUS arg
562
+ {
563
+ result = new_call val[0], :-, s(:arglist, val[2])
564
+ }
565
+ | arg tSTAR2 arg
566
+ {
567
+ result = new_call val[0], :*, s(:arglist, val[2])
568
+ }
569
+ | arg tDIVIDE arg
570
+ {
571
+ result = new_call val[0], :"/", s(:arglist, val[2])
572
+ }
573
+ | arg tPERCENT arg
574
+ {
575
+ result = new_call val[0], :%, s(:arglist, val[2])
576
+ }
577
+ | arg tPOW arg
578
+ {
579
+ result = new_call val[0], :**, s(:arglist, val[2])
580
+ }
581
+ | tUMINUS_NUM tINTEGER tPOW arg
582
+ {
583
+ result = new_call(new_call(s(:lit, val[1]), :"**", s(:arglist, val[3])), :"-@", s(:arglist))
584
+ }
585
+ | tUMINUS_NUM tFLOAT tPOW arg
586
+ {
587
+ result = new_call(new_call(s(:lit, val[1]), :"**", s(:arglist, val[3])), :"-@", s(:arglist))
588
+ }
589
+ | tUPLUS arg
590
+ {
591
+ if val[1][0] == :lit then
592
+ result = val[1]
593
+ else
594
+ result = new_call val[1], :"+@", s(:arglist)
595
+ end
596
+ }
597
+ | tUMINUS arg
598
+ {
599
+ result = new_call val[1], :"-@", s(:arglist)
600
+ }
601
+ | arg tPIPE arg
602
+ {
603
+ result = new_call val[0], :"|", s(:arglist, val[2])
604
+ }
605
+ | arg tCARET arg
606
+ {
607
+ result = new_call val[0], :"^", s(:arglist, val[2])
608
+ }
609
+ | arg tAMPER2 arg
610
+ {
611
+ result = new_call val[0], :"&", s(:arglist, val[2])
612
+ }
613
+ | arg tCMP arg
614
+ {
615
+ result = new_call val[0], :"<=>", s(:arglist, val[2])
616
+ }
617
+ | arg tGT arg
618
+ {
619
+ result = new_call val[0], :">", s(:arglist, val[2])
620
+ }
621
+ | arg tGEQ arg
622
+ {
623
+ result = new_call val[0], :">=", s(:arglist, val[2])
624
+ }
625
+ | arg tLT arg
626
+ {
627
+ result = new_call val[0], :"<", s(:arglist, val[2])
628
+ }
629
+ | arg tLEQ arg
630
+ {
631
+ result = new_call val[0], :"<=", s(:arglist, val[2])
632
+ }
633
+ | arg tEQ arg
634
+ {
635
+ result = new_call val[0], :"==", s(:arglist, val[2])
636
+ }
637
+ | arg tEQQ arg
638
+ {
639
+ result = new_call val[0], :"===", s(:arglist, val[2])
640
+ }
641
+ | arg tNEQ arg
642
+ {
643
+ val[0] = value_expr val[0] # TODO: port call_op and clean these
644
+ val[2] = value_expr val[2]
645
+ result = s(:not, new_call(val[0], :"==", s(:arglist, val[2])))
646
+ }
647
+ | arg tMATCH arg
648
+ {
649
+ result = self.get_match_node val[0], val[2]
650
+ }
651
+ | arg tNMATCH arg
652
+ {
653
+ result = s(:not, self.get_match_node(val[0], val[2]))
654
+ }
655
+ | tBANG arg
656
+ {
657
+ result = s(:not, val[1])
658
+ }
659
+ | tTILDE arg
660
+ {
661
+ val[2] = value_expr val[2]
662
+ result = new_call val[1], :"~", s(:arglist)
663
+ }
664
+ | arg tLSHFT arg
665
+ {
666
+ val[0] = value_expr val[0]
667
+ val[2] = value_expr val[2]
668
+ result = new_call val[0], :"\<\<", s(:arglist, val[2])
669
+ }
670
+ | arg tRSHFT arg
671
+ {
672
+ val[0] = value_expr val[0]
673
+ val[2] = value_expr val[2]
674
+ result = new_call val[0], :">>", s(:arglist, val[2])
675
+ }
676
+ | arg tANDOP arg
677
+ {
678
+ result = logop(:and, val[0], val[2])
679
+ }
680
+ | arg tOROP arg
681
+ {
682
+ result = logop(:or, val[0], val[2])
683
+ }
684
+ | kDEFINED opt_nl arg
685
+ {
686
+ result = s(:defined, val[2])
687
+ }
688
+ | arg tEH arg tCOLON arg
689
+ {
690
+ result = s(:if, val[0], val[2], val[4])
691
+ }
692
+ | primary
693
+
694
+ arg_value: arg
695
+ {
696
+ result = value_expr(val[0])
697
+ }
698
+
699
+ aref_args: none
700
+ | command opt_nl
701
+ {
702
+ warning 'parenthesize argument(s) for future version'
703
+ result = s(:array, val[0])
704
+ }
705
+ | args trailer
706
+ {
707
+ result = val[0]
708
+ }
709
+ | args tCOMMA tSTAR arg opt_nl
710
+ {
711
+ result = self.arg_concat val[0], val[3]
712
+ }
713
+ | assocs trailer
714
+ {
715
+ result = s(:array, s(:hash, *val[0].values))
716
+ }
717
+ | tSTAR arg opt_nl
718
+ {
719
+ result = s(:splat, val[1])
720
+ result.paren = true
721
+ }
722
+
723
+ paren_args: tLPAREN2 none tRPAREN
724
+ {
725
+ result = val[1]
726
+ }
727
+ | tLPAREN2 call_args opt_nl tRPAREN
728
+ {
729
+ result = val[1]
730
+ }
731
+ | tLPAREN2 block_call opt_nl tRPAREN
732
+ {
733
+ warning "parenthesize argument(s) for future version"
734
+ result = s(:array, val[1])
735
+ }
736
+ | tLPAREN2 args tCOMMA block_call opt_nl tRPAREN
737
+ {
738
+ warning "parenthesize argument(s) for future version"
739
+ result = val[1].add val[3]
740
+ }
741
+
742
+ opt_paren_args: none
743
+ | paren_args
744
+
745
+ call_args: command
746
+ {
747
+ warning "parenthesize argument(s) for future version"
748
+ result = s(:array, val[0])
749
+ }
750
+ | args opt_block_arg
751
+ {
752
+ result = self.arg_blk_pass val[0], val[1]
753
+ }
754
+ | args tCOMMA tSTAR arg_value opt_block_arg
755
+ {
756
+ result = self.arg_concat val[0], val[3]
757
+ result = self.arg_blk_pass result, val[4]
758
+ }
759
+ | assocs opt_block_arg
760
+ {
761
+ result = s(:array, s(:hash, *val[0].values))
762
+ result = self.arg_blk_pass result, val[1]
763
+ }
764
+ | assocs tCOMMA tSTAR arg_value opt_block_arg
765
+ {
766
+ result = self.arg_concat s(:array, s(:hash, *val[0].values)), val[3]
767
+ result = self.arg_blk_pass result, val[4]
768
+ }
769
+ | args tCOMMA assocs opt_block_arg
770
+ {
771
+ result = val[0] << s(:hash, *val[2].values)
772
+ result = self.arg_blk_pass result, val[3]
773
+ }
774
+ | args tCOMMA assocs tCOMMA tSTAR arg opt_block_arg
775
+ {
776
+ val[0] << s(:hash, *val[2].values)
777
+ result = self.arg_concat val[0], val[5]
778
+ result = self.arg_blk_pass result, val[6]
779
+ }
780
+ | tSTAR arg_value opt_block_arg
781
+ {
782
+ result = self.arg_blk_pass s(:splat, val[1]), val[2]
783
+ }
784
+ | block_arg
785
+
786
+ call_args2: arg_value tCOMMA args opt_block_arg
787
+ {
788
+ args = self.list_prepend val[0], val[2]
789
+ result = self.arg_blk_pass args, val[3]
790
+ }
791
+ | arg_value tCOMMA block_arg
792
+ {
793
+ result = self.arg_blk_pass val[0], val[2]
794
+ }
795
+ | arg_value tCOMMA tSTAR arg_value opt_block_arg
796
+ {
797
+ result = self.arg_concat s(:array, val[0]), val[3]
798
+ result = self.arg_blk_pass result, val[4]
799
+ }
800
+ | arg_value tCOMMA args tCOMMA tSTAR arg_value opt_block_arg
801
+ {
802
+ result = self.arg_concat s(:array, val[0], s(:hash, *val[2].values)), val[5]
803
+ result = self.arg_blk_pass result, val[6]
804
+ }
805
+ | assocs opt_block_arg
806
+ {
807
+ result = s(:array, s(:hash, *val[0].values))
808
+ result = self.arg_blk_pass result, val[1]
809
+ }
810
+ | assocs tCOMMA tSTAR arg_value opt_block_arg
811
+ {
812
+ result = s(:array, s(:hash, *val[0].values), val[3])
813
+ result = self.arg_blk_pass result, val[4]
814
+ }
815
+ | arg_value tCOMMA assocs opt_block_arg
816
+ {
817
+ result = s(:array, val[0], s(:hash, *val[2].values))
818
+ result = self.arg_blk_pass result, val[3]
819
+ }
820
+ | arg_value tCOMMA args tCOMMA assocs opt_block_arg
821
+ {
822
+ result = s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values))
823
+ result = self.arg_blk_pass result, val[5]
824
+ }
825
+ | arg_value tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
826
+ {
827
+ result = self.arg_concat s(:array, val[0]).add(s(:hash, *val[2].values)), val[5]
828
+ result = self.arg_blk_pass result, val[6]
829
+ }
830
+ | arg_value tCOMMA args tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
831
+ {
832
+ result = self.arg_concat s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values)), val[7]
833
+ result = self.arg_blk_pass result, val[8]
834
+ }
835
+ | tSTAR arg_value opt_block_arg
836
+ {
837
+ result = self.arg_blk_pass s(:splat, val[1]), val[2]
838
+ }
839
+ | block_arg
840
+
841
+ command_args: {
842
+ result = lexer.cmdarg.stack.dup
843
+ lexer.cmdarg.push true
844
+ }
845
+ open_args
846
+ {
847
+ lexer.cmdarg.stack.replace val[0]
848
+ result = val[1]
849
+ }
850
+
851
+ open_args: call_args
852
+ | tLPAREN_ARG
853
+ {
854
+ lexer.lex_state = :expr_endarg
855
+ }
856
+ tRPAREN
857
+ {
858
+ warning "don't put space before argument parentheses"
859
+ result = nil
860
+ }
861
+ | tLPAREN_ARG call_args2
862
+ {
863
+ lexer.lex_state = :expr_endarg
864
+ }
865
+ tRPAREN
866
+ {
867
+ warning "don't put space before argument parentheses"
868
+ result = val[1]
869
+ }
870
+
871
+ block_arg: tAMPER arg_value
872
+ {
873
+ result = s(:block_pass, val[1])
874
+ }
875
+
876
+ opt_block_arg: tCOMMA block_arg
877
+ {
878
+ result = val[1]
879
+ }
880
+ | none_block_pass
881
+
882
+ args: arg_value
883
+ {
884
+ result = s(:array, val[0])
885
+ }
886
+ | args tCOMMA arg_value
887
+ {
888
+ result = self.list_append val[0], val[2]
889
+ }
890
+
891
+ mrhs: args tCOMMA arg_value
892
+ {
893
+ result = val[0] << val[2]
894
+ }
895
+ | args tCOMMA tSTAR arg_value
896
+ {
897
+ result = self.arg_concat val[0], val[3]
898
+ }
899
+ | tSTAR arg_value
900
+ {
901
+ result = s(:splat, val[1])
902
+ }
903
+
904
+ primary: literal
905
+ | strings
906
+ | xstring
907
+ | regexp
908
+ | words
909
+ | awords
910
+ | var_ref
911
+ | backref
912
+ | tFID
913
+ {
914
+ result = new_call nil, val[0].to_sym
915
+ }
916
+ | kBEGIN
917
+ {
918
+ result = self.lexer.lineno
919
+ }
920
+ bodystmt kEND
921
+ {
922
+ unless val[2] then
923
+ result = s(:nil)
924
+ else
925
+ result = s(:begin, val[2])
926
+ end
927
+
928
+ result.line = val[1]
929
+ }
930
+ | tLPAREN_ARG expr
931
+ {
932
+ lexer.lex_state = :expr_endarg
933
+ }
934
+ opt_nl tRPAREN
935
+ {
936
+ warning "(...) interpreted as grouped expression"
937
+ result = val[1]
938
+ }
939
+ | tLPAREN compstmt tRPAREN
940
+ {
941
+ result = val[1] || s(:nil)
942
+ result.paren = true
943
+ }
944
+ | primary_value tCOLON2 tCONSTANT
945
+ {
946
+ result = s(:colon2, val[0], val[2].to_sym)
947
+ }
948
+ | tCOLON3 tCONSTANT
949
+ {
950
+ result = s(:colon3, val[1].to_sym)
951
+ }
952
+ | primary_value "[" aref_args tRBRACK
953
+ {
954
+ result = new_aref val
955
+ }
956
+ | tLBRACK aref_args tRBRACK
957
+ {
958
+ result = val[1] || s(:array)
959
+ }
960
+ | tLBRACE assoc_list tRCURLY
961
+ {
962
+ result = s(:hash, *val[1].values)
963
+ }
964
+ | kRETURN
965
+ {
966
+ result = s(:return)
967
+ }
968
+ | kYIELD tLPAREN2 call_args tRPAREN
969
+ {
970
+ result = new_yield val[2]
971
+ }
972
+ | kYIELD tLPAREN2 tRPAREN
973
+ {
974
+ result = new_yield
975
+ }
976
+ | kYIELD
977
+ {
978
+ result = new_yield
979
+ }
980
+ | kDEFINED opt_nl tLPAREN2 expr tRPAREN
981
+ {
982
+ result = s(:defined, val[3])
983
+ }
984
+ | operation brace_block
985
+ {
986
+ oper, iter = val[0], val[1]
987
+ call = new_call(nil, oper.to_sym)
988
+ iter.insert 1, call
989
+ result = iter
990
+ call.line ||= iter.line
991
+ }
992
+ | method_call
993
+ | method_call brace_block
994
+ {
995
+ call, iter = val[0], val[1]
996
+ iter.insert 1, call
997
+ result = iter
998
+ }
999
+ | kIF expr_value then compstmt if_tail kEND
1000
+ {
1001
+ result = new_if val[1], val[3], val[4]
1002
+ }
1003
+ | kUNLESS expr_value then compstmt opt_else kEND
1004
+ {
1005
+ result = new_if val[1], val[4], val[3]
1006
+ }
1007
+ | kWHILE
1008
+ {
1009
+ lexer.cond.push true
1010
+ }
1011
+ expr_value do
1012
+ {
1013
+ lexer.cond.pop
1014
+ }
1015
+ compstmt kEND
1016
+ {
1017
+ result = new_while val[5], val[2], true
1018
+ }
1019
+ | kUNTIL
1020
+ {
1021
+ lexer.cond.push true
1022
+ }
1023
+ expr_value do
1024
+ {
1025
+ lexer.cond.pop
1026
+ }
1027
+ compstmt kEND
1028
+ {
1029
+ result = new_until val[5], val[2], true
1030
+ }
1031
+ | kCASE expr_value opt_terms case_body kEND
1032
+ {
1033
+ result = new_case val[1], val[3]
1034
+ }
1035
+ | kCASE opt_terms case_body kEND
1036
+ {
1037
+ result = new_case nil, val[2]
1038
+ }
1039
+ | kCASE opt_terms kELSE compstmt kEND # TODO: need a test
1040
+ {
1041
+ result = new_case nil, val[3]
1042
+ }
1043
+ | kFOR block_var kIN
1044
+ {
1045
+ lexer.cond.push true
1046
+ }
1047
+ expr_value do
1048
+ {
1049
+ lexer.cond.pop
1050
+ }
1051
+ compstmt kEND
1052
+ {
1053
+ result = new_for val[4], val[1], val[7]
1054
+ }
1055
+ | kCLASS
1056
+ {
1057
+ result = self.lexer.lineno
1058
+ }
1059
+ cpath superclass
1060
+ {
1061
+ self.comments.push self.lexer.comments
1062
+ if (self.in_def || self.in_single > 0) then
1063
+ yyerror "class definition in method body"
1064
+ end
1065
+ self.env.extend
1066
+ }
1067
+ bodystmt kEND
1068
+ {
1069
+ result = new_class val
1070
+ self.env.unextend
1071
+ }
1072
+ | kCLASS tLSHFT
1073
+ {
1074
+ result = self.lexer.lineno
1075
+ }
1076
+ expr
1077
+ {
1078
+ result = self.in_def
1079
+ self.in_def = false
1080
+ }
1081
+ term
1082
+ {
1083
+ result = self.in_single
1084
+ self.in_single = 0
1085
+ self.env.extend
1086
+ }
1087
+ bodystmt kEND
1088
+ {
1089
+ result = new_sclass val
1090
+ self.env.unextend
1091
+ }
1092
+ | kMODULE
1093
+ {
1094
+ result = self.lexer.lineno
1095
+ }
1096
+ cpath
1097
+ {
1098
+ self.comments.push self.lexer.comments
1099
+ yyerror "module definition in method body" if
1100
+ self.in_def or self.in_single > 0
1101
+
1102
+ self.env.extend
1103
+ }
1104
+ bodystmt kEND
1105
+ {
1106
+ result = new_module val
1107
+ self.env.unextend
1108
+ }
1109
+ | kDEF fname
1110
+ {
1111
+ self.comments.push self.lexer.comments
1112
+ self.in_def = true
1113
+ self.env.extend
1114
+ result = self.lexer.lineno
1115
+ }
1116
+ f_arglist bodystmt kEND
1117
+ {
1118
+ result = new_defn val
1119
+ self.env.unextend
1120
+ self.in_def = false
1121
+ }
1122
+ | kDEF singleton dot_or_colon
1123
+ {
1124
+ self.comments.push self.lexer.comments
1125
+ lexer.lex_state = :expr_fname
1126
+ }
1127
+ fname
1128
+ {
1129
+ self.in_single += 1
1130
+ self.env.extend
1131
+ lexer.lex_state = :expr_end # force for args
1132
+ }
1133
+ f_arglist bodystmt kEND
1134
+ {
1135
+ result = new_defs val
1136
+
1137
+ self.env.unextend
1138
+ self.in_single -= 1
1139
+ }
1140
+ | kBREAK
1141
+ {
1142
+ result = s(:break)
1143
+ }
1144
+ | kNEXT
1145
+ {
1146
+ result = s(:next)
1147
+ }
1148
+ | kREDO
1149
+ {
1150
+ result = s(:redo)
1151
+ }
1152
+ | kRETRY
1153
+ {
1154
+ result = s(:retry)
1155
+ }
1156
+
1157
+ primary_value: primary
1158
+ {
1159
+ result = value_expr(val[0])
1160
+ }
1161
+
1162
+ then: term
1163
+ | tCOLON
1164
+ | kTHEN
1165
+ | term kTHEN
1166
+
1167
+ do: term
1168
+ | tCOLON
1169
+ | kDO_COND
1170
+
1171
+ if_tail: opt_else
1172
+ | kELSIF expr_value then compstmt if_tail
1173
+ {
1174
+ result = s(:if, val[1], val[3], val[4])
1175
+ }
1176
+
1177
+ opt_else: none
1178
+ | kELSE compstmt
1179
+ {
1180
+ result = val[1]
1181
+ }
1182
+
1183
+ block_var: lhs
1184
+ | mlhs
1185
+ {
1186
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1187
+ }
1188
+
1189
+ opt_block_var: none
1190
+ | tPIPE tPIPE
1191
+ {
1192
+ result = 0
1193
+ }
1194
+ | tOROP
1195
+ {
1196
+ result = 0
1197
+ }
1198
+ | tPIPE block_var tPIPE
1199
+ {
1200
+ result = val[1]
1201
+ }
1202
+
1203
+ do_block: kDO_BLOCK
1204
+ {
1205
+ self.env.extend :dynamic
1206
+ }
1207
+ opt_block_var
1208
+ {
1209
+ result = self.env.dynamic.keys
1210
+ }
1211
+ compstmt kEND
1212
+ {
1213
+ vars = val[2]
1214
+ body = val[4]
1215
+ result = new_iter nil, vars, body
1216
+
1217
+ self.env.unextend
1218
+ }
1219
+
1220
+ block_call: command do_block
1221
+ {
1222
+ raise SyntaxError, "Both block arg and actual block given." if
1223
+ val[0] && val[0][0] == :blockpass
1224
+
1225
+ result = val[1]
1226
+ result.insert 1, val[0]
1227
+ }
1228
+ | block_call tDOT operation2 opt_paren_args
1229
+ {
1230
+ result = new_call val[0], val[2], val[3]
1231
+ }
1232
+ | block_call tCOLON2 operation2 opt_paren_args
1233
+ {
1234
+ result = new_call val[0], val[2], val[3]
1235
+ }
1236
+
1237
+ method_call: operation
1238
+ {
1239
+ result = self.lexer.lineno
1240
+ }
1241
+ paren_args
1242
+ {
1243
+ result = new_call nil, val[0].to_sym, val[2]
1244
+ }
1245
+ | primary_value tDOT operation2 opt_paren_args
1246
+ {
1247
+ result = new_call val[0], val[2].to_sym, val[3]
1248
+ }
1249
+ | primary_value tCOLON2 operation2 paren_args
1250
+ {
1251
+ result = new_call val[0], val[2].to_sym, val[3]
1252
+ }
1253
+ | primary_value tCOLON2 operation3
1254
+ {
1255
+ result = new_call val[0], val[2].to_sym
1256
+ }
1257
+ | kSUPER paren_args
1258
+ {
1259
+ result = new_super val[1]
1260
+ }
1261
+ | kSUPER
1262
+ {
1263
+ result = s(:zsuper)
1264
+ }
1265
+
1266
+ brace_block: tLCURLY
1267
+ {
1268
+ self.env.extend :dynamic
1269
+ result = self.lexer.lineno
1270
+ }
1271
+ opt_block_var
1272
+ {
1273
+ result = self.env.dynamic.keys
1274
+ }
1275
+ compstmt tRCURLY
1276
+ {
1277
+ # REFACTOR
1278
+ args = val[2]
1279
+ body = val[4]
1280
+ result = new_iter nil, args, body
1281
+ self.env.unextend
1282
+ result.line = val[1]
1283
+ }
1284
+ | kDO
1285
+ {
1286
+ self.env.extend :dynamic
1287
+ result = self.lexer.lineno
1288
+ }
1289
+ opt_block_var
1290
+ {
1291
+ result = self.env.dynamic.keys
1292
+ }
1293
+ compstmt kEND
1294
+ {
1295
+ args = val[2]
1296
+ body = val[4]
1297
+ result = new_iter nil, args, body
1298
+ self.env.unextend
1299
+ result.line = val[1]
1300
+ }
1301
+
1302
+ case_body: kWHEN
1303
+ {
1304
+ result = self.lexer.lineno
1305
+ }
1306
+ when_args then compstmt cases
1307
+ {
1308
+ result = s(:when, val[2], val[4])
1309
+ result.line = val[1]
1310
+ result << val[5] if val[5]
1311
+ }
1312
+
1313
+ when_args: args
1314
+ | args tCOMMA tSTAR arg_value
1315
+ {
1316
+ result = self.list_append val[0], s(:when, val[3], nil)
1317
+ }
1318
+ | tSTAR arg_value
1319
+ {
1320
+ result = s(:array, s(:when, val[1], nil))
1321
+ }
1322
+
1323
+ cases: opt_else | case_body
1324
+
1325
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1326
+ {
1327
+ klasses, var, body, rest = val[1], val[2], val[4], val[5]
1328
+
1329
+ klasses ||= s(:array)
1330
+ klasses << node_assign(var, s(:gvar, :"$!")) if var
1331
+
1332
+ result = s(:resbody, klasses, body)
1333
+ result << rest if rest # UGH, rewritten above
1334
+ }
1335
+ |
1336
+ {
1337
+ result = nil
1338
+ }
1339
+
1340
+ exc_list: arg_value
1341
+ {
1342
+ result = s(:array, val[0])
1343
+ }
1344
+ | mrhs
1345
+ | none
1346
+
1347
+ exc_var: tASSOC lhs
1348
+ {
1349
+ result = val[1]
1350
+ }
1351
+ | none
1352
+
1353
+ opt_ensure: kENSURE compstmt
1354
+ {
1355
+ if (val[1] != nil) then
1356
+ result = val[1]
1357
+ else
1358
+ result = s(:nil)
1359
+ end
1360
+ }
1361
+ | none
1362
+
1363
+ literal: numeric { result = s(:lit, val[0]) }
1364
+ | symbol { result = s(:lit, val[0]) }
1365
+ | dsym
1366
+
1367
+ strings: string
1368
+ {
1369
+ val[0] = s(:dstr, val[0].value) if val[0][0] == :evstr
1370
+ result = val[0]
1371
+ }
1372
+
1373
+ string: string1
1374
+ | string string1
1375
+ {
1376
+ result = self.literal_concat val[0], val[1]
1377
+ }
1378
+
1379
+ string1: tSTRING_BEG string_contents tSTRING_END
1380
+ {
1381
+ result = val[1]
1382
+ }
1383
+ | tSTRING
1384
+ {
1385
+ result = s(:str, val[0])
1386
+ }
1387
+
1388
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1389
+ {
1390
+ result = new_xstring val[1]
1391
+ }
1392
+
1393
+ regexp: tREGEXP_BEG xstring_contents tREGEXP_END
1394
+ {
1395
+ result = new_regexp val
1396
+ }
1397
+
1398
+ words: tWORDS_BEG tSPACE tSTRING_END
1399
+ {
1400
+ result = s(:array)
1401
+ }
1402
+ | tWORDS_BEG word_list tSTRING_END
1403
+ {
1404
+ result = val[1]
1405
+ }
1406
+
1407
+ word_list: none
1408
+ {
1409
+ result = s(:array)
1410
+ }
1411
+ | word_list word tSPACE
1412
+ {
1413
+ word = val[1][0] == :evstr ? s(:dstr, "", val[1]) : val[1]
1414
+ result = val[0] << word
1415
+ }
1416
+
1417
+ word: string_content
1418
+ | word string_content
1419
+ {
1420
+ result = self.literal_concat val[0], val[1]
1421
+ }
1422
+
1423
+ awords: tAWORDS_BEG tSPACE tSTRING_END
1424
+ {
1425
+ result = s(:array)
1426
+ }
1427
+ | tAWORDS_BEG qword_list tSTRING_END
1428
+ {
1429
+ result = val[1]
1430
+ }
1431
+
1432
+ qword_list: none
1433
+ {
1434
+ result = s(:array)
1435
+ }
1436
+ | qword_list tSTRING_CONTENT tSPACE
1437
+ {
1438
+ result = val[0] << s(:str, val[1])
1439
+ }
1440
+
1441
+ string_contents: none
1442
+ {
1443
+ result = s(:str, "")
1444
+ }
1445
+ | string_contents string_content
1446
+ {
1447
+ result = literal_concat(val[0], val[1])
1448
+ }
1449
+
1450
+ xstring_contents: none
1451
+ {
1452
+ result = nil
1453
+ }
1454
+ | xstring_contents string_content
1455
+ {
1456
+ result = literal_concat(val[0], val[1])
1457
+ }
1458
+
1459
+ string_content: tSTRING_CONTENT
1460
+ {
1461
+ result = s(:str, val[0])
1462
+ }
1463
+ | tSTRING_DVAR
1464
+ {
1465
+ result = lexer.lex_strterm
1466
+ lexer.lex_strterm = nil
1467
+ lexer.lex_state = :expr_beg
1468
+ }
1469
+ string_dvar
1470
+ {
1471
+ lexer.lex_strterm = val[1]
1472
+ result = s(:evstr, val[2])
1473
+ }
1474
+ | tSTRING_DBEG
1475
+ {
1476
+ result = lexer.lex_strterm
1477
+ lexer.lex_strterm = nil
1478
+ lexer.lex_state = :expr_beg
1479
+ lexer.cond.push false
1480
+ lexer.cmdarg.push false
1481
+ }
1482
+ compstmt tRCURLY
1483
+ {
1484
+ lexer.lex_strterm = val[1]
1485
+ lexer.cond.lexpop
1486
+ lexer.cmdarg.lexpop
1487
+
1488
+ case val[2]
1489
+ when Sexp then
1490
+ case val[2][0]
1491
+ when :str, :dstr, :evstr then
1492
+ result = val[2]
1493
+ else
1494
+ result = s(:evstr, val[2])
1495
+ end
1496
+ when nil then
1497
+ result = s(:evstr)
1498
+ else
1499
+ raise "unknown rescue body: #{val[2].inspect}"
1500
+ end
1501
+ }
1502
+
1503
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1504
+ | tIVAR { result = s(:ivar, val[0].to_sym) }
1505
+ | tCVAR { result = s(:cvar, val[0].to_sym) }
1506
+ | backref
1507
+
1508
+
1509
+ symbol: tSYMBEG sym
1510
+ {
1511
+ lexer.lex_state = :expr_end
1512
+ result = val[1].to_sym
1513
+ }
1514
+ | tSYMBOL
1515
+ {
1516
+ result = val[0].to_sym
1517
+ }
1518
+
1519
+ sym: fname | tIVAR | tGVAR | tCVAR
1520
+
1521
+ dsym: tSYMBEG xstring_contents tSTRING_END
1522
+ {
1523
+ lexer.lex_state = :expr_end
1524
+ result = val[1]
1525
+
1526
+ yyerror "empty symbol literal" if
1527
+ result.nil? or result.empty?
1528
+
1529
+ case result[0]
1530
+ when :dstr then
1531
+ result[0] = :dsym
1532
+ when :str then
1533
+ result = s(:lit, result.last.intern)
1534
+ else
1535
+ result = s(:dsym, "", result)
1536
+ end
1537
+ }
1538
+
1539
+ numeric: tINTEGER
1540
+ | tFLOAT
1541
+ | tUMINUS_NUM tINTEGER =tLOWEST
1542
+ {
1543
+ result = -val[1] # TODO: pt_testcase
1544
+ }
1545
+ | tUMINUS_NUM tFLOAT =tLOWEST
1546
+ {
1547
+ result = -val[1] # TODO: pt_testcase
1548
+ }
1549
+
1550
+ variable: tIDENTIFIER
1551
+ | tIVAR
1552
+ | tGVAR
1553
+ | tCONSTANT
1554
+ | tCVAR
1555
+ | kNIL { result = :nil }
1556
+ | kSELF { result = :self }
1557
+ | kTRUE { result = :true }
1558
+ | kFALSE { result = :false }
1559
+ | k__FILE__ { result = :__FILE__ }
1560
+ | k__LINE__ { result = :__LINE__ }
1561
+
1562
+ var_ref: variable
1563
+ {
1564
+ result = self.gettable val[0]
1565
+ }
1566
+
1567
+ var_lhs: variable
1568
+ {
1569
+ result = self.assignable val[0]
1570
+ }
1571
+
1572
+ backref: tNTH_REF { result = s(:nth_ref, val[0]) }
1573
+ | tBACK_REF { result = s(:back_ref, val[0]) }
1574
+
1575
+ superclass: term
1576
+ {
1577
+ result = nil
1578
+ }
1579
+ | tLT
1580
+ {
1581
+ lexer.lex_state = :expr_beg
1582
+ }
1583
+ expr_value term
1584
+ {
1585
+ result = val[2]
1586
+ }
1587
+ | error term
1588
+ {
1589
+ yyerrok
1590
+ result = nil
1591
+ }
1592
+
1593
+ f_arglist: tLPAREN2 f_args opt_nl tRPAREN
1594
+ {
1595
+ result = val[1]
1596
+ lexer.lex_state = :expr_beg
1597
+ }
1598
+ | f_args term
1599
+ {
1600
+ result = val[0]
1601
+ }
1602
+
1603
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
1604
+ {
1605
+ result = args val[0], val[2], val[4], val[5]
1606
+ }
1607
+ | f_arg tCOMMA f_optarg opt_f_block_arg
1608
+ {
1609
+ result = args val[0], val[2], nil, val[3]
1610
+ }
1611
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
1612
+ {
1613
+ result = args val[0], nil, val[2], val[3]
1614
+ }
1615
+ | f_arg opt_f_block_arg
1616
+ {
1617
+ result = args val[0], nil, nil, val[1]
1618
+ }
1619
+ | f_optarg tCOMMA f_rest_arg opt_f_block_arg
1620
+ {
1621
+ result = args nil, val[0], val[2], val[3]
1622
+ }
1623
+ | f_optarg opt_f_block_arg
1624
+ {
1625
+ result = args nil, val[0], nil, val[1]
1626
+ }
1627
+ | f_rest_arg opt_f_block_arg
1628
+ {
1629
+ result = args nil, nil, val[0], val[1]
1630
+ }
1631
+ | f_block_arg
1632
+ {
1633
+ result = args nil, nil, nil, val[0]
1634
+ }
1635
+ |
1636
+ {
1637
+ result = args nil, nil, nil, nil
1638
+ }
1639
+
1640
+ f_norm_arg: tCONSTANT
1641
+ {
1642
+ yyerror "formal argument cannot be a constant: #{val[0]}"
1643
+ }
1644
+ | tIVAR
1645
+ {
1646
+ yyerror "formal argument cannot be an instance variable"
1647
+ }
1648
+ | tCVAR
1649
+ {
1650
+ yyerror "formal argument cannot be a class variable"
1651
+ }
1652
+ | tIDENTIFIER
1653
+ {
1654
+ identifier = val[0].to_sym
1655
+ self.env[identifier] = :lvar
1656
+
1657
+ result = val[0]
1658
+ }
1659
+
1660
+ f_arg: f_norm_arg
1661
+ {
1662
+ result = s(:args)
1663
+ result << val[0].to_sym
1664
+ }
1665
+ | f_arg tCOMMA f_norm_arg
1666
+ {
1667
+ val[0] << val[2].to_sym
1668
+ result = val[0]
1669
+ }
1670
+
1671
+ f_opt: tIDENTIFIER tEQL arg_value
1672
+ {
1673
+ result = self.assignable val[0], val[2]
1674
+ # TODO: detect duplicate names
1675
+ }
1676
+
1677
+ f_optarg: f_opt
1678
+ {
1679
+ result = s(:block, val[0])
1680
+ }
1681
+ | f_optarg tCOMMA f_opt
1682
+ {
1683
+ result = self.append_to_block val[0], val[2]
1684
+ }
1685
+
1686
+ restarg_mark: tSTAR2 | tSTAR
1687
+
1688
+ f_rest_arg: restarg_mark tIDENTIFIER
1689
+ {
1690
+ # TODO: differs from parse.y - needs tests
1691
+ name = val[1].to_sym
1692
+ self.assignable name
1693
+ result = :"*#{name}"
1694
+ }
1695
+ | restarg_mark
1696
+ {
1697
+ name = :"*"
1698
+ self.env[name] = :lvar
1699
+ result = name
1700
+ }
1701
+
1702
+ blkarg_mark: tAMPER2 | tAMPER
1703
+
1704
+ f_block_arg: blkarg_mark tIDENTIFIER
1705
+ {
1706
+ identifier = val[1].to_sym
1707
+
1708
+ self.env[identifier] = :lvar
1709
+ result = s(:block_arg, identifier.to_sym)
1710
+ }
1711
+
1712
+ opt_f_block_arg: tCOMMA f_block_arg
1713
+ {
1714
+ result = val[1]
1715
+ }
1716
+ |
1717
+ {
1718
+ result = nil
1719
+ }
1720
+
1721
+ singleton: var_ref
1722
+ | tLPAREN2
1723
+ {
1724
+ lexer.lex_state = :expr_beg
1725
+ }
1726
+ expr opt_nl tRPAREN
1727
+ {
1728
+ result = val[2]
1729
+ yyerror "Can't define single method for literals." if
1730
+ result[0] == :lit
1731
+ }
1732
+
1733
+ assoc_list: none # [!nil]
1734
+ {
1735
+ result = s(:array)
1736
+ }
1737
+ | assocs trailer # [!nil]
1738
+ {
1739
+ result = val[0]
1740
+ }
1741
+ | args trailer
1742
+ {
1743
+ size = val[0].size
1744
+ if (size % 2 != 1) then # != 1 because of leading :array
1745
+ yyerror "Odd number (#{size}) list for Hash. #{val[0].inspect}"
1746
+ end
1747
+ result = val[0]
1748
+ }
1749
+
1750
+ assocs: assoc
1751
+ | assocs tCOMMA assoc
1752
+ {
1753
+ list = val[0].dup
1754
+ more = val[2][1..-1]
1755
+ list.push(*more) unless more.empty?
1756
+ result = list
1757
+ }
1758
+
1759
+ assoc: arg_value tASSOC arg_value
1760
+ {
1761
+ result = s(:array, val[0], val[2])
1762
+ }
1763
+
1764
+ operation: tIDENTIFIER | tCONSTANT | tFID
1765
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
1766
+ operation3: tIDENTIFIER | tFID | op
1767
+ dot_or_colon: tDOT | tCOLON2
1768
+ opt_terms: | terms
1769
+ opt_nl: | tNL
1770
+ trailer: | tNL | tCOMMA
1771
+
1772
+ term: tSEMI { yyerrok }
1773
+ | tNL
1774
+
1775
+ terms: term
1776
+ | terms tSEMI { yyerrok }
1777
+
1778
+ none: { result = nil }
1779
+
1780
+ none_block_pass: { result = nil }
1643
1781
 
1644
1782
  end
1645
1783
 
1646
1784
  ---- inner
1647
1785
 
1648
- require 'ruby_lexer'
1786
+ require "ruby_lexer"
1787
+
1788
+ # Local Variables: **
1789
+ # racc-token-length-max:14 **
1790
+ # End: **