ruby_parser 3.1.3 → 3.2.0

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