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