ruby_parser 3.10.1 → 3.11.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,2378 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby25Parser
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.sexp_type = :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.sexp_type = :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].sexp_body # REFACTOR pattern
291
+ }
292
+ | fcall command_args cmd_brace_block
293
+ {
294
+ result = val[0].concat val[1].sexp_body
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.sexp_body
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].sexp_body
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].sexp_body
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].sexp_body))
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].sexp_type = :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
960
+ {
961
+ result = self.lexer.cmdarg.stack.dup
962
+ lexer.cmdarg.stack.replace [false] # TODO add api for these
963
+ }
964
+ expr
965
+ {
966
+ lexer.lex_state = :expr_endarg
967
+ }
968
+ rparen
969
+ {
970
+ warning "(...) interpreted as grouped expression"
971
+ lexer.cmdarg.stack.replace val[1]
972
+ result = val[2]
973
+ }
974
+ | tLPAREN compstmt tRPAREN
975
+ {
976
+ result = val[1] || s(:nil)
977
+ result.paren = true
978
+ }
979
+ | primary_value tCOLON2 tCONSTANT
980
+ {
981
+ result = s(:colon2, val[0], val[2].to_sym)
982
+ }
983
+ | tCOLON3 tCONSTANT
984
+ {
985
+ result = s(:colon3, val[1].to_sym)
986
+ }
987
+ | tLBRACK aref_args tRBRACK
988
+ {
989
+ result = val[1] || s(:array)
990
+ result.sexp_type = :array # aref_args is :args
991
+ }
992
+ | tLBRACE
993
+ {
994
+ result = self.lexer.lineno
995
+ }
996
+ assoc_list tRCURLY
997
+ {
998
+ result = new_hash val
999
+ }
1000
+ | kRETURN
1001
+ {
1002
+ result = s(:return)
1003
+ }
1004
+ | kYIELD tLPAREN2 call_args rparen
1005
+ {
1006
+ result = new_yield val[2]
1007
+ }
1008
+ | kYIELD tLPAREN2 rparen
1009
+ {
1010
+ result = new_yield
1011
+ }
1012
+ | kYIELD
1013
+ {
1014
+ result = new_yield
1015
+ }
1016
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1017
+ {
1018
+ result = s(:defined, val[3])
1019
+ }
1020
+ | kNOT tLPAREN2 expr rparen
1021
+ {
1022
+ result = s(:call, val[2], :"!")
1023
+ }
1024
+ | kNOT tLPAREN2 rparen
1025
+ {
1026
+ debug20 14, val, result
1027
+ }
1028
+ | fcall brace_block
1029
+ {
1030
+ oper, iter = val[0], val[1]
1031
+ call = oper # FIX
1032
+ iter.insert 1, call
1033
+ result = iter
1034
+ call.line = iter.line
1035
+ }
1036
+ | method_call
1037
+ | method_call brace_block
1038
+ {
1039
+ call, iter = val[0], val[1]
1040
+ block_dup_check call, iter
1041
+ iter.insert 1, call # FIX
1042
+ result = iter
1043
+ }
1044
+ | tLAMBDA lambda
1045
+ {
1046
+ result = val[1] # TODO: fix lineno
1047
+ }
1048
+ | kIF expr_value then compstmt if_tail kEND
1049
+ {
1050
+ result = new_if val[1], val[3], val[4]
1051
+ }
1052
+ | kUNLESS expr_value then compstmt opt_else kEND
1053
+ {
1054
+ result = new_if val[1], val[4], val[3]
1055
+ }
1056
+ | kWHILE
1057
+ {
1058
+ lexer.cond.push true
1059
+ }
1060
+ expr_value do
1061
+ {
1062
+ lexer.cond.pop
1063
+ }
1064
+ compstmt kEND
1065
+ {
1066
+ result = new_while val[5], val[2], true
1067
+ }
1068
+ | kUNTIL
1069
+ {
1070
+ lexer.cond.push true
1071
+ }
1072
+ expr_value do
1073
+ {
1074
+ lexer.cond.pop
1075
+ }
1076
+ compstmt kEND
1077
+ {
1078
+ result = new_until val[5], val[2], true
1079
+ }
1080
+ | kCASE expr_value opt_terms case_body kEND
1081
+ {
1082
+ (_, line), expr, _, body, _ = val
1083
+ result = new_case expr, body, line
1084
+ }
1085
+ | kCASE opt_terms case_body kEND
1086
+ {
1087
+ (_, line), _, body, _ = val
1088
+ result = new_case nil, body, line
1089
+ }
1090
+ | kFOR for_var kIN
1091
+ {
1092
+ lexer.cond.push true
1093
+ }
1094
+ expr_value do
1095
+ {
1096
+ lexer.cond.pop
1097
+ }
1098
+ compstmt kEND
1099
+ {
1100
+ result = new_for val[4], val[1], val[7]
1101
+ }
1102
+ | kCLASS
1103
+ {
1104
+ result = self.lexer.lineno
1105
+ }
1106
+ cpath superclass
1107
+ {
1108
+ self.comments.push self.lexer.comments
1109
+ if (self.in_def || self.in_single > 0) then
1110
+ yyerror "class definition in method body"
1111
+ end
1112
+ self.env.extend
1113
+ }
1114
+ bodystmt kEND
1115
+ {
1116
+ result = new_class val
1117
+ self.env.unextend
1118
+ self.lexer.comments # we don't care about comments in the body
1119
+ }
1120
+ | kCLASS tLSHFT
1121
+ {
1122
+ result = self.lexer.lineno
1123
+ }
1124
+ expr
1125
+ {
1126
+ result = self.in_def
1127
+ self.in_def = false
1128
+ }
1129
+ term
1130
+ {
1131
+ result = self.in_single
1132
+ self.in_single = 0
1133
+ self.env.extend
1134
+ }
1135
+ bodystmt kEND
1136
+ {
1137
+ result = new_sclass val
1138
+ self.env.unextend
1139
+ self.lexer.comments # we don't care about comments in the body
1140
+ }
1141
+ | kMODULE
1142
+ {
1143
+ result = self.lexer.lineno
1144
+ }
1145
+ cpath
1146
+ {
1147
+ self.comments.push self.lexer.comments
1148
+ yyerror "module definition in method body" if
1149
+ self.in_def or self.in_single > 0
1150
+
1151
+ self.env.extend
1152
+ }
1153
+ bodystmt kEND
1154
+ {
1155
+ result = new_module val
1156
+ self.env.unextend
1157
+ self.lexer.comments # we don't care about comments in the body
1158
+ }
1159
+ | kDEF fname
1160
+ {
1161
+ result = [self.in_def, self.lexer.cmdarg.stack.dup]
1162
+
1163
+ self.comments.push self.lexer.comments
1164
+ self.in_def = true
1165
+ self.env.extend
1166
+ # TODO: local->cmdargs = cmdarg_stack;
1167
+ # TODO: port local_push_gen and local_pop_gen
1168
+ lexer.cmdarg.stack.replace [false]
1169
+ }
1170
+ f_arglist bodystmt kEND
1171
+ {
1172
+ in_def, cmdarg = val[2]
1173
+
1174
+ result = new_defn val
1175
+
1176
+ lexer.cmdarg.stack.replace cmdarg
1177
+ self.env.unextend
1178
+ self.in_def = in_def
1179
+ self.lexer.comments # we don't care about comments in the body
1180
+ }
1181
+ | kDEF singleton dot_or_colon
1182
+ {
1183
+ self.comments.push self.lexer.comments
1184
+ lexer.lex_state = :expr_fname
1185
+ }
1186
+ fname
1187
+ {
1188
+ self.in_single += 1
1189
+ self.env.extend
1190
+ lexer.lex_state = :expr_endfn # force for args
1191
+ result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1192
+ lexer.cmdarg.stack.replace [false]
1193
+ }
1194
+ f_arglist bodystmt kEND
1195
+ {
1196
+ line, cmdarg = val[5]
1197
+ result = new_defs val
1198
+ result[3].line line
1199
+
1200
+ lexer.cmdarg.stack.replace cmdarg
1201
+
1202
+ self.env.unextend
1203
+ self.in_single -= 1
1204
+ self.lexer.comments # we don't care about comments in the body
1205
+ }
1206
+ | kBREAK
1207
+ {
1208
+ result = s(:break)
1209
+ }
1210
+ | kNEXT
1211
+ {
1212
+ result = s(:next)
1213
+ }
1214
+ | kREDO
1215
+ {
1216
+ result = s(:redo)
1217
+ }
1218
+ | kRETRY
1219
+ {
1220
+ result = s(:retry)
1221
+ }
1222
+
1223
+ primary_value: primary
1224
+ {
1225
+ result = value_expr(val[0])
1226
+ }
1227
+
1228
+ # These are really stupid
1229
+ k_begin: kBEGIN
1230
+ k_if: kIF
1231
+ k_unless: kUNLESS
1232
+ k_while: kWHILE
1233
+ k_until: kUNTIL
1234
+ k_case: kCASE
1235
+ k_for: kFOR
1236
+ k_class: kCLASS
1237
+ k_module: kMODULE
1238
+ k_def: kDEF
1239
+ k_end: kEND
1240
+
1241
+ then: term
1242
+ | kTHEN
1243
+ | term kTHEN
1244
+
1245
+ do: term
1246
+ | kDO_COND
1247
+
1248
+ if_tail: opt_else
1249
+ | kELSIF expr_value then compstmt if_tail
1250
+ {
1251
+ result = s(:if, val[1], val[3], val[4])
1252
+ }
1253
+
1254
+ opt_else: none
1255
+ | kELSE compstmt
1256
+ {
1257
+ result = val[1]
1258
+ }
1259
+
1260
+ for_var: lhs
1261
+ | mlhs
1262
+ {
1263
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1264
+ }
1265
+
1266
+ f_marg: f_norm_arg
1267
+ | tLPAREN f_margs rparen
1268
+ {
1269
+ result = val[1]
1270
+ }
1271
+
1272
+ f_marg_list: f_marg
1273
+ {
1274
+ result = s(:array, val[0])
1275
+ }
1276
+ | f_marg_list tCOMMA f_marg
1277
+ {
1278
+ result = list_append val[0], val[2]
1279
+ }
1280
+
1281
+ f_margs: f_marg_list
1282
+ {
1283
+ args, = val
1284
+
1285
+ result = block_var args
1286
+ }
1287
+ | f_marg_list tCOMMA tSTAR f_norm_arg
1288
+ {
1289
+ args, _, _, splat = val
1290
+
1291
+ result = block_var args, "*#{splat}".to_sym
1292
+ }
1293
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1294
+ {
1295
+ args, _, _, splat, _, args2 = val
1296
+
1297
+ result = block_var args, "*#{splat}".to_sym, args2
1298
+ }
1299
+ | f_marg_list tCOMMA tSTAR
1300
+ {
1301
+ args, _, _ = val
1302
+
1303
+ result = block_var args, :*
1304
+ }
1305
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1306
+ {
1307
+ args, _, _, _, args2 = val
1308
+
1309
+ result = block_var args, :*, args2
1310
+ }
1311
+ | tSTAR f_norm_arg
1312
+ {
1313
+ _, splat = val
1314
+
1315
+ result = block_var :"*#{splat}"
1316
+ }
1317
+ | tSTAR f_norm_arg tCOMMA f_marg_list
1318
+ {
1319
+ _, splat, _, args = val
1320
+
1321
+ result = block_var :"*#{splat}", args
1322
+ }
1323
+ | tSTAR
1324
+ {
1325
+ result = block_var :*
1326
+ }
1327
+ | tSTAR tCOMMA f_marg_list
1328
+ {
1329
+ _, _, args = val
1330
+
1331
+ result = block_var :*, args
1332
+ }
1333
+
1334
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1335
+ {
1336
+ result = call_args val
1337
+ }
1338
+ | f_block_kwarg opt_f_block_arg
1339
+ {
1340
+ result = call_args val
1341
+ }
1342
+ | f_kwrest opt_f_block_arg
1343
+ {
1344
+ result = call_args val
1345
+ }
1346
+ | f_block_arg
1347
+ {
1348
+ result = call_args val
1349
+ }
1350
+
1351
+ opt_block_args_tail: tCOMMA block_args_tail
1352
+ {
1353
+ result = args val
1354
+ }
1355
+ | none
1356
+
1357
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1358
+ {
1359
+ result = args val
1360
+ }
1361
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1362
+ {
1363
+ result = args val
1364
+ }
1365
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1366
+ {
1367
+ result = args val
1368
+ }
1369
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1370
+ {
1371
+ result = args val
1372
+ }
1373
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1374
+ {
1375
+ result = args val
1376
+ }
1377
+ | f_arg tCOMMA
1378
+ {
1379
+ result = args val
1380
+ }
1381
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1382
+ {
1383
+ result = args val
1384
+ }
1385
+ | f_arg opt_block_args_tail
1386
+ {
1387
+ result = args val
1388
+ }
1389
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1390
+ {
1391
+ result = args val
1392
+ }
1393
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1394
+ {
1395
+ result = args val
1396
+ }
1397
+ | f_block_optarg opt_block_args_tail
1398
+ {
1399
+ result = args val
1400
+ }
1401
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1402
+ {
1403
+ result = args val
1404
+ }
1405
+ | f_rest_arg opt_block_args_tail
1406
+ {
1407
+ result = args val
1408
+ }
1409
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1410
+ {
1411
+ result = args val
1412
+ }
1413
+ | block_args_tail
1414
+ {
1415
+ result = args val
1416
+ }
1417
+
1418
+ opt_block_param: none { result = 0 }
1419
+ | block_param_def
1420
+
1421
+ block_param_def: tPIPE opt_bv_decl tPIPE
1422
+ {
1423
+ result = args val
1424
+ }
1425
+ | tOROP
1426
+ {
1427
+ self.lexer.command_start = true
1428
+ result = s(:args)
1429
+ }
1430
+ | tPIPE block_param opt_bv_decl tPIPE
1431
+ {
1432
+ result = args val
1433
+ }
1434
+
1435
+ opt_bv_decl: opt_nl
1436
+ | opt_nl tSEMI bv_decls opt_nl
1437
+ {
1438
+ result = args val
1439
+ }
1440
+
1441
+ bv_decls: bvar
1442
+ {
1443
+ result = args val
1444
+ }
1445
+ | bv_decls tCOMMA bvar
1446
+ {
1447
+ result = args val
1448
+ }
1449
+
1450
+ bvar: tIDENTIFIER
1451
+ {
1452
+ result = s(:shadow, val[0].to_sym)
1453
+ }
1454
+ | f_bad_arg
1455
+
1456
+ lambda: {
1457
+ self.env.extend :dynamic
1458
+ result = self.lexer.lineno
1459
+
1460
+ result = lexer.lpar_beg
1461
+ lexer.paren_nest += 1
1462
+ lexer.lpar_beg = lexer.paren_nest
1463
+ }
1464
+ f_larglist lambda_body
1465
+ {
1466
+ lpar, args, body = val
1467
+ lexer.lpar_beg = lpar
1468
+
1469
+ call = new_call nil, :lambda
1470
+ result = new_iter call, args, body
1471
+ self.env.unextend
1472
+ }
1473
+
1474
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1475
+ {
1476
+ result = args val
1477
+ }
1478
+ | f_args
1479
+ {
1480
+ result = val[0]
1481
+ result = 0 if result == s(:args)
1482
+ }
1483
+
1484
+ lambda_body: tLAMBEG compstmt tRCURLY
1485
+ {
1486
+ result = val[1]
1487
+ }
1488
+ | kDO_LAMBDA compstmt kEND
1489
+ {
1490
+ result = val[1]
1491
+ }
1492
+
1493
+ do_block: kDO_BLOCK
1494
+ {
1495
+ self.env.extend :dynamic
1496
+ result = self.lexer.lineno
1497
+ }
1498
+ opt_block_param
1499
+ {
1500
+ result = nil # self.env.dynamic.keys
1501
+ }
1502
+ compstmt kEND
1503
+ {
1504
+ args = val[2]
1505
+ body = val[4]
1506
+ result = new_iter nil, args, body
1507
+ result.line = val[1]
1508
+
1509
+ self.env.unextend
1510
+ }
1511
+
1512
+ block_call: command do_block
1513
+ {
1514
+ # TODO:
1515
+ ## if (nd_type($1) == NODE_YIELD) {
1516
+ ## compile_error(PARSER_ARG "block given to yield");
1517
+
1518
+ syntax_error "Both block arg and actual block given." if
1519
+ val[0].block_pass?
1520
+
1521
+ val = invert_block_call val if inverted? val
1522
+
1523
+ result = val[1]
1524
+ result.insert 1, val[0]
1525
+ }
1526
+ | block_call dot_or_colon operation2 opt_paren_args
1527
+ {
1528
+ result = new_call val[0], val[2].to_sym, val[3]
1529
+ }
1530
+ | block_call dot_or_colon operation2 opt_paren_args brace_block
1531
+ {
1532
+ iter1, _, name, args, iter2 = val
1533
+
1534
+ call = new_call iter1, name.to_sym, args
1535
+ iter2.insert 1, call
1536
+
1537
+ result = iter2
1538
+ }
1539
+ | block_call dot_or_colon operation2 command_args do_block
1540
+ {
1541
+ iter1, _, name, args, iter2 = val
1542
+
1543
+ call = new_call iter1, name.to_sym, args
1544
+ iter2.insert 1, call
1545
+
1546
+ result = iter2
1547
+ }
1548
+
1549
+ method_call: fcall
1550
+ {
1551
+ result = self.lexer.lineno
1552
+ }
1553
+ paren_args
1554
+ {
1555
+ args = self.call_args val[2..-1]
1556
+ result = val[0].concat args.sexp_body
1557
+ }
1558
+ | primary_value call_op operation2 opt_paren_args
1559
+ {
1560
+ result = new_call val[0], val[2].to_sym, val[3], val[1]
1561
+ }
1562
+ | primary_value tCOLON2 operation2 paren_args
1563
+ {
1564
+ result = new_call val[0], val[2].to_sym, val[3]
1565
+ }
1566
+ | primary_value tCOLON2 operation3
1567
+ {
1568
+ result = new_call val[0], val[2].to_sym
1569
+ }
1570
+ | primary_value call_op paren_args
1571
+ {
1572
+ result = new_call val[0], :call, val[2], val[1]
1573
+ }
1574
+ | primary_value tCOLON2 paren_args
1575
+ {
1576
+ result = new_call val[0], :call, val[2]
1577
+ }
1578
+ | kSUPER paren_args
1579
+ {
1580
+ result = new_super val[1]
1581
+ }
1582
+ | kSUPER
1583
+ {
1584
+ result = s(:zsuper)
1585
+ }
1586
+ | primary_value tLBRACK2 opt_call_args rbracket
1587
+ {
1588
+ result = new_aref val
1589
+ }
1590
+
1591
+ brace_block: tLCURLY
1592
+ {
1593
+ self.env.extend :dynamic
1594
+ result = self.lexer.lineno
1595
+ }
1596
+ opt_block_param
1597
+ {
1598
+ result = nil # self.env.dynamic.keys
1599
+ }
1600
+ compstmt tRCURLY
1601
+ {
1602
+ _, line, args, _, body, _ = val
1603
+
1604
+ result = new_iter nil, args, body
1605
+ result.line = line
1606
+
1607
+ self.env.unextend
1608
+ }
1609
+ | kDO
1610
+ {
1611
+ self.env.extend :dynamic
1612
+ result = self.lexer.lineno
1613
+ }
1614
+ opt_block_param
1615
+ {
1616
+ result = nil # self.env.dynamic.keys
1617
+ }
1618
+ compstmt kEND
1619
+ {
1620
+ _, line, args, _, body, _ = val
1621
+
1622
+ result = new_iter nil, args, body
1623
+ result.line = line
1624
+
1625
+ self.env.unextend
1626
+ }
1627
+
1628
+ case_body: kWHEN
1629
+ {
1630
+ result = self.lexer.lineno
1631
+ }
1632
+ args then compstmt cases
1633
+ {
1634
+ result = new_when(val[2], val[4])
1635
+ result.line = val[1]
1636
+ result << val[5] if val[5]
1637
+ }
1638
+
1639
+ cases: opt_else | case_body
1640
+
1641
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1642
+ {
1643
+ (_, line), klasses, var, _, body, rest = val
1644
+
1645
+ klasses ||= s(:array)
1646
+ klasses << new_assign(var, s(:gvar, :"$!")) if var
1647
+ klasses.line line
1648
+
1649
+ result = new_resbody(klasses, body)
1650
+ result << rest if rest # UGH, rewritten above
1651
+ }
1652
+ |
1653
+ {
1654
+ result = nil
1655
+ }
1656
+
1657
+ exc_list: arg_value
1658
+ {
1659
+ result = s(:array, val[0])
1660
+ }
1661
+ | mrhs
1662
+ | none
1663
+
1664
+ exc_var: tASSOC lhs
1665
+ {
1666
+ result = val[1]
1667
+ }
1668
+ | none
1669
+
1670
+ opt_ensure: kENSURE compstmt
1671
+ {
1672
+ _, body = val
1673
+
1674
+ result = body || s(:nil)
1675
+ }
1676
+ | none
1677
+
1678
+ literal: numeric
1679
+ {
1680
+ result = s(:lit, val[0])
1681
+ }
1682
+ | symbol
1683
+ {
1684
+ result = s(:lit, val[0])
1685
+ }
1686
+ | dsym
1687
+
1688
+ strings: string
1689
+ {
1690
+ val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1691
+ result = val[0]
1692
+ }
1693
+
1694
+ string: tCHAR
1695
+ {
1696
+ debug20 23, val, result
1697
+ }
1698
+ | string1
1699
+ | string string1
1700
+ {
1701
+ result = self.literal_concat val[0], val[1]
1702
+ }
1703
+
1704
+ string1: tSTRING_BEG string_contents tSTRING_END
1705
+ {
1706
+ result = val[1]
1707
+ }
1708
+ | tSTRING
1709
+ {
1710
+ result = new_string val
1711
+ }
1712
+
1713
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1714
+ {
1715
+ result = new_xstring val[1]
1716
+ }
1717
+
1718
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
1719
+ {
1720
+ result = new_regexp val
1721
+ }
1722
+
1723
+ words: tWORDS_BEG tSPACE tSTRING_END
1724
+ {
1725
+ result = s(:array)
1726
+ }
1727
+ | tWORDS_BEG word_list tSTRING_END
1728
+ {
1729
+ result = val[1]
1730
+ }
1731
+
1732
+ word_list: none
1733
+ {
1734
+ result = new_word_list
1735
+ }
1736
+ | word_list word tSPACE
1737
+ {
1738
+ result = val[0].dup << new_word_list_entry(val)
1739
+ }
1740
+
1741
+ word: string_content
1742
+ | word string_content
1743
+ {
1744
+ result = self.literal_concat val[0], val[1]
1745
+ }
1746
+
1747
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1748
+ {
1749
+ result = s(:array)
1750
+ }
1751
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1752
+ {
1753
+ result = val[1]
1754
+ }
1755
+
1756
+ symbol_list: none
1757
+ {
1758
+ result = new_symbol_list
1759
+ }
1760
+ | symbol_list word tSPACE
1761
+ {
1762
+ result = val[0].dup << new_symbol_list_entry(val)
1763
+ }
1764
+
1765
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
1766
+ {
1767
+ result = s(:array)
1768
+ }
1769
+ | tQWORDS_BEG qword_list tSTRING_END
1770
+ {
1771
+ result = val[1]
1772
+ }
1773
+
1774
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1775
+ {
1776
+ result = s(:array)
1777
+ }
1778
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
1779
+ {
1780
+ result = val[1]
1781
+ }
1782
+
1783
+ qword_list: none
1784
+ {
1785
+ result = new_qword_list
1786
+ }
1787
+ | qword_list tSTRING_CONTENT tSPACE
1788
+ {
1789
+ result = val[0].dup << new_qword_list_entry(val)
1790
+ }
1791
+
1792
+ qsym_list: none
1793
+ {
1794
+ result = new_qsym_list
1795
+ }
1796
+ | qsym_list tSTRING_CONTENT tSPACE
1797
+ {
1798
+ result = val[0].dup << new_qsym_list_entry(val)
1799
+ }
1800
+
1801
+ string_contents: none
1802
+ {
1803
+ result = s(:str, "")
1804
+ }
1805
+ | string_contents string_content
1806
+ {
1807
+ result = literal_concat(val[0], val[1])
1808
+ }
1809
+
1810
+ xstring_contents: none
1811
+ {
1812
+ result = nil
1813
+ }
1814
+ | xstring_contents string_content
1815
+ {
1816
+ result = literal_concat(val[0], val[1])
1817
+ }
1818
+
1819
+ regexp_contents: none
1820
+ {
1821
+ result = nil
1822
+ }
1823
+ | regexp_contents string_content
1824
+ {
1825
+ result = literal_concat(val[0], val[1])
1826
+ }
1827
+
1828
+ string_content: tSTRING_CONTENT
1829
+ {
1830
+ result = new_string val
1831
+ }
1832
+ | tSTRING_DVAR
1833
+ {
1834
+ result = lexer.lex_strterm
1835
+
1836
+ lexer.lex_strterm = nil
1837
+ lexer.lex_state = :expr_beg # TODO: expr_value ?
1838
+ }
1839
+ string_dvar
1840
+ {
1841
+ lexer.lex_strterm = val[1]
1842
+ result = s(:evstr, val[2])
1843
+ }
1844
+ | tSTRING_DBEG
1845
+ {
1846
+ result = [lexer.lex_strterm,
1847
+ lexer.brace_nest,
1848
+ lexer.string_nest, # TODO: remove
1849
+ lexer.cond.store,
1850
+ lexer.cmdarg.store,
1851
+ lexer.lex_state,
1852
+ ]
1853
+
1854
+ lexer.lex_strterm = nil
1855
+ lexer.brace_nest = 0
1856
+ lexer.string_nest = 0
1857
+
1858
+ lexer.lex_state = :expr_value
1859
+ }
1860
+ compstmt tRCURLY
1861
+ {
1862
+ # TODO: tRCURLY -> tSTRING_END
1863
+ _, memo, stmt, _ = val
1864
+
1865
+ lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
1866
+
1867
+ lexer.lex_strterm = lex_strterm
1868
+ lexer.brace_nest = brace_nest
1869
+ lexer.string_nest = string_nest
1870
+
1871
+ lexer.cond.restore oldcond
1872
+ lexer.cmdarg.restore oldcmdarg
1873
+
1874
+ lexer.lex_state = oldlex_state
1875
+
1876
+ case stmt
1877
+ when Sexp then
1878
+ case stmt.sexp_type
1879
+ when :str, :dstr, :evstr then
1880
+ result = stmt
1881
+ else
1882
+ result = s(:evstr, stmt)
1883
+ end
1884
+ when nil then
1885
+ result = s(:evstr)
1886
+ else
1887
+ debug20 25
1888
+ raise "unknown string body: #{stmt.inspect}"
1889
+ end
1890
+ }
1891
+
1892
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1893
+ | tIVAR { result = s(:ivar, val[0].to_sym) }
1894
+ | tCVAR { result = s(:cvar, val[0].to_sym) }
1895
+ | backref
1896
+
1897
+ symbol: tSYMBEG sym
1898
+ {
1899
+ lexer.lex_state = :expr_end
1900
+ result = val[1].to_sym
1901
+ }
1902
+ | tSYMBOL
1903
+ {
1904
+ result = val[0].to_sym
1905
+ }
1906
+
1907
+ sym: fname | tIVAR | tGVAR | tCVAR
1908
+
1909
+ dsym: tSYMBEG xstring_contents tSTRING_END
1910
+ {
1911
+ lexer.lex_state = :expr_end
1912
+ result = val[1]
1913
+
1914
+ result ||= s(:str, "")
1915
+
1916
+ case result.sexp_type
1917
+ when :dstr then
1918
+ result.sexp_type = :dsym
1919
+ when :str then
1920
+ result = s(:lit, result.last.to_sym)
1921
+ when :evstr then
1922
+ result = s(:dsym, "", result)
1923
+ else
1924
+ debug20 26, val, result
1925
+ end
1926
+ }
1927
+
1928
+ numeric: simple_numeric
1929
+ | tUMINUS_NUM simple_numeric
1930
+ {
1931
+ result = -val[1] # TODO: pt_testcase
1932
+ }
1933
+
1934
+ simple_numeric: tINTEGER
1935
+ | tFLOAT
1936
+ | tRATIONAL
1937
+ | tIMAGINARY
1938
+
1939
+ user_variable: tIDENTIFIER
1940
+ | tIVAR
1941
+ | tGVAR
1942
+ | tCONSTANT
1943
+ | tCVAR
1944
+
1945
+ keyword_variable: kNIL { result = s(:nil) }
1946
+ | kSELF { result = s(:self) }
1947
+ | kTRUE { result = s(:true) }
1948
+ | kFALSE { result = s(:false) }
1949
+ | k__FILE__ { result = s(:str, self.file) }
1950
+ | k__LINE__ { result = s(:lit, lexer.lineno) }
1951
+ | k__ENCODING__
1952
+ {
1953
+ result =
1954
+ if defined? Encoding then
1955
+ s(:colon2, s(:const, :Encoding), :UTF_8)
1956
+ else
1957
+ s(:str, "Unsupported!")
1958
+ end
1959
+ }
1960
+
1961
+ var_ref: user_variable
1962
+ {
1963
+ var = val[0]
1964
+ result = Sexp === var ? var : self.gettable(var)
1965
+ }
1966
+ | keyword_variable
1967
+ {
1968
+ var = val[0]
1969
+ result = Sexp === var ? var : self.gettable(var)
1970
+ }
1971
+
1972
+ var_lhs: user_variable
1973
+ {
1974
+ result = self.assignable val[0]
1975
+ }
1976
+ | keyword_variable
1977
+ {
1978
+ result = self.assignable val[0]
1979
+ debug20 29, val, result
1980
+ }
1981
+
1982
+ backref: tNTH_REF { result = s(:nth_ref, val[0]) }
1983
+ | tBACK_REF { result = s(:back_ref, val[0]) }
1984
+
1985
+ superclass: term
1986
+ {
1987
+ result = nil
1988
+ }
1989
+ | tLT
1990
+ {
1991
+ lexer.lex_state = :expr_beg
1992
+ }
1993
+ expr_value term
1994
+ {
1995
+ result = val[2]
1996
+ }
1997
+ | error term
1998
+ {
1999
+ yyerrok
2000
+ result = nil
2001
+ debug20 30, val, result
2002
+ }
2003
+
2004
+ f_arglist: tLPAREN2 f_args rparen
2005
+ {
2006
+ result = val[1]
2007
+ self.lexer.lex_state = :expr_beg
2008
+ self.lexer.command_start = true
2009
+ # TODO:
2010
+ # $<num>$ = parser->parser_in_kwarg;
2011
+ # parser->parser_in_kwarg = 1;
2012
+ }
2013
+ | f_args term
2014
+ {
2015
+ # TODO: parser->parser_in_kwarg = $<num>1;
2016
+ result = val[0]
2017
+ self.lexer.lex_state = :expr_beg
2018
+ self.lexer.command_start = true
2019
+ }
2020
+
2021
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2022
+ {
2023
+ result = args val
2024
+ }
2025
+ | f_kwarg opt_f_block_arg
2026
+ {
2027
+ result = args val
2028
+ }
2029
+ | f_kwrest opt_f_block_arg
2030
+ {
2031
+ result = args val
2032
+ }
2033
+ | f_block_arg
2034
+
2035
+ opt_args_tail: tCOMMA args_tail
2036
+ {
2037
+ result = val[1]
2038
+ }
2039
+ |
2040
+ {
2041
+ result = nil
2042
+ }
2043
+
2044
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2045
+ {
2046
+ result = args val
2047
+ }
2048
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2049
+ {
2050
+ result = args val
2051
+ }
2052
+ | f_arg tCOMMA f_optarg opt_args_tail
2053
+ {
2054
+ result = args val
2055
+ }
2056
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2057
+ {
2058
+ result = args val
2059
+ }
2060
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2061
+ {
2062
+ result = args val
2063
+ }
2064
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2065
+ {
2066
+ result = args val
2067
+ }
2068
+ | f_arg opt_args_tail
2069
+ {
2070
+ result = args val
2071
+ }
2072
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2073
+ {
2074
+ result = args val
2075
+ }
2076
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2077
+ {
2078
+ result = args val
2079
+ }
2080
+ | f_optarg opt_args_tail
2081
+ {
2082
+ result = args val
2083
+ }
2084
+ | f_optarg tCOMMA f_arg opt_args_tail
2085
+ {
2086
+ result = args val
2087
+ }
2088
+ | f_rest_arg opt_args_tail
2089
+ {
2090
+ result = args val
2091
+ }
2092
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2093
+ {
2094
+ result = args val
2095
+ }
2096
+ | args_tail
2097
+ {
2098
+ result = args val
2099
+ }
2100
+ |
2101
+ {
2102
+ result = args val
2103
+ }
2104
+
2105
+ f_bad_arg: tCONSTANT
2106
+ {
2107
+ yyerror "formal argument cannot be a constant"
2108
+ }
2109
+ | tIVAR
2110
+ {
2111
+ yyerror "formal argument cannot be an instance variable"
2112
+ }
2113
+ | tGVAR
2114
+ {
2115
+ yyerror "formal argument cannot be a global variable"
2116
+ }
2117
+ | tCVAR
2118
+ {
2119
+ yyerror "formal argument cannot be a class variable"
2120
+ }
2121
+
2122
+ f_norm_arg: f_bad_arg
2123
+ | tIDENTIFIER
2124
+ {
2125
+ identifier = val[0].to_sym
2126
+ self.env[identifier] = :lvar
2127
+
2128
+ result = identifier
2129
+ }
2130
+
2131
+ f_arg_asgn: f_norm_arg
2132
+
2133
+ f_arg_item: f_arg_asgn
2134
+ | tLPAREN f_margs rparen
2135
+ {
2136
+ result = val[1]
2137
+ }
2138
+
2139
+ f_arg: f_arg_item
2140
+ {
2141
+ case val[0]
2142
+ when Symbol then
2143
+ result = s(:args)
2144
+ result << val[0]
2145
+ when Sexp then
2146
+ result = val[0]
2147
+ else
2148
+ debug20 32
2149
+ raise "Unknown f_arg type: #{val.inspect}"
2150
+ end
2151
+ }
2152
+ | f_arg tCOMMA f_arg_item
2153
+ {
2154
+ list, _, item = val
2155
+
2156
+ if list.sexp_type == :args then
2157
+ result = list
2158
+ else
2159
+ result = s(:args, list)
2160
+ end
2161
+
2162
+ result << item
2163
+ }
2164
+
2165
+ f_label: tLABEL
2166
+
2167
+ f_kw: f_label arg_value
2168
+ {
2169
+ # TODO: call_args
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, val[1]))
2175
+ }
2176
+ | f_label
2177
+ {
2178
+ label, _ = val[0] # TODO: fix lineno?
2179
+ identifier = label.to_sym
2180
+ self.env[identifier] = :lvar
2181
+
2182
+ result = s(:array, s(:kwarg, identifier))
2183
+ }
2184
+
2185
+ f_block_kw: f_label primary_value
2186
+ {
2187
+ # TODO: call_args
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, val[1]))
2193
+ }
2194
+ | f_label
2195
+ {
2196
+ label, _ = val[0] # TODO: fix lineno?
2197
+ identifier = label.to_sym
2198
+ self.env[identifier] = :lvar
2199
+
2200
+ result = s(:array, s(:kwarg, identifier))
2201
+ }
2202
+
2203
+ f_block_kwarg: f_block_kw
2204
+ | f_block_kwarg tCOMMA f_block_kw
2205
+ {
2206
+ list, _, item = val
2207
+ result = list << item.last
2208
+ }
2209
+
2210
+ f_kwarg: f_kw
2211
+ | f_kwarg tCOMMA f_kw
2212
+ {
2213
+ result = args val
2214
+ }
2215
+
2216
+ kwrest_mark: tPOW
2217
+ | tDSTAR
2218
+
2219
+ f_kwrest: kwrest_mark tIDENTIFIER
2220
+ {
2221
+ result = :"**#{val[1]}"
2222
+ }
2223
+ | kwrest_mark
2224
+ {
2225
+ result = :"**"
2226
+ }
2227
+
2228
+ f_opt: f_arg_asgn tEQL arg_value
2229
+ {
2230
+ result = self.assignable val[0], val[2]
2231
+ # TODO: detect duplicate names
2232
+ }
2233
+
2234
+ f_block_opt: f_arg_asgn tEQL primary_value
2235
+ {
2236
+ result = self.assignable val[0], val[2]
2237
+ }
2238
+
2239
+ f_block_optarg: f_block_opt
2240
+ {
2241
+ result = s(:block, val[0])
2242
+ }
2243
+ | f_block_optarg tCOMMA f_block_opt
2244
+ {
2245
+ result = val[0]
2246
+ result << val[2]
2247
+ }
2248
+
2249
+ f_optarg: f_opt
2250
+ {
2251
+ result = s(:block, val[0])
2252
+ }
2253
+ | f_optarg tCOMMA f_opt
2254
+ {
2255
+ result = self.block_append val[0], val[2]
2256
+ }
2257
+
2258
+ restarg_mark: tSTAR2 | tSTAR
2259
+
2260
+ f_rest_arg: restarg_mark tIDENTIFIER
2261
+ {
2262
+ # TODO: differs from parse.y - needs tests
2263
+ name = val[1].to_sym
2264
+ self.assignable name
2265
+ result = :"*#{name}"
2266
+ }
2267
+ | restarg_mark
2268
+ {
2269
+ name = :"*"
2270
+ self.env[name] = :lvar
2271
+ result = name
2272
+ }
2273
+
2274
+ blkarg_mark: tAMPER2 | tAMPER
2275
+
2276
+ f_block_arg: blkarg_mark tIDENTIFIER
2277
+ {
2278
+ identifier = val[1].to_sym
2279
+
2280
+ self.env[identifier] = :lvar
2281
+ result = "&#{identifier}".to_sym
2282
+ }
2283
+
2284
+ opt_f_block_arg: tCOMMA f_block_arg
2285
+ {
2286
+ result = val[1]
2287
+ }
2288
+ |
2289
+ {
2290
+ result = nil
2291
+ }
2292
+
2293
+ singleton: var_ref
2294
+ | tLPAREN2
2295
+ {
2296
+ lexer.lex_state = :expr_beg
2297
+ }
2298
+ expr rparen
2299
+ {
2300
+ result = val[2]
2301
+ yyerror "Can't define single method for literals." if
2302
+ result.sexp_type == :lit
2303
+ }
2304
+
2305
+ assoc_list: none # [!nil]
2306
+ {
2307
+ result = s(:array)
2308
+ }
2309
+ | assocs trailer # [!nil]
2310
+ {
2311
+ result = val[0]
2312
+ }
2313
+
2314
+ assocs: assoc
2315
+ | assocs tCOMMA assoc
2316
+ {
2317
+ list = val[0].dup
2318
+ more = val[2].sexp_body
2319
+ list.push(*more) unless more.empty?
2320
+ result = list
2321
+ result.sexp_type = :hash
2322
+ }
2323
+
2324
+ assoc: arg_value tASSOC arg_value
2325
+ {
2326
+ result = s(:array, val[0], val[2])
2327
+ }
2328
+ | tLABEL opt_nl arg_value
2329
+ {
2330
+ result = s(:array, s(:lit, val[0][0].to_sym), val.last)
2331
+ }
2332
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2333
+ {
2334
+ _, sym, _, value = val
2335
+ sym.sexp_type = :dsym
2336
+ result = s(:array, sym, value)
2337
+ }
2338
+ | tSYMBOL arg_value
2339
+ {
2340
+ raise "not yet: #{val.inspect}"
2341
+ # result = s(:array, s(:lit, val[1].to_sym), val[1])
2342
+ }
2343
+ | tDSTAR arg_value
2344
+ {
2345
+ result = s(:array, s(:kwsplat, val[1]))
2346
+ }
2347
+
2348
+ operation: tIDENTIFIER | tCONSTANT | tFID
2349
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2350
+ operation3: tIDENTIFIER | tFID | op
2351
+ dot_or_colon: tDOT | tCOLON2
2352
+ call_op: tDOT
2353
+ | tLONELY
2354
+ opt_terms: | terms
2355
+ opt_nl: | tNL
2356
+ rparen: opt_nl tRPAREN
2357
+ rbracket: opt_nl tRBRACK
2358
+ trailer: | tNL | tCOMMA
2359
+
2360
+ term: tSEMI { yyerrok }
2361
+ | tNL
2362
+
2363
+ terms: term
2364
+ | terms tSEMI { yyerrok }
2365
+
2366
+ none: { result = nil; }
2367
+ end
2368
+
2369
+ ---- inner
2370
+
2371
+ require "ruby_lexer"
2372
+ require "ruby_parser_extras"
2373
+
2374
+ # :stopdoc:
2375
+
2376
+ # Local Variables: **
2377
+ # racc-token-length-max:14 **
2378
+ # End: **