parser 0.9.alpha

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