ruby_parser 2.3.1 → 3.0.0.a1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

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: **