ruby_parser 3.1.3 → 3.2.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,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: **