ruby_parser 3.8.4 → 3.9.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,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: **