ruby_parser-legacy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of ruby_parser-legacy might be problematic. Click here for more details.

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