ruby_parser 3.6.6 → 3.7.0

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