parser 0.9.alpha

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