parser 0.9.alpha

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