ruby_parser 3.8.4 → 3.9.0

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