ruby_parser 2.3.1 → 3.0.0.a1

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.

@@ -0,0 +1,2014 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby19Parser
4
+
5
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
6
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
7
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
8
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
9
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
10
+ k__FILE__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tLABEL tCVAR tNTH_REF
11
+ tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT tREGEXP_END tUPLUS
12
+ tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ tGEQ tLEQ tANDOP
13
+ tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF tASET tLSHFT tRSHFT
14
+ tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN tLPAREN2 tRPAREN tLPAREN_ARG
15
+ tLBRACK tLBRACK2 tRBRACK tLBRACE tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2
16
+ tTILDE tPERCENT tDIVIDE tPLUS tMINUS tLT tGT tPIPE tBANG tCARET
17
+ tLCURLY tRCURLY tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
18
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END tSTRING
19
+ tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAST_TOKEN tLAMBDA tLAMBEG
20
+
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
+
46
+ rule
47
+
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], new_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 tLBRACK2 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
+ line = val[0].last
216
+ result = s(:return, ret_args(val[1])).line(line)
217
+ }
218
+ | kBREAK call_args
219
+ {
220
+ line = val[0].last
221
+ result = s(:break, ret_args(val[1])).line(line)
222
+ }
223
+ | kNEXT call_args
224
+ {
225
+ line = val[0].last
226
+ result = s(:next, ret_args(val[1])).line(line)
227
+ }
228
+
229
+ block_command: block_call
230
+ | block_call tDOT operation2 command_args
231
+ {
232
+ result = new_call val[0], val[2], val[3]
233
+ }
234
+ | block_call tCOLON2 operation2 command_args
235
+ {
236
+ result = new_call val[0], val[2], val[3]
237
+ }
238
+
239
+ cmd_brace_block: tLBRACE_ARG
240
+ {
241
+ self.env.extend(:dynamic)
242
+ result = self.lexer.lineno
243
+ }
244
+ opt_block_var
245
+ {
246
+ result = self.env.dynamic.keys
247
+ }
248
+ compstmt tRCURLY
249
+ {
250
+ result = new_iter nil, val[2], val[4]
251
+ self.env.unextend
252
+ }
253
+
254
+ command: operation command_args =tLOWEST
255
+ {
256
+ result = new_call nil, val[0].to_sym, val[1]
257
+ }
258
+ | operation command_args cmd_brace_block
259
+ {
260
+ result = new_call nil, val[0].to_sym, val[1]
261
+ if val[2] then
262
+ if result[0] == :block_pass then
263
+ raise "both block arg and actual block given"
264
+ end
265
+ result, operation = val[2], result
266
+ result.insert 1, operation
267
+ end
268
+ }
269
+ | primary_value tDOT operation2 command_args =tLOWEST
270
+ {
271
+ result = new_call val[0], val[2].to_sym, val[3]
272
+ }
273
+ | primary_value tDOT operation2 command_args cmd_brace_block
274
+ {
275
+ result = new_call val[0], val[2].to_sym, val[3]
276
+ }
277
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
278
+ {
279
+ result = new_call val[0], val[2].to_sym, val[3]
280
+ }
281
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
282
+ {
283
+ result = new_call val[0], val[2].to_sym, val[3]
284
+ if val[4] then
285
+ if result[0] == :block_pass then # REFACTOR
286
+ raise "both block arg and actual block given"
287
+ end
288
+ val[2] << result
289
+ result = val[2]
290
+ end
291
+ }
292
+ | kSUPER command_args
293
+ {
294
+ result = new_super val[1]
295
+ }
296
+ | kYIELD command_args
297
+ {
298
+ result = new_yield val[1]
299
+ }
300
+
301
+ mlhs: mlhs_basic
302
+ | tLPAREN mlhs_entry rparen
303
+ {
304
+ result = val[1]
305
+ }
306
+
307
+ mlhs_entry: mlhs_basic
308
+ | tLPAREN mlhs_entry rparen
309
+ {
310
+ result = s(:masgn, s(:array, val[1]))
311
+ }
312
+
313
+ mlhs_basic: mlhs_head
314
+ {
315
+ result = s(:masgn, val[0])
316
+ }
317
+ | mlhs_head mlhs_item
318
+ {
319
+ result = s(:masgn, val[0] << val[1].compact)
320
+ }
321
+ | mlhs_head tSTAR mlhs_node
322
+ {
323
+ result = s(:masgn, val[0] << s(:splat, val[2]))
324
+ }
325
+ | mlhs_head tSTAR
326
+ {
327
+ result = s(:masgn, val[0] << s(:splat))
328
+ }
329
+ | tSTAR mlhs_node
330
+ {
331
+ result = s(:masgn, s(:array, s(:splat, val[1])))
332
+ }
333
+ | tSTAR
334
+ {
335
+ result = s(:masgn, s(:array, s(:splat)))
336
+ }
337
+
338
+ mlhs_item: mlhs_node
339
+ | tLPAREN mlhs_entry rparen
340
+ {
341
+ result = val[1]
342
+ }
343
+
344
+ mlhs_head: mlhs_item tCOMMA
345
+ {
346
+ result = s(:array, val[0])
347
+ }
348
+ | mlhs_head mlhs_item tCOMMA
349
+ {
350
+ result = val[0] << val[1].compact
351
+ }
352
+
353
+ mlhs_node: user_variable
354
+ {
355
+ result = self.assignable val[0]
356
+ }
357
+ | keyword_variable
358
+ {
359
+ result = self.assignable val[0]
360
+ }
361
+ | primary_value tLBRACK2 aref_args tRBRACK
362
+ {
363
+ result = self.aryset val[0], val[2]
364
+ }
365
+ | primary_value tDOT tIDENTIFIER
366
+ {
367
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
368
+ }
369
+ | primary_value tCOLON2 tIDENTIFIER
370
+ {
371
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
372
+ }
373
+ | primary_value tDOT tCONSTANT
374
+ {
375
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
376
+ }
377
+ | primary_value tCOLON2 tCONSTANT
378
+ {
379
+ if (self.in_def || self.in_single > 0) then
380
+ yyerror "dynamic constant assignment"
381
+ end
382
+
383
+ result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
384
+ }
385
+ | tCOLON3 tCONSTANT
386
+ {
387
+ if (self.in_def || self.in_single > 0) then
388
+ yyerror "dynamic constant assignment"
389
+ end
390
+
391
+ result = s(:const, nil, s(:colon3, val[1].to_sym))
392
+ }
393
+ | backref
394
+ {
395
+ self.backref_assign_error val[0]
396
+ }
397
+
398
+ lhs: user_variable
399
+ {
400
+ result = self.assignable val[0]
401
+ }
402
+ | keyword_variable
403
+ {
404
+ result = self.assignable val[0]
405
+ }
406
+ | primary_value tLBRACK2 aref_args tRBRACK
407
+ {
408
+ result = self.aryset val[0], val[2]
409
+ }
410
+ | primary_value tDOT tIDENTIFIER
411
+ {
412
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
413
+ }
414
+ | primary_value tCOLON2 tIDENTIFIER
415
+ {
416
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
417
+ }
418
+ | primary_value tDOT tCONSTANT
419
+ {
420
+ result = s(:attrasgn, val[0], :"#{val[2]}=")
421
+ }
422
+ | primary_value tCOLON2 tCONSTANT
423
+ {
424
+ if (self.in_def || self.in_single > 0) then
425
+ yyerror "dynamic constant assignment"
426
+ end
427
+
428
+ result = s(:const, s(:colon2, val[0], val[2].to_sym))
429
+ }
430
+ | tCOLON3 tCONSTANT
431
+ {
432
+ if (self.in_def || self.in_single > 0) then
433
+ yyerror "dynamic constant assignment"
434
+ end
435
+
436
+ result = s(:const, s(:colon3, val[1].to_sym))
437
+ }
438
+ | backref
439
+ {
440
+ self.backref_assign_error val[0]
441
+ }
442
+
443
+ cname: tIDENTIFIER
444
+ {
445
+ yyerror "class/module name must be CONSTANT"
446
+ }
447
+ | tCONSTANT
448
+
449
+ cpath: tCOLON3 cname
450
+ {
451
+ result = s(:colon3, val[1].to_sym)
452
+ }
453
+ | cname
454
+ {
455
+ result = val[0].to_sym
456
+ }
457
+ | primary_value tCOLON2 cname
458
+ {
459
+ result = s(:colon2, val[0], val[2].to_sym)
460
+ }
461
+
462
+ fname: tIDENTIFIER | tCONSTANT | tFID
463
+ | op
464
+ {
465
+ lexer.lex_state = :expr_end
466
+ result = val[0]
467
+ }
468
+
469
+ | reswords
470
+ {
471
+ lexer.lex_state = :expr_end
472
+ result = val[0]
473
+ }
474
+
475
+ fsym: fname | symbol
476
+
477
+ fitem: fsym { result = s(:lit, val[0].to_sym) }
478
+ | dsym
479
+
480
+ undef_list: fitem
481
+ {
482
+ result = new_undef val[0]
483
+ }
484
+ |
485
+ undef_list tCOMMA
486
+ {
487
+ lexer.lex_state = :expr_fname
488
+ }
489
+ fitem
490
+ {
491
+ result = new_undef val[0], val[3]
492
+ }
493
+
494
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
495
+ | tMATCH | tGT | tGEQ | tLT | tLEQ | tLSHFT
496
+ | tRSHFT | tPLUS | tMINUS | tSTAR2 | tSTAR | tDIVIDE
497
+ | tPERCENT | tPOW | tTILDE | tUPLUS | tUMINUS | tAREF
498
+ | tASET | tBACK_REF2
499
+
500
+ reswords: k__LINE__ | k__FILE__ | klBEGIN | klEND | kALIAS | kAND
501
+ | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | kDEFINED
502
+ | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE
503
+ | kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT
504
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN | kSELF
505
+ | kSUPER | kTHEN | kTRUE | kUNDEF | kWHEN | kYIELD
506
+ | kIF | kUNLESS | kWHILE | kUNTIL
507
+
508
+ arg: lhs tEQL arg
509
+ {
510
+ result = self.node_assign val[0], val[2]
511
+ }
512
+ | lhs tEQL arg kRESCUE_MOD arg
513
+ {
514
+ result = self.node_assign val[0], s(:rescue, val[2], new_resbody(s(:array), val[4]))
515
+ # result.line = val[0].line
516
+ }
517
+ | var_lhs tOP_ASGN arg
518
+ {
519
+ result = new_op_asgn val
520
+ }
521
+ | primary_value tLBRACK2 aref_args tRBRACK tOP_ASGN arg
522
+ {
523
+ val[2][0] = :arglist
524
+ result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
525
+ }
526
+ | primary_value tDOT tIDENTIFIER tOP_ASGN arg
527
+ {
528
+ result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
529
+ }
530
+ | primary_value tDOT tCONSTANT tOP_ASGN arg
531
+ {
532
+ result = s(:op_asgn2, val[0], :"#{val[2]}=", val[3].to_sym, val[4])
533
+ }
534
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
535
+ {
536
+ result = s(:op_asgn, val[0], val[4], val[2], val[3])
537
+ }
538
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
539
+
540
+ {
541
+ yyerror "constant re-assignment"
542
+ }
543
+ | tCOLON3 tCONSTANT tOP_ASGN arg
544
+ {
545
+ yyerror "constant re-assignment"
546
+ }
547
+ | backref tOP_ASGN arg
548
+ {
549
+ self.backref_assign_error val[0]
550
+ }
551
+ | arg tDOT2 arg
552
+ {
553
+ v1, v2 = val[0], val[2]
554
+ if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
555
+ result = s(:lit, (v1.last)..(v2.last))
556
+ else
557
+ result = s(:dot2, v1, v2)
558
+ end
559
+ }
560
+ | arg tDOT3 arg
561
+ {
562
+ v1, v2 = val[0], val[2]
563
+ if v1.node_type == :lit and v2.node_type == :lit and Fixnum === v1.last and Fixnum === v2.last then
564
+ result = s(:lit, (v1.last)...(v2.last))
565
+ else
566
+ result = s(:dot3, v1, v2)
567
+ end
568
+ }
569
+ | arg tPLUS arg
570
+ {
571
+ result = new_call val[0], :+, argl(val[2])
572
+ }
573
+ | arg tMINUS arg
574
+ {
575
+ result = new_call val[0], :-, argl(val[2])
576
+ }
577
+ | arg tSTAR2 arg
578
+ {
579
+ result = new_call val[0], :*, argl(val[2])
580
+ }
581
+ | arg tDIVIDE arg
582
+ {
583
+ result = new_call val[0], :"/", argl(val[2])
584
+ }
585
+ | arg tPERCENT arg
586
+ {
587
+ result = new_call val[0], :"%", argl(val[2])
588
+ }
589
+ | arg tPOW arg
590
+ {
591
+ result = new_call val[0], :**, argl(val[2])
592
+ }
593
+ | tUMINUS_NUM tINTEGER tPOW arg
594
+ {
595
+ result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
596
+ }
597
+ | tUMINUS_NUM tFLOAT tPOW arg
598
+ {
599
+ result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
600
+ }
601
+ | tUPLUS arg
602
+ {
603
+ if val[1][0] == :lit then
604
+ result = val[1]
605
+ else
606
+ result = new_call val[1], :"+@"
607
+ end
608
+ }
609
+ | tUMINUS arg
610
+ {
611
+ result = new_call val[1], :"-@"
612
+ }
613
+ | arg tPIPE arg
614
+ {
615
+ result = new_call val[0], :"|", argl(val[2])
616
+ }
617
+ | arg tCARET arg
618
+ {
619
+ result = new_call val[0], :"^", argl(val[2])
620
+ }
621
+ | arg tAMPER2 arg
622
+ {
623
+ result = new_call val[0], :"&", argl(val[2])
624
+ }
625
+ | arg tCMP arg
626
+ {
627
+ result = new_call val[0], :"<=>", argl(val[2])
628
+ }
629
+ | arg tGT arg
630
+ {
631
+ result = new_call val[0], :">", argl(val[2])
632
+ }
633
+ | arg tGEQ arg
634
+ {
635
+ result = new_call val[0], :">=", argl(val[2])
636
+ }
637
+ | arg tLT arg
638
+ {
639
+ result = new_call val[0], :"<", argl(val[2])
640
+ }
641
+ | arg tLEQ arg
642
+ {
643
+ result = new_call val[0], :"<=", argl(val[2])
644
+ }
645
+ | arg tEQ arg
646
+ {
647
+ result = new_call val[0], :"==", argl(val[2])
648
+ }
649
+ | arg tEQQ arg
650
+ {
651
+ result = new_call val[0], :"===", argl(val[2])
652
+ }
653
+ | arg tNEQ arg
654
+ {
655
+ result = new_call val[0], :"!=", argl(val[2])
656
+ }
657
+ | arg tMATCH arg
658
+ {
659
+ result = self.get_match_node val[0], val[2]
660
+ }
661
+ | arg tNMATCH arg
662
+ {
663
+ result = s(:not, self.get_match_node(val[0], val[2]))
664
+ }
665
+ | tBANG arg
666
+ {
667
+ result = new_call val[1], :"!@"
668
+ }
669
+ | tTILDE arg
670
+ {
671
+ val[2] = value_expr val[2]
672
+ result = new_call val[1], :"~"
673
+ }
674
+ | arg tLSHFT arg
675
+ {
676
+ val[0] = value_expr val[0]
677
+ val[2] = value_expr val[2]
678
+ result = new_call val[0], :"\<\<", argl(val[2])
679
+ }
680
+ | arg tRSHFT arg
681
+ {
682
+ val[0] = value_expr val[0]
683
+ val[2] = value_expr val[2]
684
+ result = new_call val[0], :">>", argl(val[2])
685
+ }
686
+ | arg tANDOP arg
687
+ {
688
+ result = logop(:and, val[0], val[2])
689
+ }
690
+ | arg tOROP arg
691
+ {
692
+ result = logop(:or, val[0], val[2])
693
+ }
694
+ | kDEFINED opt_nl arg
695
+ {
696
+ result = s(:defined, val[2])
697
+ }
698
+ | arg tEH arg tCOLON arg
699
+ {
700
+ lexer.tern.pop
701
+ result = s(:if, val[0], val[2], val[4])
702
+ }
703
+ | primary
704
+
705
+ arg_value: arg
706
+ {
707
+ result = value_expr(val[0])
708
+ }
709
+
710
+ aref_args: none
711
+ | command opt_nl
712
+ {
713
+ warning 'parenthesize argument(s) for future version'
714
+ result = s(:array, val[0])
715
+ }
716
+ | args trailer
717
+ {
718
+ result = val[0]
719
+ }
720
+ | args tCOMMA tSTAR arg opt_nl
721
+ {
722
+ result = self.arg_concat val[0], val[3]
723
+ }
724
+ | assocs trailer
725
+ {
726
+ result = s(:array, s(:hash, *val[0].values))
727
+ }
728
+ | args tCOMMA assocs trailer
729
+ {
730
+ result = val[0] << s(:hash, *val[2].values)
731
+ }
732
+ | tSTAR arg opt_nl
733
+ {
734
+ result = s(:array, s(:splat, val[1]))
735
+ }
736
+
737
+ paren_args: tLPAREN2 opt_call_args rparen
738
+ {
739
+ result = val[1]
740
+ }
741
+
742
+ opt_call_args: none
743
+ {
744
+ result = val[0]
745
+ }
746
+ | call_args
747
+ {
748
+ result = val[0]
749
+ }
750
+ | args tCOMMA
751
+ {
752
+ result = val[0]
753
+ }
754
+ | block_call
755
+ {
756
+ warning "parenthesize argument(s) for future version"
757
+ result = s(:array, val[0])
758
+ }
759
+ | args tCOMMA block_call
760
+ {
761
+ warning "parenthesize argument(s) for future version"
762
+ result = val[0].add val[2]
763
+ }
764
+
765
+ opt_paren_args: none
766
+ | paren_args
767
+
768
+ call_args: command
769
+ {
770
+ warning "parenthesize argument(s) for future version"
771
+ result = s(:array, val[0])
772
+ }
773
+ | args opt_block_arg
774
+ {
775
+ result = self.arg_blk_pass val[0], val[1]
776
+ }
777
+ | args tCOMMA tSTAR arg_value opt_block_arg
778
+ {
779
+ result = self.arg_concat val[0], val[3]
780
+ result = self.arg_blk_pass result, val[4]
781
+ }
782
+ | args tCOMMA tSTAR arg_value tCOMMA args opt_block_arg
783
+ {
784
+ result = self.arg_concat val[0], val[3]
785
+ val[5][1..-1].each {|a| result << a }
786
+ result = self.arg_blk_pass result, val[6]
787
+ }
788
+ | assocs opt_block_arg
789
+ {
790
+ result = s(:array, s(:hash, *val[0].values))
791
+ result = self.arg_blk_pass result, val[1]
792
+ }
793
+ | assocs tCOMMA tSTAR arg_value opt_block_arg
794
+ {
795
+ result = self.arg_concat s(:array, s(:hash, *val[0].values)), val[3]
796
+ result = self.arg_blk_pass result, val[4]
797
+ }
798
+ | args tCOMMA assocs opt_block_arg
799
+ {
800
+ result = val[0] << s(:hash, *val[2].values)
801
+ result = self.arg_blk_pass result, val[3]
802
+ }
803
+ | args tCOMMA assocs tCOMMA tSTAR arg opt_block_arg
804
+ {
805
+ val[0] << s(:hash, *val[2].values)
806
+ result = self.arg_concat val[0], val[5]
807
+ result = self.arg_blk_pass result, val[6]
808
+ }
809
+ | tSTAR arg_value opt_block_arg
810
+ {
811
+ result = self.arg_blk_pass s(:splat, val[1]), val[2]
812
+ }
813
+ | block_arg
814
+
815
+ call_args2: arg_value tCOMMA args opt_block_arg
816
+ {
817
+ args = self.list_prepend val[0], val[2]
818
+ result = self.arg_blk_pass args, val[3]
819
+ }
820
+ | arg_value tCOMMA block_arg
821
+ {
822
+ result = self.arg_blk_pass val[0], val[2]
823
+ }
824
+ | arg_value tCOMMA tSTAR arg_value opt_block_arg
825
+ {
826
+ result = self.arg_concat s(:array, val[0]), val[3]
827
+ result = self.arg_blk_pass result, val[4]
828
+ }
829
+ | arg_value tCOMMA args tCOMMA tSTAR arg_value opt_block_arg
830
+ {
831
+ result = self.arg_concat s(:array, val[0], s(:hash, *val[2].values)), val[5]
832
+ result = self.arg_blk_pass result, val[6]
833
+ }
834
+ | assocs opt_block_arg
835
+ {
836
+ result = s(:array, s(:hash, *val[0].values))
837
+ result = self.arg_blk_pass result, val[1]
838
+ }
839
+ | assocs tCOMMA tSTAR arg_value opt_block_arg
840
+ {
841
+ result = s(:array, s(:hash, *val[0].values), val[3])
842
+ result = self.arg_blk_pass result, val[4]
843
+ }
844
+ | arg_value tCOMMA assocs opt_block_arg
845
+ {
846
+ result = s(:array, val[0], s(:hash, *val[2].values))
847
+ result = self.arg_blk_pass result, val[3]
848
+ }
849
+ | arg_value tCOMMA args tCOMMA assocs opt_block_arg
850
+ {
851
+ result = s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values))
852
+ result = self.arg_blk_pass result, val[5]
853
+ }
854
+ | arg_value tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
855
+ {
856
+ result = self.arg_concat s(:array, val[0]).add(s(:hash, *val[2].values)), val[5]
857
+ result = self.arg_blk_pass result, val[6]
858
+ }
859
+ | arg_value tCOMMA args tCOMMA assocs tCOMMA tSTAR arg_value opt_block_arg
860
+ {
861
+ result = self.arg_concat s(:array, val[0]).add_all(val[2]).add(s(:hash, *val[4].values)), val[7]
862
+ result = self.arg_blk_pass result, val[8]
863
+ }
864
+ | tSTAR arg_value opt_block_arg
865
+ {
866
+ result = self.arg_blk_pass s(:splat, val[1]), val[2]
867
+ }
868
+ | block_arg
869
+
870
+ command_args: {
871
+ result = lexer.cmdarg.stack.dup
872
+ lexer.cmdarg.push true
873
+ }
874
+ open_args
875
+ {
876
+ lexer.cmdarg.stack.replace val[0]
877
+ result = val[1]
878
+ }
879
+
880
+ open_args: call_args
881
+ | tLPAREN_ARG
882
+ {
883
+ lexer.lex_state = :expr_endarg
884
+ }
885
+ tRPAREN
886
+ {
887
+ warning "don't put space before argument parentheses"
888
+ result = nil
889
+ }
890
+ | tLPAREN_ARG call_args2
891
+ {
892
+ lexer.lex_state = :expr_endarg
893
+ }
894
+ tRPAREN
895
+ {
896
+ warning "don't put space before argument parentheses"
897
+ result = val[1]
898
+ }
899
+
900
+ block_arg: tAMPER arg_value
901
+ {
902
+ result = s(:block_pass, val[1])
903
+ }
904
+
905
+ opt_block_arg: tCOMMA block_arg
906
+ {
907
+ result = val[1]
908
+ }
909
+ | none
910
+
911
+ args: arg_value
912
+ {
913
+ result = s(:array, val[0])
914
+ }
915
+ | args tCOMMA arg_value
916
+ {
917
+ result = self.list_append val[0], val[2]
918
+ }
919
+
920
+ mrhs: args tCOMMA arg_value
921
+ {
922
+ result = val[0] << val[2]
923
+ }
924
+ | args tCOMMA tSTAR arg_value
925
+ {
926
+ result = self.arg_concat val[0], val[3]
927
+ }
928
+ | tSTAR arg_value
929
+ {
930
+ result = s(:splat, val[1])
931
+ }
932
+
933
+ primary: literal
934
+ | strings
935
+ | xstring
936
+ | regexp
937
+ | words
938
+ | qwords
939
+ | var_ref
940
+ | backref
941
+ | tFID
942
+ {
943
+ result = new_call nil, val[0].to_sym
944
+ }
945
+ | kBEGIN
946
+ {
947
+ result = self.lexer.lineno
948
+ }
949
+ bodystmt kEND
950
+ {
951
+ unless val[2] then
952
+ result = s(:nil)
953
+ else
954
+ result = s(:begin, val[2])
955
+ end
956
+
957
+ result.line = val[1]
958
+ }
959
+ | tLPAREN_ARG expr
960
+ {
961
+ lexer.lex_state = :expr_endarg
962
+ }
963
+ rparen
964
+ {
965
+ warning "(...) interpreted as grouped expression"
966
+ result = val[1]
967
+ }
968
+ | tLPAREN compstmt tRPAREN
969
+ {
970
+ result = val[1] || s(:nil)
971
+ result.paren = true
972
+ }
973
+ | primary_value tCOLON2 tCONSTANT
974
+ {
975
+ result = s(:colon2, val[0], val[2].to_sym)
976
+ }
977
+ | tCOLON3 tCONSTANT
978
+ {
979
+ result = s(:colon3, val[1].to_sym)
980
+ }
981
+ | primary_value tLBRACK2 aref_args tRBRACK
982
+ {
983
+ result = new_aref val
984
+ }
985
+ | tLBRACK aref_args tRBRACK
986
+ {
987
+ result = val[1] || s(:array)
988
+ }
989
+ | tLBRACE assoc_list tRCURLY
990
+ {
991
+ result = s(:hash, *val[1].values)
992
+ }
993
+ | kRETURN
994
+ {
995
+ result = s(:return)
996
+ }
997
+ | kYIELD tLPAREN2 call_args rparen
998
+ {
999
+ result = new_yield val[2]
1000
+ }
1001
+ | kYIELD tLPAREN2 rparen
1002
+ {
1003
+ result = new_yield
1004
+ }
1005
+ | kYIELD
1006
+ {
1007
+ result = new_yield
1008
+ }
1009
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1010
+ {
1011
+ result = s(:defined, val[3])
1012
+ }
1013
+ | operation brace_block
1014
+ {
1015
+ oper, iter = val[0], val[1]
1016
+ call = new_call nil, oper.to_sym
1017
+ iter.insert 1, call
1018
+ result = iter
1019
+ call.line = iter.line
1020
+ }
1021
+ | method_call
1022
+ | method_call brace_block
1023
+ {
1024
+ call, iter = val[0], val[1]
1025
+ iter.insert 1, call
1026
+ result = iter
1027
+ }
1028
+ | tLAMBDA lambda
1029
+ {
1030
+ result = val[1]
1031
+ }
1032
+ | kIF expr_value then compstmt if_tail kEND
1033
+ {
1034
+ result = new_if val[1], val[3], val[4]
1035
+ }
1036
+ | kUNLESS expr_value then compstmt opt_else kEND
1037
+ {
1038
+ result = new_if val[1], val[4], val[3]
1039
+ }
1040
+ | kWHILE
1041
+ {
1042
+ lexer.cond.push true
1043
+ }
1044
+ expr_value do
1045
+ {
1046
+ lexer.cond.pop
1047
+ }
1048
+ compstmt kEND
1049
+ {
1050
+ result = new_while val[5], val[2], true
1051
+ }
1052
+ | kUNTIL
1053
+ {
1054
+ lexer.cond.push true
1055
+ }
1056
+ expr_value do
1057
+ {
1058
+ lexer.cond.pop
1059
+ }
1060
+ compstmt kEND
1061
+ {
1062
+ result = new_until val[5], val[2], true
1063
+ }
1064
+ | kCASE expr_value opt_terms case_body kEND
1065
+ {
1066
+ result = new_case val[1], val[3]
1067
+ }
1068
+ | kCASE opt_terms case_body kEND
1069
+ {
1070
+ result = new_case nil, val[2]
1071
+ }
1072
+ | kCASE opt_terms kELSE compstmt kEND # TODO: need a test
1073
+ {
1074
+ result = new_case nil, val[3]
1075
+ }
1076
+ | kFOR for_var kIN
1077
+ {
1078
+ lexer.cond.push true
1079
+ }
1080
+ expr_value do
1081
+ {
1082
+ lexer.cond.pop
1083
+ }
1084
+ compstmt kEND
1085
+ {
1086
+ result = new_for val[4], val[1], val[7]
1087
+ }
1088
+ | kCLASS
1089
+ {
1090
+ result = self.lexer.lineno
1091
+ }
1092
+ cpath superclass
1093
+ {
1094
+ self.comments.push self.lexer.comments
1095
+ if (self.in_def || self.in_single > 0) then
1096
+ yyerror "class definition in method body"
1097
+ end
1098
+ self.env.extend
1099
+ }
1100
+ bodystmt kEND
1101
+ {
1102
+ result = new_class val
1103
+ self.env.unextend
1104
+ }
1105
+ | kCLASS tLSHFT
1106
+ {
1107
+ result = self.lexer.lineno
1108
+ }
1109
+ expr
1110
+ {
1111
+ result = self.in_def
1112
+ self.in_def = false
1113
+ }
1114
+ term
1115
+ {
1116
+ result = self.in_single
1117
+ self.in_single = 0
1118
+ self.env.extend
1119
+ }
1120
+ bodystmt kEND
1121
+ {
1122
+ result = new_sclass val
1123
+ self.env.unextend
1124
+ }
1125
+ | kMODULE
1126
+ {
1127
+ result = self.lexer.lineno
1128
+ }
1129
+ cpath
1130
+ {
1131
+ self.comments.push self.lexer.comments
1132
+ yyerror "module definition in method body" if
1133
+ self.in_def or self.in_single > 0
1134
+
1135
+ self.env.extend
1136
+ }
1137
+ bodystmt kEND
1138
+ {
1139
+ result = new_module val
1140
+ self.env.unextend
1141
+ }
1142
+ | kDEF fname
1143
+ {
1144
+ self.comments.push self.lexer.comments
1145
+ self.in_def = true
1146
+ self.env.extend
1147
+ result = lexer.lineno, lexer.src.beginning_of_line?
1148
+ }
1149
+ f_arglist bodystmt kEND
1150
+ {
1151
+ result = new_defn val
1152
+ self.env.unextend
1153
+ self.in_def = false
1154
+ }
1155
+ | kDEF singleton dot_or_colon
1156
+ {
1157
+ self.comments.push self.lexer.comments
1158
+ lexer.lex_state = :expr_fname
1159
+ }
1160
+ fname
1161
+ {
1162
+ self.in_single += 1
1163
+ self.env.extend
1164
+ lexer.lex_state = :expr_end # force for args
1165
+ }
1166
+ f_arglist bodystmt kEND
1167
+ {
1168
+ result = new_defs val
1169
+
1170
+ self.env.unextend
1171
+ self.in_single -= 1
1172
+ }
1173
+ | kBREAK
1174
+ {
1175
+ result = s(:break)
1176
+ }
1177
+ | kNEXT
1178
+ {
1179
+ result = s(:next)
1180
+ }
1181
+ | kREDO
1182
+ {
1183
+ result = s(:redo)
1184
+ }
1185
+ | kRETRY
1186
+ {
1187
+ result = s(:retry)
1188
+ }
1189
+
1190
+ primary_value: primary
1191
+ {
1192
+ result = value_expr(val[0])
1193
+ }
1194
+
1195
+ # These are really stupid
1196
+ k_begin: kBEGIN
1197
+ k_if: kIF
1198
+ k_unless: kUNLESS
1199
+ k_while: kWHILE
1200
+ k_until: kUNTIL
1201
+ k_case: kCASE
1202
+ k_for: kFOR
1203
+ k_class: kCLASS
1204
+ k_module: kMODULE
1205
+ k_def: kDEF
1206
+ k_end: kEND
1207
+
1208
+ then: term
1209
+ | tCOLON
1210
+ | kTHEN
1211
+ | term kTHEN
1212
+
1213
+ do: term
1214
+ | tCOLON
1215
+ | kDO_COND
1216
+
1217
+ if_tail: opt_else
1218
+ | kELSIF expr_value then compstmt if_tail
1219
+ {
1220
+ result = s(:if, val[1], val[3], val[4])
1221
+ }
1222
+
1223
+ opt_else: none
1224
+ | kELSE compstmt
1225
+ {
1226
+ result = val[1]
1227
+ }
1228
+
1229
+ for_var: lhs
1230
+ | mlhs
1231
+ {
1232
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1233
+ }
1234
+
1235
+ block_par: mlhs_item
1236
+ {
1237
+ result = s(:array, val[0])
1238
+ }
1239
+ | block_par tCOMMA mlhs_item
1240
+ {
1241
+ result = self.list_append val[0], val[2]
1242
+ }
1243
+
1244
+ block_var: block_par
1245
+ {
1246
+ result = block_var val[0], nil, nil
1247
+ }
1248
+ | block_par tCOMMA
1249
+ {
1250
+ result = block_var val[0], nil, nil
1251
+ }
1252
+ | block_par tCOMMA tAMPER lhs
1253
+ {
1254
+ result = block_var val[0], nil, val[3]
1255
+ }
1256
+ | block_par tCOMMA tSTAR lhs tCOMMA tAMPER lhs
1257
+ {
1258
+ result = block_var val[0], val[3], val[6]
1259
+ }
1260
+ | block_par tCOMMA tSTAR tCOMMA tAMPER lhs
1261
+ {
1262
+ result = block_var val[0], s(:splat), val[5]
1263
+ }
1264
+ | block_par tCOMMA tSTAR lhs
1265
+ {
1266
+ result = block_var val[0], val[3], nil
1267
+ }
1268
+ | block_par tCOMMA tSTAR
1269
+ {
1270
+ result = block_var val[0], s(:splat), nil
1271
+ }
1272
+ | tSTAR lhs tCOMMA tAMPER lhs
1273
+ {
1274
+ result = block_var nil, val[1], val[4]
1275
+ }
1276
+ | tSTAR tCOMMA tAMPER lhs
1277
+ {
1278
+ result = block_var nil, s(:splat), val[3]
1279
+ }
1280
+ | tSTAR lhs
1281
+ {
1282
+ result = block_var nil, val[1], nil
1283
+ }
1284
+ | tSTAR
1285
+ {
1286
+ result = block_var nil, s(:splat), nil
1287
+ }
1288
+ | tAMPER lhs
1289
+ {
1290
+ result = block_var nil, nil, val[1]
1291
+ }
1292
+ ;
1293
+
1294
+ opt_block_var: none
1295
+ | tPIPE tPIPE
1296
+ {
1297
+ result = 0
1298
+ self.lexer.command_start = true
1299
+ }
1300
+ | tOROP
1301
+ {
1302
+ result = 0
1303
+ self.lexer.command_start = true
1304
+ }
1305
+ | tPIPE block_var tPIPE
1306
+ {
1307
+ result = val[1]
1308
+ self.lexer.command_start = true
1309
+ }
1310
+ | tPIPE tAMPER block_var tPIPE
1311
+ {
1312
+ result = s(:lasgn, :"&block")
1313
+ self.lexer.command_start = true
1314
+ }
1315
+
1316
+ opt_bv_decl: none
1317
+ | tSEMI bv_decls
1318
+ {
1319
+ result = val[1]
1320
+ }
1321
+
1322
+ bv_decls: bvar
1323
+ | bv_decls tCOMMA bvar
1324
+ {
1325
+ result = val[0] << val[2]
1326
+ }
1327
+
1328
+ bvar: tIDENTIFIER
1329
+ | f_bad_arg
1330
+
1331
+ lambda: lambda_body
1332
+ {
1333
+ call = new_call nil, :lambda
1334
+ result = s(:iter, call, 0, val[0])
1335
+ }
1336
+ | f_larglist lambda_body
1337
+ {
1338
+ case val[0].size
1339
+ when 1
1340
+ args = 0
1341
+ when 2
1342
+ args = s(:lasgn, val[0][1])
1343
+ else
1344
+ vars = val[0][1..-1].map { |name| s(:lasgn, name) }
1345
+ args = s(:masgn, s(:array, *vars))
1346
+ end
1347
+
1348
+ call = new_call nil, :lambda
1349
+ result = s(:iter, call, args, val[1])
1350
+ }
1351
+
1352
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1353
+ {
1354
+ result = val[1]
1355
+ }
1356
+ | f_args
1357
+ {
1358
+ result = val[0]
1359
+ }
1360
+
1361
+ lambda_body: tLAMBEG compstmt tRCURLY
1362
+ {
1363
+ result = val[1]
1364
+ }
1365
+ | kDO_LAMBDA compstmt kEND
1366
+ {
1367
+ result = val[1]
1368
+ }
1369
+
1370
+ do_block: kDO_BLOCK
1371
+ {
1372
+ self.env.extend :dynamic
1373
+ result = self.lexer.lineno
1374
+ }
1375
+ opt_block_var
1376
+ {
1377
+ result = self.env.dynamic.keys
1378
+ }
1379
+ compstmt kEND
1380
+ {
1381
+ vars = val[2]
1382
+ body = val[4]
1383
+ result = new_iter nil, vars, body
1384
+ result.line = val[1]
1385
+
1386
+ self.env.unextend
1387
+ }
1388
+
1389
+ block_call: command do_block
1390
+ {
1391
+ raise SyntaxError, "Both block arg and actual block given." if
1392
+ val[0] && val[0][0] == :blockpass
1393
+
1394
+ result = val[1]
1395
+ result.insert 1, val[0]
1396
+ }
1397
+ | block_call tDOT operation2 opt_paren_args
1398
+ {
1399
+ result = new_call val[0], val[2], val[3]
1400
+ }
1401
+ | block_call tCOLON2 operation2 opt_paren_args
1402
+ {
1403
+ result = new_call val[0], val[2], val[3]
1404
+ }
1405
+
1406
+ method_call: operation
1407
+ {
1408
+ result = self.lexer.lineno
1409
+ }
1410
+ paren_args
1411
+ {
1412
+ result = new_call nil, val[0].to_sym, val[2]
1413
+ }
1414
+ | primary_value tDOT operation2 opt_paren_args
1415
+ {
1416
+ result = new_call val[0], val[2].to_sym, val[3]
1417
+ }
1418
+ | primary_value tCOLON2 operation2 paren_args
1419
+ {
1420
+ result = new_call val[0], val[2].to_sym, val[3]
1421
+ }
1422
+ | primary_value tCOLON2 operation3
1423
+ {
1424
+ result = new_call val[0], val[2].to_sym
1425
+ }
1426
+ | kSUPER paren_args
1427
+ {
1428
+ result = new_super val[1]
1429
+ }
1430
+ | kSUPER
1431
+ {
1432
+ result = s(:zsuper)
1433
+ }
1434
+
1435
+ brace_block: tLCURLY
1436
+ {
1437
+ self.env.extend :dynamic
1438
+ result = self.lexer.lineno
1439
+ }
1440
+ opt_block_var
1441
+ {
1442
+ result = self.env.dynamic.keys
1443
+ }
1444
+ compstmt tRCURLY
1445
+ {
1446
+ # REFACTOR
1447
+ args = val[2]
1448
+ body = val[4]
1449
+ result = new_iter nil, args, body
1450
+ self.env.unextend
1451
+ result.line = val[1]
1452
+ }
1453
+ | kDO
1454
+ {
1455
+ self.env.extend :dynamic
1456
+ result = self.lexer.lineno
1457
+ }
1458
+ opt_block_var
1459
+ {
1460
+ result = self.env.dynamic.keys
1461
+ }
1462
+ compstmt kEND
1463
+ {
1464
+ args = val[2]
1465
+ body = val[4]
1466
+ result = new_iter nil, args, body
1467
+ self.env.unextend
1468
+ result.line = val[1]
1469
+ }
1470
+
1471
+ case_body: kWHEN
1472
+ {
1473
+ result = self.lexer.lineno
1474
+ }
1475
+ when_args then compstmt cases
1476
+ {
1477
+ result = new_when(val[2], val[4])
1478
+ result.line = val[1]
1479
+ result << val[5] if val[5]
1480
+ }
1481
+
1482
+ when_args: args
1483
+ | args tCOMMA tSTAR arg_value
1484
+ {
1485
+ result = self.list_append val[0], new_when(val[3], nil)
1486
+ }
1487
+ | tSTAR arg_value
1488
+ {
1489
+ result = s(:array, new_when(val[1], nil))
1490
+ }
1491
+
1492
+ cases: opt_else | case_body
1493
+
1494
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1495
+ {
1496
+ klasses, var, body, rest = val[1], val[2], val[4], val[5]
1497
+
1498
+ klasses ||= s(:array)
1499
+ klasses << node_assign(var, s(:gvar, :"$!")) if var
1500
+
1501
+ result = new_resbody(klasses, body)
1502
+ result << rest if rest # UGH, rewritten above
1503
+ }
1504
+ |
1505
+ {
1506
+ result = nil
1507
+ }
1508
+
1509
+ exc_list: arg_value
1510
+ {
1511
+ result = s(:array, val[0])
1512
+ }
1513
+ | mrhs
1514
+ | none
1515
+
1516
+ exc_var: tASSOC lhs
1517
+ {
1518
+ result = val[1]
1519
+ }
1520
+ | none
1521
+
1522
+ opt_ensure: kENSURE compstmt
1523
+ {
1524
+ if (val[1] != nil) then
1525
+ result = val[1]
1526
+ else
1527
+ result = s(:nil)
1528
+ end
1529
+ }
1530
+ | none
1531
+
1532
+ literal: numeric { result = s(:lit, val[0]) }
1533
+ | symbol { result = s(:lit, val[0]) }
1534
+ | dsym
1535
+
1536
+ strings: string
1537
+ {
1538
+ val[0] = s(:dstr, val[0].value) if val[0][0] == :evstr
1539
+ result = val[0]
1540
+ }
1541
+
1542
+ string: string1
1543
+ | string string1
1544
+ {
1545
+ result = self.literal_concat val[0], val[1]
1546
+ }
1547
+
1548
+ string1: tSTRING_BEG string_contents tSTRING_END
1549
+ {
1550
+ result = val[1]
1551
+ }
1552
+ | tSTRING
1553
+ {
1554
+ result = s(:str, val[0])
1555
+ }
1556
+
1557
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1558
+ {
1559
+ result = new_xstring val[1]
1560
+ }
1561
+
1562
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
1563
+ {
1564
+ result = new_regexp val
1565
+ }
1566
+
1567
+ words: tWORDS_BEG tSPACE tSTRING_END
1568
+ {
1569
+ result = s(:array)
1570
+ }
1571
+ | tWORDS_BEG word_list tSTRING_END
1572
+ {
1573
+ result = val[1]
1574
+ }
1575
+
1576
+ word_list: none
1577
+ {
1578
+ result = s(:array)
1579
+ }
1580
+ | word_list word tSPACE
1581
+ {
1582
+ word = val[1][0] == :evstr ? s(:dstr, "", val[1]) : val[1]
1583
+ result = val[0] << word
1584
+ }
1585
+
1586
+ word: string_content
1587
+ | word string_content
1588
+ {
1589
+ result = self.literal_concat val[0], val[1]
1590
+ }
1591
+
1592
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
1593
+ {
1594
+ result = s(:array)
1595
+ }
1596
+ | tQWORDS_BEG qword_list tSTRING_END
1597
+ {
1598
+ result = val[1]
1599
+ }
1600
+
1601
+ qword_list: none
1602
+ {
1603
+ result = s(:array)
1604
+ }
1605
+ | qword_list tSTRING_CONTENT tSPACE
1606
+ {
1607
+ result = val[0] << s(:str, val[1])
1608
+ }
1609
+
1610
+ string_contents: none
1611
+ {
1612
+ result = s(:str, "")
1613
+ }
1614
+ | string_contents string_content
1615
+ {
1616
+ result = literal_concat(val[0], val[1])
1617
+ }
1618
+
1619
+ xstring_contents: none
1620
+ {
1621
+ result = nil
1622
+ }
1623
+ | xstring_contents string_content
1624
+ {
1625
+ result = literal_concat(val[0], val[1])
1626
+ }
1627
+
1628
+ regexp_contents: none
1629
+ {
1630
+ result = nil
1631
+ }
1632
+ | regexp_contents string_content
1633
+ {
1634
+ result = literal_concat(val[0], val[1])
1635
+ }
1636
+
1637
+ string_content: tSTRING_CONTENT
1638
+ {
1639
+ result = s(:str, val[0])
1640
+ }
1641
+ | tSTRING_DVAR
1642
+ {
1643
+ result = lexer.lex_strterm
1644
+ lexer.lex_strterm = nil
1645
+ lexer.lex_state = :expr_beg
1646
+ }
1647
+ string_dvar
1648
+ {
1649
+ lexer.lex_strterm = val[1]
1650
+ result = s(:evstr, val[2])
1651
+ }
1652
+ | tSTRING_DBEG
1653
+ {
1654
+ result = lexer.lex_strterm
1655
+ lexer.lex_strterm = nil
1656
+ lexer.lex_state = :expr_beg
1657
+ lexer.cond.push false
1658
+ lexer.cmdarg.push false
1659
+ }
1660
+ compstmt tRCURLY
1661
+ {
1662
+ lexer.lex_strterm = val[1]
1663
+ lexer.cond.lexpop
1664
+ lexer.cmdarg.lexpop
1665
+
1666
+ case val[2]
1667
+ when Sexp then
1668
+ case val[2][0]
1669
+ when :str, :dstr, :evstr then
1670
+ result = val[2]
1671
+ else
1672
+ result = s(:evstr, val[2])
1673
+ end
1674
+ when nil then
1675
+ result = s(:evstr)
1676
+ else
1677
+ raise "unknown rescue body: #{val[2].inspect}"
1678
+ end
1679
+ }
1680
+
1681
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1682
+ | tIVAR { result = s(:ivar, val[0].to_sym) }
1683
+ | tCVAR { result = s(:cvar, val[0].to_sym) }
1684
+ | backref
1685
+
1686
+
1687
+ symbol: tSYMBEG sym
1688
+ {
1689
+ lexer.lex_state = :expr_end
1690
+ result = val[1].to_sym
1691
+ }
1692
+ | tSYMBOL
1693
+ {
1694
+ result = val[0].to_sym
1695
+ }
1696
+
1697
+ sym: fname | tIVAR | tGVAR | tCVAR
1698
+
1699
+ dsym: tSYMBEG xstring_contents tSTRING_END
1700
+ {
1701
+ lexer.lex_state = :expr_end
1702
+ result = val[1]
1703
+
1704
+ yyerror "empty symbol literal" if
1705
+ result.nil? or result.empty?
1706
+
1707
+ case result[0]
1708
+ when :dstr then
1709
+ result[0] = :dsym
1710
+ when :str then
1711
+ result = s(:lit, result.last.intern)
1712
+ else
1713
+ result = s(:dsym, "", result)
1714
+ end
1715
+ }
1716
+
1717
+ numeric: tINTEGER
1718
+ | tFLOAT
1719
+ | tUMINUS_NUM tINTEGER =tLOWEST
1720
+ {
1721
+ result = -val[1] # TODO: pt_testcase
1722
+ }
1723
+ | tUMINUS_NUM tFLOAT =tLOWEST
1724
+ {
1725
+ result = -val[1] # TODO: pt_testcase
1726
+ }
1727
+
1728
+ user_variable: tIDENTIFIER
1729
+ | tIVAR
1730
+ | tGVAR
1731
+ | tCONSTANT
1732
+ | tCVAR
1733
+
1734
+ keyword_variable: kNIL { result = s(:nil) }
1735
+ | kSELF { result = s(:self) }
1736
+ | kTRUE { result = s(:true) }
1737
+ | kFALSE { result = s(:false) }
1738
+ | k__FILE__ { result = s(:str, self.file) }
1739
+ | k__LINE__ { result = s(:lit, lexer.src.current_line) }
1740
+
1741
+ var_ref: user_variable
1742
+ {
1743
+ var = val[0]
1744
+ result = Sexp === var ? var : self.gettable(var)
1745
+ }
1746
+ | keyword_variable
1747
+ {
1748
+ var = val[0]
1749
+ result = Sexp === var ? var : self.gettable(var)
1750
+ }
1751
+
1752
+ var_lhs: user_variable
1753
+ {
1754
+ result = self.assignable val[0]
1755
+ }
1756
+ | keyword_variable
1757
+ {
1758
+ result = self.assignable val[0]
1759
+ }
1760
+
1761
+ backref: tNTH_REF { result = s(:nth_ref, val[0]) }
1762
+ | tBACK_REF { result = s(:back_ref, val[0]) }
1763
+
1764
+ superclass: term
1765
+ {
1766
+ result = nil
1767
+ }
1768
+ | tLT
1769
+ {
1770
+ lexer.lex_state = :expr_beg
1771
+ }
1772
+ expr_value term
1773
+ {
1774
+ result = val[2]
1775
+ }
1776
+ | error term
1777
+ {
1778
+ yyerrok
1779
+ result = nil
1780
+ }
1781
+
1782
+ f_arglist: tLPAREN2 f_args rparen
1783
+ {
1784
+ result = val[1]
1785
+ lexer.lex_state = :expr_beg
1786
+ self.lexer.command_start = true
1787
+ }
1788
+ | f_args term
1789
+ {
1790
+ result = val[0]
1791
+ }
1792
+
1793
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
1794
+ {
1795
+ result = args19 val
1796
+ }
1797
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1798
+ {
1799
+ result = args19 val
1800
+ }
1801
+ | f_arg tCOMMA f_optarg opt_f_block_arg
1802
+ {
1803
+ result = args19 val
1804
+ }
1805
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg
1806
+ {
1807
+ result = args19 val
1808
+ }
1809
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
1810
+ {
1811
+ result = args19 val
1812
+ }
1813
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1814
+ {
1815
+ result = args19 val
1816
+ }
1817
+ | f_arg opt_f_block_arg
1818
+ {
1819
+ result = args19 val
1820
+ }
1821
+ | f_optarg tCOMMA f_rest_arg opt_f_block_arg
1822
+ {
1823
+ result = args19 val
1824
+ }
1825
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1826
+ {
1827
+ result = args19 val
1828
+ }
1829
+ | f_optarg opt_f_block_arg
1830
+ {
1831
+ result = args19 val
1832
+ }
1833
+ | f_optarg tCOMMA f_arg opt_f_block_arg
1834
+ {
1835
+ result = args19 val
1836
+ }
1837
+ | f_rest_arg opt_f_block_arg
1838
+ {
1839
+ result = args19 val
1840
+ }
1841
+ | f_rest_arg tCOMMA f_arg opt_f_block_arg
1842
+ {
1843
+ result = args19 val
1844
+ }
1845
+ | f_block_arg
1846
+ {
1847
+ result = args19 val
1848
+ }
1849
+ |
1850
+ {
1851
+ result = args19 val
1852
+ }
1853
+
1854
+ f_bad_arg: tCONSTANT
1855
+ {
1856
+ yyerror "formal argument cannot be a constant"
1857
+ }
1858
+ | tIVAR
1859
+ {
1860
+ yyerror "formal argument cannot be an instance variable"
1861
+ }
1862
+ | tGVAR
1863
+ {
1864
+ yyerror "formal argument cannot be a global variable"
1865
+ }
1866
+ | tCVAR
1867
+ {
1868
+ yyerror "formal argument cannot be a class variable"
1869
+ }
1870
+
1871
+ f_norm_arg: f_bad_arg
1872
+ | tIDENTIFIER
1873
+ {
1874
+ identifier = val[0].to_sym
1875
+ self.env[identifier] = :lvar
1876
+
1877
+ result = val[0]
1878
+ }
1879
+
1880
+ f_arg: f_norm_arg
1881
+ {
1882
+ result = s(:args)
1883
+ result << val[0].to_sym
1884
+ }
1885
+ | f_arg tCOMMA f_norm_arg
1886
+ {
1887
+ val[0] << val[2].to_sym
1888
+ result = val[0]
1889
+ }
1890
+
1891
+ f_opt: tIDENTIFIER tEQL arg_value
1892
+ {
1893
+ result = self.assignable val[0], val[2]
1894
+ # TODO: detect duplicate names
1895
+ }
1896
+
1897
+ f_optarg: f_opt
1898
+ {
1899
+ result = s(:block, val[0])
1900
+ }
1901
+ | f_optarg tCOMMA f_opt
1902
+ {
1903
+ result = self.block_append val[0], val[2]
1904
+ }
1905
+
1906
+ restarg_mark: tSTAR2 | tSTAR
1907
+
1908
+ f_rest_arg: restarg_mark tIDENTIFIER
1909
+ {
1910
+ # TODO: differs from parse.y - needs tests
1911
+ name = val[1].to_sym
1912
+ self.assignable name
1913
+ result = :"*#{name}"
1914
+ }
1915
+ | restarg_mark
1916
+ {
1917
+ name = :"*"
1918
+ self.env[name] = :lvar
1919
+ result = name
1920
+ }
1921
+
1922
+ blkarg_mark: tAMPER2 | tAMPER
1923
+
1924
+ f_block_arg: blkarg_mark tIDENTIFIER
1925
+ {
1926
+ identifier = val[1].to_sym
1927
+
1928
+ self.env[identifier] = :lvar
1929
+ result = s(:block_arg, identifier.to_sym)
1930
+ }
1931
+
1932
+ opt_f_block_arg: tCOMMA f_block_arg
1933
+ {
1934
+ result = val[1]
1935
+ }
1936
+ |
1937
+ {
1938
+ result = nil
1939
+ }
1940
+
1941
+ singleton: var_ref
1942
+ | tLPAREN2
1943
+ {
1944
+ lexer.lex_state = :expr_beg
1945
+ }
1946
+ expr rparen
1947
+ {
1948
+ result = val[2]
1949
+ yyerror "Can't define single method for literals." if
1950
+ result[0] == :lit
1951
+ }
1952
+
1953
+ assoc_list: none # [!nil]
1954
+ {
1955
+ result = s(:array)
1956
+ }
1957
+ | assocs trailer # [!nil]
1958
+ {
1959
+ result = val[0]
1960
+ }
1961
+ | args trailer
1962
+ {
1963
+ size = val[0].size
1964
+ if (size % 2 != 1) then # != 1 because of leading :array
1965
+ yyerror "Odd number (#{size}) list for Hash. #{val[0].inspect}"
1966
+ end
1967
+ result = val[0]
1968
+ }
1969
+
1970
+ assocs: assoc
1971
+ | assocs tCOMMA assoc
1972
+ {
1973
+ list = val[0].dup
1974
+ more = val[2][1..-1]
1975
+ list.push(*more) unless more.empty?
1976
+ result = list
1977
+ }
1978
+
1979
+ assoc: arg_value tASSOC arg_value
1980
+ {
1981
+ result = s(:array, val[0], val[2])
1982
+ }
1983
+ | tLABEL arg_value
1984
+ {
1985
+ result = s(:array, s(:lit, val[0][0].to_sym), val[1])
1986
+ }
1987
+
1988
+ operation: tIDENTIFIER | tCONSTANT | tFID
1989
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
1990
+ operation3: tIDENTIFIER | tFID | op
1991
+ dot_or_colon: tDOT | tCOLON2
1992
+ opt_terms: | terms
1993
+ opt_nl: | tNL
1994
+ rparen: opt_nl tRPAREN
1995
+ rbracket: opt_nl tRBRACK
1996
+ trailer: | tNL | tCOMMA
1997
+
1998
+ term: tSEMI { yyerrok }
1999
+ | tNL
2000
+
2001
+ terms: term
2002
+ | terms tSEMI { yyerrok }
2003
+
2004
+ none: { result = nil }
2005
+ end
2006
+
2007
+ ---- inner
2008
+
2009
+ require "ruby_lexer"
2010
+ require "ruby_parser_extras"
2011
+
2012
+ # Local Variables: **
2013
+ # racc-token-length-max:14 **
2014
+ # End: **