ruby_parser 3.7.3 → 3.8.0

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