ruby_parser 3.7.3 → 3.8.0

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