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