ruby_parser 3.14.0 → 3.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2677 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby30Parser
4
+
5
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
6
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
7
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
8
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
9
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
10
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
11
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
12
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
13
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
14
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
15
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
16
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
17
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
18
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
22
+ tRATIONAL tIMAGINARY
23
+ tLABEL_END
24
+ tLONELY
25
+ tBDOT2 tBDOT3
26
+
27
+ preclow
28
+ nonassoc tLOWEST
29
+ nonassoc tLBRACE_ARG
30
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
31
+ left kOR kAND
32
+ right kNOT
33
+ nonassoc kDEFINED
34
+ right tEQL tOP_ASGN
35
+ left kRESCUE_MOD
36
+ right tEH tCOLON
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
38
+ left tOROP
39
+ left tANDOP
40
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
41
+ left tGT tGEQ tLT tLEQ
42
+ left tPIPE tCARET
43
+ left tAMPER2
44
+ left tLSHFT tRSHFT
45
+ left tPLUS tMINUS
46
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
47
+ right tUMINUS_NUM tUMINUS
48
+ right tPOW
49
+ right tBANG tTILDE tUPLUS
50
+ prechigh
51
+
52
+ rule
53
+
54
+ program: {
55
+ self.lexer.lex_state = EXPR_BEG
56
+ }
57
+ top_compstmt
58
+ {
59
+ result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
63
+ }
64
+
65
+ top_compstmt: top_stmts opt_terms
66
+ {
67
+ stmt, _ = val
68
+ result = stmt
69
+ }
70
+
71
+ top_stmts: none
72
+ | top_stmt
73
+ | top_stmts terms top_stmt
74
+ {
75
+ result = self.block_append val[0], val[2]
76
+ }
77
+ | error top_stmt
78
+
79
+ top_stmt: stmt
80
+ | klBEGIN
81
+ {
82
+ if (self.in_def || self.in_single > 0) then
83
+ debug20 1
84
+ yyerror "BEGIN in method"
85
+ end
86
+ self.env.extend
87
+ }
88
+ begin_block
89
+ {
90
+ (_, lineno), _, iter = val
91
+ iter.line lineno
92
+
93
+ (_, preexe,) = iter
94
+ preexe.line lineno
95
+
96
+ result = iter
97
+ }
98
+
99
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
100
+ {
101
+ _, line, stmt, _ = val
102
+ result = new_iter s(:preexe).line(line), 0, stmt
103
+ }
104
+
105
+ bodystmt: compstmt opt_rescue k_else
106
+ {
107
+ res = _values[-2]
108
+ yyerror "else without rescue is useless" unless res
109
+ }
110
+ compstmt
111
+ opt_ensure
112
+ {
113
+ body, resc, _, _, els, ens = val
114
+
115
+ result = new_body [body, resc, els, ens]
116
+ }
117
+ | compstmt opt_rescue opt_ensure
118
+ {
119
+ body, resc, ens = val
120
+
121
+ result = new_body [body, resc, nil, ens]
122
+ }
123
+
124
+ compstmt: stmts opt_terms
125
+ {
126
+ result = new_compstmt val
127
+ }
128
+
129
+ stmts: none
130
+ | stmt_or_begin # TODO: newline_node ?
131
+ | stmts terms stmt_or_begin
132
+ {
133
+ result = self.block_append val[0], val[2]
134
+ }
135
+ | error stmt
136
+ {
137
+ result = val[1]
138
+ debug20 2, val, result
139
+ }
140
+
141
+ stmt_or_begin: stmt
142
+ | klBEGIN
143
+ {
144
+ yyerror "BEGIN is permitted only at toplevel"
145
+ }
146
+
147
+ stmt: kALIAS fitem
148
+ {
149
+ lexer.lex_state = EXPR_FNAME
150
+ }
151
+ fitem
152
+ {
153
+ (_, line), lhs, _, rhs = val
154
+ result = s(:alias, lhs, rhs).line(line).line line
155
+ }
156
+ | kALIAS tGVAR tGVAR
157
+ {
158
+ (_, line), lhs, rhs = val
159
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
+ }
161
+ | kALIAS tGVAR tBACK_REF
162
+ {
163
+ (_, line), lhs, rhs = val
164
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
+ }
166
+ | kALIAS tGVAR tNTH_REF
167
+ {
168
+ yyerror "can't make alias for the number variables"
169
+ }
170
+ | kUNDEF undef_list
171
+ {
172
+ result = val[1]
173
+ }
174
+ | stmt kIF_MOD expr_value
175
+ {
176
+ t, _, c = val
177
+ result = new_if c, t, nil
178
+ }
179
+ | stmt kUNLESS_MOD expr_value
180
+ {
181
+ f, _, c = val
182
+ result = new_if c, nil, f
183
+ }
184
+ | stmt kWHILE_MOD expr_value
185
+ {
186
+ e, _, c = val
187
+ result = new_while e, c, true
188
+ }
189
+ | stmt kUNTIL_MOD expr_value
190
+ {
191
+ e, _, c = val
192
+ result = new_until e, c, true
193
+ }
194
+ | stmt kRESCUE_MOD stmt
195
+ {
196
+ body, _, resbody = val
197
+
198
+ resbody = new_resbody s(:array).line(resbody.line), resbody
199
+ result = new_rescue body, resbody
200
+ }
201
+ | klEND tLCURLY compstmt tRCURLY
202
+ {
203
+ (_, line), _, stmt, _ = val
204
+
205
+ if (self.in_def || self.in_single > 0) then
206
+ debug20 3
207
+ yyerror "END in method; use at_exit"
208
+ end
209
+
210
+ result = new_iter s(:postexe).line(line), 0, stmt
211
+ }
212
+ | command_asgn
213
+ | mlhs tEQL command_call
214
+ {
215
+ result = new_masgn val[0], val[2], :wrap
216
+ }
217
+ | lhs tEQL mrhs
218
+ {
219
+ lhs, _, rhs = val
220
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
221
+ }
222
+ | mlhs tEQL mrhs_arg
223
+ {
224
+ result = new_masgn val[0], val[2]
225
+ }
226
+ | expr
227
+
228
+ command_asgn: lhs tEQL command_rhs
229
+ {
230
+ result = new_assign val[0], val[2]
231
+ }
232
+ # | lhs tEQL command_asgn
233
+ # {
234
+ # result = new_assign val[0], val[2]
235
+ # }
236
+ | var_lhs tOP_ASGN command_rhs
237
+ {
238
+ result = new_op_asgn val
239
+ }
240
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
241
+ {
242
+ result = new_op_asgn1 val
243
+ }
244
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
+ {
246
+ prim, _, id, opasgn, rhs = val
247
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
+ if val[1] == '&.'
249
+ result.sexp_type = :safe_op_asgn
250
+ end
251
+ result.line = val[0].line
252
+ }
253
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
+ {
255
+ result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
+ if val[1] == '&.'
257
+ result.sexp_type = :safe_op_asgn
258
+ end
259
+ result.line = val[0].line
260
+ }
261
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
+ {
263
+ lhs1, _, lhs2, op, rhs = val
264
+
265
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
266
+ }
267
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
+ {
269
+ lhs1, _, lhs2, op, rhs = val
270
+
271
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
272
+ }
273
+ | backref tOP_ASGN command_rhs
274
+ {
275
+ self.backref_assign_error val[0]
276
+ }
277
+
278
+ command_rhs: command_call =tOP_ASGN
279
+ {
280
+ expr, = val
281
+ result = value_expr expr
282
+ }
283
+ | command_call kRESCUE_MOD stmt
284
+ {
285
+ expr, (_, line), resbody = val
286
+
287
+ expr = value_expr expr
288
+ ary = s(:array).line line
289
+ result = new_rescue(expr, new_resbody(ary, resbody))
290
+ }
291
+ | command_asgn
292
+
293
+ expr: command_call
294
+ | expr kAND expr
295
+ {
296
+ lhs, _, rhs = val
297
+ result = logical_op :and, lhs, rhs
298
+ }
299
+ | expr kOR expr
300
+ {
301
+ lhs, _, rhs = val
302
+ result = logical_op :or, lhs, rhs
303
+ }
304
+ | kNOT opt_nl expr
305
+ {
306
+ (_, line), _, expr = val
307
+ result = new_call(expr, :"!").line line
308
+ # REFACTOR: call_uni_op
309
+ }
310
+ | tBANG command_call
311
+ {
312
+ _, cmd = val
313
+ result = new_call(cmd, :"!").line cmd.line
314
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
+ # REFACTOR: call_uni_op -- see parse26.y
316
+ }
317
+ | arg
318
+
319
+ expr_value: expr
320
+ {
321
+ result = value_expr(val[0])
322
+ }
323
+
324
+ expr_value_do: {
325
+ lexer.cond.push true
326
+ }
327
+ expr_value do
328
+ {
329
+ lexer.cond.pop
330
+ }
331
+ {
332
+ _, expr, _, _ = val
333
+ result = expr
334
+ }
335
+
336
+ command_call: command
337
+ | block_command
338
+
339
+ block_command: block_call
340
+ | block_call call_op2 operation2 command_args
341
+ {
342
+ blk, _, msg, args = val
343
+ result = new_call(blk, msg.to_sym, args).line blk.line
344
+ }
345
+
346
+ cmd_brace_block: tLBRACE_ARG
347
+ {
348
+ # self.env.extend(:dynamic)
349
+ result = self.lexer.lineno
350
+ }
351
+ brace_body tRCURLY
352
+ {
353
+ _, line, body, _ = val
354
+
355
+ result = body
356
+ result.line = line
357
+
358
+ # self.env.unextend
359
+ }
360
+
361
+ fcall: operation
362
+ {
363
+ msg, = val
364
+ result = new_call(nil, msg.to_sym).line lexer.lineno
365
+ }
366
+
367
+ command: fcall command_args =tLOWEST
368
+ {
369
+ call, args = val
370
+ result = call.concat args.sexp_body
371
+ }
372
+ | fcall command_args cmd_brace_block
373
+ {
374
+ call, args, block = val
375
+
376
+ result = call.concat args.sexp_body
377
+
378
+ if block then
379
+ block_dup_check result, block
380
+
381
+ result, operation = block, result
382
+ result.insert 1, operation
383
+ end
384
+ }
385
+ | primary_value call_op operation2 command_args =tLOWEST
386
+ {
387
+ lhs, callop, op, args = val
388
+ result = new_call lhs, op.to_sym, args, callop
389
+ }
390
+ | primary_value call_op operation2 command_args cmd_brace_block
391
+ {
392
+ recv, _, msg, args, block = val
393
+ call = new_call recv, msg.to_sym, args, val[1]
394
+
395
+ block_dup_check call, block
396
+
397
+ block.insert 1, call
398
+ result = block
399
+ }
400
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
401
+ {
402
+ result = new_call val[0], val[2].to_sym, val[3]
403
+ }
404
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
+ {
406
+ recv, _, msg, args, block = val
407
+ call = new_call recv, msg.to_sym, args
408
+
409
+ block_dup_check call, block
410
+
411
+ block.insert 1, call
412
+ result = block
413
+ }
414
+ | kSUPER command_args
415
+ {
416
+ result = new_super val[1]
417
+ }
418
+ | kYIELD command_args
419
+ {
420
+ (_, line), args = val
421
+ result = new_yield args
422
+ result.line line # TODO: push to new_yield
423
+ }
424
+ | k_return call_args
425
+ {
426
+ line = val[0].last
427
+ result = s(:return, ret_args(val[1])).line(line)
428
+ }
429
+ | kBREAK call_args
430
+ {
431
+ (_, line), args = val
432
+ result = s(:break, ret_args(args)).line line
433
+ }
434
+ | kNEXT call_args
435
+ {
436
+ line = val[0].last
437
+ result = s(:next, ret_args(val[1])).line(line)
438
+ }
439
+
440
+ mlhs: mlhs_basic
441
+ | tLPAREN mlhs_inner rparen
442
+ {
443
+ result = val[1]
444
+ }
445
+
446
+ mlhs_inner: mlhs_basic
447
+ | tLPAREN mlhs_inner rparen
448
+ {
449
+ _, arg, _ = val
450
+ l = arg.line
451
+
452
+ result = s(:masgn, s(:array, arg).line(l)).line l
453
+ }
454
+
455
+ mlhs_basic: mlhs_head
456
+ {
457
+ head, = val
458
+ result = s(:masgn, head).line head.line
459
+ }
460
+ | mlhs_head mlhs_item
461
+ {
462
+ lhs, rhs = val
463
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
464
+ }
465
+ | mlhs_head tSTAR mlhs_node
466
+ {
467
+ head, _, tail = val
468
+ head << s(:splat, tail).line(tail.line)
469
+ result = s(:masgn, head).line head.line
470
+ }
471
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
472
+ {
473
+ ary1, _, splat, _, ary2 = val
474
+
475
+ result = list_append ary1, s(:splat, splat).line(splat.line)
476
+ result.concat ary2.sexp_body
477
+ result = s(:masgn, result).line result.line
478
+ }
479
+ | mlhs_head tSTAR
480
+ {
481
+ head, _ = val
482
+ l = head.line
483
+ result = s(:masgn, head << s(:splat).line(l)).line l
484
+ }
485
+ | mlhs_head tSTAR tCOMMA mlhs_post
486
+ {
487
+ head, _, _, post = val
488
+ ary = list_append head, s(:splat).line(head.line)
489
+ ary.concat post.sexp_body
490
+ result = s(:masgn, ary).line ary.line
491
+ }
492
+ | tSTAR mlhs_node
493
+ {
494
+ _, node = val
495
+ l = node.line
496
+ splat = s(:splat, node).line l
497
+ ary = s(:array, splat).line l
498
+ result = s(:masgn, ary).line l
499
+ }
500
+ | tSTAR mlhs_node tCOMMA mlhs_post
501
+ {
502
+ _, node, _, post = val
503
+
504
+ splat = s(:splat, node).line node.line
505
+ ary = s(:array, splat).line splat.line
506
+ ary.concat post.sexp_body
507
+ result = s(:masgn, ary).line ary.line
508
+ }
509
+ | tSTAR
510
+ {
511
+ l = lexer.lineno
512
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
513
+ }
514
+ | tSTAR tCOMMA mlhs_post
515
+ {
516
+ _, _, post = val
517
+ l = post.line
518
+
519
+ splat = s(:splat).line l
520
+ ary = s(:array, splat, *post.sexp_body).line l
521
+ result = s(:masgn, ary).line l
522
+ }
523
+
524
+ mlhs_item: mlhs_node
525
+ | tLPAREN mlhs_inner rparen
526
+ {
527
+ result = val[1]
528
+ }
529
+
530
+ mlhs_head: mlhs_item tCOMMA
531
+ {
532
+ lhs, _ = val
533
+ result = s(:array, lhs).line lhs.line
534
+ }
535
+ | mlhs_head mlhs_item tCOMMA
536
+ {
537
+ result = val[0] << val[1].compact
538
+ }
539
+
540
+ mlhs_post: mlhs_item
541
+ {
542
+ item, = val
543
+ result = s(:array, item).line item.line
544
+ }
545
+ | mlhs_post tCOMMA mlhs_item
546
+ {
547
+ result = list_append val[0], val[2]
548
+ }
549
+
550
+ mlhs_node: user_variable
551
+ {
552
+ result = self.assignable val[0]
553
+ }
554
+ | keyword_variable
555
+ {
556
+ result = self.assignable val[0]
557
+ }
558
+ | primary_value tLBRACK2 opt_call_args rbracket
559
+ {
560
+ result = self.aryset val[0], val[2]
561
+ }
562
+ | primary_value call_op tIDENTIFIER
563
+ {
564
+ result = new_attrasgn val[0], val[2], val[1]
565
+ }
566
+ | primary_value tCOLON2 tIDENTIFIER
567
+ {
568
+ recv, _, id = val
569
+ result = new_attrasgn recv, id
570
+ }
571
+ | primary_value call_op tCONSTANT
572
+ {
573
+ result = new_attrasgn val[0], val[2], val[1]
574
+ }
575
+ | primary_value tCOLON2 tCONSTANT
576
+ {
577
+ if (self.in_def || self.in_single > 0) then
578
+ debug20 7
579
+ yyerror "dynamic constant assignment"
580
+ end
581
+
582
+ expr, _, id = val
583
+ l = expr.line
584
+
585
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
586
+ }
587
+ | tCOLON3 tCONSTANT
588
+ {
589
+ if (self.in_def || self.in_single > 0) then
590
+ debug20 8
591
+ yyerror "dynamic constant assignment"
592
+ end
593
+
594
+ _, id = val
595
+ l = lexer.lineno
596
+
597
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
+ }
599
+ | backref
600
+ {
601
+ self.backref_assign_error val[0]
602
+ }
603
+
604
+ lhs: user_variable
605
+ {
606
+ line = lexer.lineno
607
+ result = self.assignable val[0]
608
+ result.line = line
609
+ }
610
+ | keyword_variable
611
+ {
612
+ line = lexer.lineno
613
+ result = self.assignable val[0]
614
+ result.line = line
615
+ debug20 9, val, result
616
+ }
617
+ | primary_value tLBRACK2 opt_call_args rbracket
618
+ {
619
+ lhs, _, args, _ = val
620
+ result = self.aryset lhs, args
621
+ }
622
+ | primary_value call_op tIDENTIFIER # REFACTOR
623
+ {
624
+ lhs, op, id = val
625
+ result = new_attrasgn lhs, id, op
626
+ }
627
+ | primary_value tCOLON2 tIDENTIFIER
628
+ {
629
+ lhs, _, id = val
630
+ result = new_attrasgn lhs, id
631
+ }
632
+ | primary_value call_op tCONSTANT # REFACTOR?
633
+ {
634
+ result = new_attrasgn val[0], val[2], val[1]
635
+ }
636
+ | primary_value tCOLON2 tCONSTANT
637
+ {
638
+ expr, _, id = val
639
+
640
+ if (self.in_def || self.in_single > 0) then
641
+ debug20 10
642
+ yyerror "dynamic constant assignment"
643
+ end
644
+
645
+ l = expr.line
646
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
647
+ }
648
+ | tCOLON3 tCONSTANT
649
+ {
650
+ _, id = val
651
+
652
+ if (self.in_def || self.in_single > 0) then
653
+ debug20 11
654
+ yyerror "dynamic constant assignment"
655
+ end
656
+
657
+ l = lexer.lineno
658
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
+ }
660
+ | backref
661
+ {
662
+ self.backref_assign_error val[0]
663
+ }
664
+
665
+ cname: tIDENTIFIER
666
+ {
667
+ yyerror "class/module name must be CONSTANT"
668
+ }
669
+ | tCONSTANT
670
+
671
+ cpath: tCOLON3 cname
672
+ {
673
+ _, name = val
674
+ result = s(:colon3, name.to_sym).line lexer.lineno
675
+ }
676
+ | cname
677
+ {
678
+ result = val[0].to_sym
679
+ }
680
+ | primary_value tCOLON2 cname
681
+ {
682
+ pval, _, name = val
683
+
684
+ result = s(:colon2, pval, name.to_sym)
685
+ result.line pval.line
686
+ }
687
+
688
+ fname: tIDENTIFIER | tCONSTANT | tFID
689
+ | op
690
+ {
691
+ lexer.lex_state = EXPR_END
692
+ result = val[0]
693
+ }
694
+
695
+ | reswords
696
+ {
697
+ (sym, _line), = val
698
+ lexer.lex_state = EXPR_END
699
+ result = sym
700
+ }
701
+
702
+ fsym: fname | symbol
703
+
704
+ fitem: fsym
705
+ {
706
+ id, = val
707
+ result = s(:lit, id.to_sym).line lexer.lineno
708
+ }
709
+ | dsym
710
+
711
+ undef_list: fitem
712
+ {
713
+ result = new_undef val[0]
714
+ }
715
+ |
716
+ undef_list tCOMMA
717
+ {
718
+ lexer.lex_state = EXPR_FNAME
719
+ }
720
+ fitem
721
+ {
722
+ result = new_undef val[0], val[3]
723
+ }
724
+
725
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
726
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
727
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
+ # TODO: tUBANG dead?
731
+ | tUBANG
732
+
733
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
735
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
736
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
737
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
738
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
739
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
740
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
741
+ | kUNTIL
742
+
743
+ arg: lhs tEQL arg_rhs
744
+ {
745
+ result = new_assign val[0], val[2]
746
+ }
747
+ | var_lhs tOP_ASGN arg_rhs
748
+ {
749
+ result = new_op_asgn val
750
+ }
751
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
752
+ {
753
+ result = new_op_asgn1 val
754
+ }
755
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
756
+ {
757
+ result = new_op_asgn2 val
758
+ }
759
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
760
+ {
761
+ result = new_op_asgn2 val
762
+ }
763
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
+ {
765
+ lhs, _, id, op, rhs = val
766
+
767
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
+ }
769
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
+ {
771
+ lhs1, _, lhs2, op, rhs = val
772
+
773
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
+ result = new_const_op_asgn [lhs, op, rhs]
775
+ }
776
+ | tCOLON3 tCONSTANT
777
+ {
778
+ result = self.lexer.lineno
779
+ }
780
+ tOP_ASGN arg_rhs
781
+ {
782
+ _, lhs, line, op, rhs = val
783
+
784
+ lhs = s(:colon3, lhs.to_sym).line line
785
+ result = new_const_op_asgn [lhs, op, rhs]
786
+ }
787
+ | backref tOP_ASGN arg_rhs
788
+ {
789
+ # TODO: lhs = var_field val[0]
790
+ asgn = new_op_asgn val
791
+ result = self.backref_assign_error asgn
792
+ }
793
+ | arg tDOT2 arg
794
+ {
795
+ v1, v2 = val[0], val[2]
796
+ if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
797
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
+ else
799
+ result = s(:dot2, v1, v2).line v1.line
800
+ end
801
+ }
802
+ | arg tDOT3 arg
803
+ {
804
+ v1, v2 = val[0], val[2]
805
+ if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
806
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
+ else
808
+ result = s(:dot3, v1, v2).line v1.line
809
+ end
810
+ }
811
+ | arg tDOT2
812
+ {
813
+ v1, _ = val
814
+ v2 = nil
815
+
816
+ result = s(:dot2, v1, v2).line v1.line
817
+ }
818
+ | arg tDOT3
819
+ {
820
+ v1, _ = val
821
+ v2 = nil
822
+
823
+ result = s(:dot3, v1, v2).line v1.line
824
+ }
825
+
826
+ | tBDOT2 arg
827
+ {
828
+ _, v2, = val
829
+ v1 = nil
830
+
831
+ result = s(:dot2, v1, v2).line v2.line
832
+ }
833
+ | tBDOT3 arg
834
+ {
835
+ _, v2 = val
836
+ v1 = nil
837
+
838
+ result = s(:dot3, v1, v2).line v2.line
839
+ }
840
+
841
+ | arg tPLUS arg
842
+ {
843
+ result = new_call val[0], :+, argl(val[2])
844
+ }
845
+ | arg tMINUS arg
846
+ {
847
+ result = new_call val[0], :-, argl(val[2])
848
+ }
849
+ | arg tSTAR2 arg # TODO: rename
850
+ {
851
+ result = new_call val[0], :*, argl(val[2])
852
+ }
853
+ | arg tDIVIDE arg
854
+ {
855
+ result = new_call val[0], :"/", argl(val[2])
856
+ }
857
+ | arg tPERCENT arg
858
+ {
859
+ result = new_call val[0], :"%", argl(val[2])
860
+ }
861
+ | arg tPOW arg
862
+ {
863
+ result = new_call val[0], :**, argl(val[2])
864
+ }
865
+ | tUMINUS_NUM simple_numeric tPOW arg
866
+ {
867
+ lit = s(:lit, val[1]).line lexer.lineno
868
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
869
+
870
+ }
871
+ | tUPLUS arg
872
+ {
873
+ result = new_call val[1], :"+@"
874
+ }
875
+ | tUMINUS arg
876
+ {
877
+ result = new_call val[1], :"-@"
878
+ }
879
+ | arg tPIPE arg
880
+ {
881
+ result = new_call val[0], :"|", argl(val[2])
882
+ }
883
+ | arg tCARET arg
884
+ {
885
+ result = new_call val[0], :"^", argl(val[2])
886
+ }
887
+ | arg tAMPER2 arg
888
+ {
889
+ result = new_call val[0], :"&", argl(val[2])
890
+ }
891
+ | arg tCMP arg
892
+ {
893
+ result = new_call val[0], :"<=>", argl(val[2])
894
+ }
895
+ | rel_expr =tCMP
896
+ | arg tEQ arg
897
+ {
898
+ result = new_call val[0], :"==", argl(val[2])
899
+ }
900
+ | arg tEQQ arg
901
+ {
902
+ result = new_call val[0], :"===", argl(val[2])
903
+ }
904
+ | arg tNEQ arg
905
+ {
906
+ result = new_call val[0], :"!=", argl(val[2])
907
+ }
908
+ | arg tMATCH arg
909
+ {
910
+ lhs, _, rhs = val
911
+ result = new_match lhs, rhs
912
+ }
913
+ | arg tNMATCH arg
914
+ {
915
+ lhs, _, rhs = val
916
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
917
+ }
918
+ | tBANG arg
919
+ {
920
+ _, arg = val
921
+ result = new_call arg, :"!"
922
+ result.line arg.line
923
+ }
924
+ | tTILDE arg
925
+ {
926
+ result = new_call value_expr(val[1]), :"~"
927
+ }
928
+ | arg tLSHFT arg
929
+ {
930
+ val[0] = value_expr val[0]
931
+ val[2] = value_expr val[2]
932
+ result = new_call val[0], :"\<\<", argl(val[2])
933
+ }
934
+ | arg tRSHFT arg
935
+ {
936
+ val[0] = value_expr val[0]
937
+ val[2] = value_expr val[2]
938
+ result = new_call val[0], :">>", argl(val[2])
939
+ }
940
+ | arg tANDOP arg
941
+ {
942
+ result = logical_op :and, val[0], val[2]
943
+ }
944
+ | arg tOROP arg
945
+ {
946
+ result = logical_op :or, val[0], val[2]
947
+ }
948
+ | kDEFINED opt_nl arg
949
+ {
950
+ (_, line), _, arg = val
951
+ result = s(:defined, arg).line line
952
+ }
953
+ | arg tEH arg opt_nl tCOLON arg
954
+ {
955
+ c, _, t, _, _, f = val
956
+ result = s(:if, c, t, f).line c.line
957
+ }
958
+ | primary
959
+
960
+ relop: tGT
961
+ | tLT
962
+ | tGEQ
963
+ | tLEQ
964
+
965
+ rel_expr: arg relop arg =tGT
966
+ {
967
+ lhs, op, rhs = val
968
+ result = new_call lhs, op.to_sym, argl(rhs)
969
+ }
970
+ | rel_expr relop arg =tGT
971
+ {
972
+ lhs, op, rhs = val
973
+ warn "comparison '%s' after comparison", op
974
+ result = new_call lhs, op.to_sym, argl(rhs)
975
+ }
976
+
977
+ arg_value: arg
978
+ {
979
+ result = value_expr(val[0])
980
+ }
981
+
982
+ aref_args: none
983
+ | args trailer
984
+ {
985
+ result = args [val[0]]
986
+ }
987
+ | args tCOMMA assocs trailer
988
+ {
989
+ result = args [val[0], array_to_hash(val[2])]
990
+ }
991
+ | assocs trailer
992
+ {
993
+ result = args [array_to_hash(val[0])]
994
+ }
995
+
996
+ arg_rhs: arg =tOP_ASGN
997
+ | arg kRESCUE_MOD arg
998
+ {
999
+ body, (_, line), resbody = val
1000
+ body = value_expr body
1001
+ resbody = remove_begin resbody
1002
+
1003
+ ary = s(:array).line line
1004
+ result = new_rescue(body, new_resbody(ary, resbody))
1005
+ }
1006
+
1007
+ paren_args: tLPAREN2 opt_call_args rparen
1008
+ {
1009
+ _, args, _ = val
1010
+ result = args
1011
+ }
1012
+
1013
+ opt_paren_args: none
1014
+ | paren_args
1015
+
1016
+ opt_call_args: none
1017
+ | call_args
1018
+ | args tCOMMA
1019
+ {
1020
+ result = args val
1021
+ }
1022
+ | args tCOMMA assocs tCOMMA
1023
+ {
1024
+ result = args [val[0], array_to_hash(val[2])]
1025
+ }
1026
+ | assocs tCOMMA
1027
+ {
1028
+ result = args [array_to_hash(val[0])]
1029
+ }
1030
+
1031
+ call_args: command
1032
+ {
1033
+ warning "parenthesize argument(s) for future version"
1034
+ result = call_args val
1035
+ }
1036
+ | args opt_block_arg
1037
+ {
1038
+ result = call_args val
1039
+ }
1040
+ | assocs opt_block_arg
1041
+ {
1042
+ result = call_args [array_to_hash(val[0]), val[1]]
1043
+ }
1044
+ | args tCOMMA assocs opt_block_arg
1045
+ {
1046
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1047
+ }
1048
+ | block_arg
1049
+ {
1050
+ result = call_args val
1051
+ }
1052
+
1053
+ command_args: {
1054
+ # parse26.y line 2200
1055
+
1056
+ # If call_args starts with a open paren '(' or
1057
+ # '[', look-ahead reading of the letters calls
1058
+ # CMDARG_PUSH(0), but the push must be done
1059
+ # after CMDARG_PUSH(1). So this code makes them
1060
+ # consistent by first cancelling the premature
1061
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1062
+ # finally redoing CMDARG_PUSH(0).
1063
+
1064
+ result = yychar = self.last_token_type.first
1065
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1066
+ lexer.cmdarg.pop if lookahead
1067
+ lexer.cmdarg.push true
1068
+ lexer.cmdarg.push false if lookahead
1069
+ }
1070
+ call_args
1071
+ {
1072
+ yychar, args = val
1073
+
1074
+ # call_args can be followed by tLBRACE_ARG (that
1075
+ # does CMDARG_PUSH(0) in the lexer) but the push
1076
+ # must be done after CMDARG_POP() in the parser.
1077
+ # So this code does CMDARG_POP() to pop 0 pushed
1078
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1079
+ # by command_args, and CMDARG_PUSH(0) to restore
1080
+ # back the flag set by tLBRACE_ARG.
1081
+
1082
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1083
+ lexer.cmdarg.pop if lookahead
1084
+ lexer.cmdarg.pop
1085
+ lexer.cmdarg.push false if lookahead
1086
+ result = args
1087
+ }
1088
+
1089
+ block_arg: tAMPER arg_value
1090
+ {
1091
+ _, arg = val
1092
+ result = s(:block_pass, arg).line arg.line
1093
+ }
1094
+
1095
+ opt_block_arg: tCOMMA block_arg
1096
+ {
1097
+ result = val[1]
1098
+ }
1099
+ | none
1100
+
1101
+ args: arg_value
1102
+ {
1103
+ arg, = val
1104
+ lineno = arg.line || lexer.lineno # HACK
1105
+
1106
+ result = s(:array, arg).line lineno
1107
+ }
1108
+ | tSTAR arg_value
1109
+ {
1110
+ _, arg = val
1111
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1112
+ }
1113
+ | args tCOMMA arg_value
1114
+ {
1115
+ args, _, id = val
1116
+ result = self.list_append args, id
1117
+ }
1118
+ | args tCOMMA tSTAR arg_value
1119
+ {
1120
+ # TODO: the line number from tSTAR has been dropped
1121
+ args, _, _, id = val
1122
+ line = lexer.lineno
1123
+ result = self.list_append args, s(:splat, id).line(line)
1124
+ }
1125
+
1126
+ mrhs_arg: mrhs
1127
+ {
1128
+ result = new_masgn_arg val[0]
1129
+ }
1130
+ | arg_value
1131
+ {
1132
+ result = new_masgn_arg val[0], :wrap
1133
+ }
1134
+
1135
+ mrhs: args tCOMMA arg_value
1136
+ {
1137
+ result = val[0] << val[2]
1138
+ }
1139
+ | args tCOMMA tSTAR arg_value
1140
+ {
1141
+ # TODO: make all tXXXX terminals include lexer.lineno
1142
+ arg, _, _, splat = val
1143
+ result = self.arg_concat arg, splat
1144
+ }
1145
+ | tSTAR arg_value
1146
+ {
1147
+ _, arg = val
1148
+ result = s(:splat, arg).line arg.line
1149
+ }
1150
+
1151
+ primary: literal
1152
+ | strings
1153
+ | xstring
1154
+ | regexp
1155
+ | words
1156
+ | qwords
1157
+ | symbols
1158
+ | qsymbols
1159
+ | var_ref
1160
+ | backref
1161
+ | tFID
1162
+ {
1163
+ msg, = val
1164
+ result = new_call nil, msg.to_sym
1165
+ }
1166
+ | k_begin
1167
+ {
1168
+ lexer.cmdarg.push false
1169
+ result = self.lexer.lineno
1170
+ }
1171
+ bodystmt k_end
1172
+ {
1173
+ lexer.cmdarg.pop
1174
+ result = new_begin val
1175
+ }
1176
+ | tLPAREN_ARG
1177
+ {
1178
+ lexer.lex_state = EXPR_ENDARG
1179
+ result = lexer.lineno
1180
+ }
1181
+ rparen
1182
+ {
1183
+ _, line, _ = val
1184
+ result = s(:begin).line line
1185
+ }
1186
+ | tLPAREN_ARG
1187
+ stmt
1188
+ {
1189
+ lexer.lex_state = EXPR_ENDARG
1190
+ }
1191
+ rparen
1192
+ {
1193
+ _, stmt, _, _, = val
1194
+ # warning "(...) interpreted as grouped expression"
1195
+ result = stmt
1196
+ }
1197
+ | tLPAREN compstmt tRPAREN
1198
+ {
1199
+ _, stmt, _ = val
1200
+ result = stmt
1201
+ result ||= s(:nil).line lexer.lineno
1202
+ result.paren = true
1203
+ }
1204
+ | primary_value tCOLON2 tCONSTANT
1205
+ {
1206
+ expr, _, id = val
1207
+
1208
+ result = s(:colon2, expr, id.to_sym).line expr.line
1209
+ }
1210
+ | tCOLON3 tCONSTANT
1211
+ {
1212
+ _, id = val
1213
+
1214
+ result = s(:colon3, id.to_sym).line lexer.lineno
1215
+ }
1216
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1217
+ {
1218
+ _, line, args, _ = val
1219
+ result = args || s(:array)
1220
+ result.sexp_type = :array # aref_args is :args
1221
+ result.line line
1222
+ }
1223
+ | tLBRACE
1224
+ {
1225
+ result = self.lexer.lineno
1226
+ }
1227
+ assoc_list tRCURLY
1228
+ {
1229
+ result = new_hash val
1230
+ }
1231
+ | k_return
1232
+ {
1233
+ (_, line), = val
1234
+ result = s(:return).line line
1235
+ }
1236
+ | kYIELD tLPAREN2 call_args rparen
1237
+ {
1238
+ result = new_yield val[2]
1239
+ }
1240
+ | kYIELD tLPAREN2 rparen
1241
+ {
1242
+ result = new_yield
1243
+ }
1244
+ | kYIELD
1245
+ {
1246
+ result = new_yield
1247
+ }
1248
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1249
+ {
1250
+ (_, line), _, _, arg, _ = val
1251
+
1252
+ result = s(:defined, arg).line line
1253
+ }
1254
+ | kNOT tLPAREN2 expr rparen
1255
+ {
1256
+ _, _, lhs, _ = val
1257
+ result = new_call lhs, :"!"
1258
+ }
1259
+ | kNOT tLPAREN2 rparen
1260
+ {
1261
+ debug20 14, val, result
1262
+ }
1263
+ | fcall brace_block
1264
+ {
1265
+ call, iter = val
1266
+
1267
+ iter.insert 1, call
1268
+ result = iter
1269
+ # FIX: probably not: call.line = iter.line
1270
+ }
1271
+ | method_call
1272
+ | method_call brace_block
1273
+ {
1274
+ call, iter = val[0], val[1]
1275
+ block_dup_check call, iter
1276
+ iter.insert 1, call # FIX
1277
+ result = iter
1278
+ }
1279
+ | tLAMBDA lambda
1280
+ {
1281
+ result = val[1] # TODO: fix lineno
1282
+ }
1283
+ | k_if expr_value then compstmt if_tail k_end
1284
+ {
1285
+ _, c, _, t, f, _ = val
1286
+ result = new_if c, t, f
1287
+ }
1288
+ | k_unless expr_value then compstmt opt_else k_end
1289
+ {
1290
+ _, c, _, t, f, _ = val
1291
+ result = new_if c, f, t
1292
+ }
1293
+ | k_while expr_value_do compstmt k_end
1294
+ {
1295
+ _, cond, body, _ = val
1296
+ result = new_while body, cond, true
1297
+ }
1298
+ | k_until expr_value_do compstmt k_end
1299
+ {
1300
+ _, cond, body, _ = val
1301
+ result = new_until body, cond, true
1302
+ }
1303
+ | k_case expr_value opt_terms case_body k_end
1304
+ {
1305
+ (_, line), expr, _, body, _ = val
1306
+ result = new_case expr, body, line
1307
+ }
1308
+ | k_case opt_terms case_body k_end
1309
+ {
1310
+ (_, line), _, body, _ = val
1311
+ result = new_case nil, body, line
1312
+ }
1313
+ | k_for for_var kIN expr_value_do compstmt k_end
1314
+ {
1315
+ _, var, _, iter, body, _ = val
1316
+ result = new_for iter, var, body
1317
+ }
1318
+ | k_class
1319
+ {
1320
+ result = self.lexer.lineno
1321
+ }
1322
+ cpath superclass
1323
+ {
1324
+ self.comments.push self.lexer.comments
1325
+ if (self.in_def || self.in_single > 0) then
1326
+ yyerror "class definition in method body"
1327
+ end
1328
+ self.env.extend
1329
+ }
1330
+ bodystmt k_end
1331
+ {
1332
+ result = new_class val
1333
+ self.env.unextend
1334
+ self.lexer.comments # we don't care about comments in the body
1335
+ }
1336
+ | k_class tLSHFT
1337
+ {
1338
+ result = self.lexer.lineno
1339
+ }
1340
+ expr
1341
+ {
1342
+ result = self.in_def
1343
+ self.in_def = false
1344
+ }
1345
+ term
1346
+ {
1347
+ result = self.in_single
1348
+ self.in_single = 0
1349
+ self.env.extend
1350
+ }
1351
+ bodystmt k_end
1352
+ {
1353
+ result = new_sclass val
1354
+ self.env.unextend
1355
+ self.lexer.comments # we don't care about comments in the body
1356
+ }
1357
+ | k_module
1358
+ {
1359
+ result = self.lexer.lineno
1360
+ }
1361
+ cpath
1362
+ {
1363
+ self.comments.push self.lexer.comments
1364
+ yyerror "module definition in method body" if
1365
+ self.in_def or self.in_single > 0
1366
+
1367
+ self.env.extend
1368
+ }
1369
+ bodystmt k_end
1370
+ {
1371
+ result = new_module val
1372
+ self.env.unextend
1373
+ self.lexer.comments # we don't care about comments in the body
1374
+ }
1375
+ | k_def fname
1376
+ {
1377
+ result = self.in_def
1378
+
1379
+ self.in_def = true # group = local_push
1380
+ self.env.extend
1381
+ lexer.cmdarg.push false
1382
+ lexer.cond.push false
1383
+
1384
+ self.comments.push self.lexer.comments
1385
+ }
1386
+ f_arglist bodystmt { result = lexer.lineno } k_end
1387
+ {
1388
+ in_def = val[2]
1389
+
1390
+ result = new_defn val
1391
+
1392
+ lexer.cond.pop # group = local_pop
1393
+ lexer.cmdarg.pop
1394
+ self.env.unextend
1395
+ self.in_def = in_def
1396
+
1397
+ self.lexer.comments # we don't care about comments in the body
1398
+ }
1399
+ | k_def singleton dot_or_colon
1400
+ {
1401
+ lexer.lex_state = EXPR_FNAME
1402
+ }
1403
+ fname
1404
+ {
1405
+ result = [self.in_def, lexer.lineno]
1406
+
1407
+ self.in_single += 1 # TODO: remove?
1408
+
1409
+ self.in_def = true # local_push
1410
+ self.env.extend
1411
+ lexer.cmdarg.push false
1412
+ lexer.cond.push false
1413
+
1414
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1415
+ self.comments.push self.lexer.comments
1416
+ }
1417
+ f_arglist bodystmt k_end
1418
+ {
1419
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1420
+
1421
+ result = new_defs val
1422
+
1423
+ lexer.cond.pop # group = local_pop
1424
+ lexer.cmdarg.pop
1425
+ self.env.unextend
1426
+ self.in_def = in_def
1427
+
1428
+ self.in_single -= 1
1429
+
1430
+ # TODO: restore cur_arg ? what's cur_arg?
1431
+
1432
+ self.lexer.comments # we don't care about comments in the body
1433
+ }
1434
+ | kBREAK
1435
+ {
1436
+ (_, line), = val
1437
+ result = s(:break).line line
1438
+ }
1439
+ | kNEXT
1440
+ {
1441
+ (_, line), = val
1442
+ result = s(:next).line line
1443
+ }
1444
+ | kREDO
1445
+ {
1446
+ (_, line), = val
1447
+ result = s(:redo).line line
1448
+ }
1449
+ | kRETRY
1450
+ {
1451
+ (_, line), = val
1452
+ result = s(:retry).line line
1453
+ }
1454
+
1455
+ primary_value: primary
1456
+ {
1457
+ result = value_expr(val[0])
1458
+ }
1459
+
1460
+ # These are really stupid
1461
+ k_begin: kBEGIN
1462
+ k_if: kIF
1463
+ k_unless: kUNLESS
1464
+ k_while: kWHILE
1465
+ k_until: kUNTIL
1466
+ k_case: kCASE
1467
+ k_for: kFOR
1468
+ k_class: kCLASS
1469
+ k_module: kMODULE
1470
+ k_def: kDEF
1471
+ k_do: kDO
1472
+ k_do_block: kDO_BLOCK
1473
+ k_rescue: kRESCUE
1474
+ k_ensure: kENSURE
1475
+ k_when: kWHEN
1476
+ k_else: kELSE
1477
+ k_elsif: kELSIF
1478
+ k_end: kEND
1479
+ k_return: kRETURN
1480
+
1481
+ then: term
1482
+ | kTHEN
1483
+ | term kTHEN
1484
+
1485
+ do: term
1486
+ | kDO_COND
1487
+
1488
+ if_tail: opt_else
1489
+ | k_elsif expr_value then compstmt if_tail
1490
+ {
1491
+ (_, line), c, _, t, rest = val
1492
+
1493
+ result = s(:if, c, t, rest).line line
1494
+ }
1495
+
1496
+ opt_else: none
1497
+ | kELSE compstmt
1498
+ {
1499
+ result = val[1]
1500
+ }
1501
+
1502
+ for_var: lhs
1503
+ | mlhs
1504
+ {
1505
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1506
+ }
1507
+
1508
+ f_marg: f_norm_arg
1509
+ | tLPAREN f_margs rparen
1510
+ {
1511
+ result = val[1]
1512
+ }
1513
+
1514
+ f_marg_list: f_marg
1515
+ {
1516
+ sym, = val
1517
+
1518
+ result = s(:array, sym).line lexer.lineno
1519
+ }
1520
+ | f_marg_list tCOMMA f_marg
1521
+ {
1522
+ result = list_append val[0], val[2]
1523
+ }
1524
+
1525
+ f_margs: f_marg_list
1526
+ {
1527
+ args, = val
1528
+
1529
+ result = block_var args
1530
+ }
1531
+ | f_marg_list tCOMMA tSTAR f_norm_arg
1532
+ {
1533
+ args, _, _, splat = val
1534
+
1535
+ result = block_var args, "*#{splat}".to_sym
1536
+ }
1537
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1538
+ {
1539
+ args, _, _, splat, _, args2 = val
1540
+
1541
+ result = block_var args, "*#{splat}".to_sym, args2
1542
+ }
1543
+ | f_marg_list tCOMMA tSTAR
1544
+ {
1545
+ args, _, _ = val
1546
+
1547
+ result = block_var args, :*
1548
+ }
1549
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1550
+ {
1551
+ args, _, _, _, args2 = val
1552
+
1553
+ result = block_var args, :*, args2
1554
+ }
1555
+ | tSTAR f_norm_arg
1556
+ {
1557
+ _, splat = val
1558
+
1559
+ result = block_var :"*#{splat}"
1560
+ }
1561
+ | tSTAR f_norm_arg tCOMMA f_marg_list
1562
+ {
1563
+ _, splat, _, args = val
1564
+
1565
+ result = block_var :"*#{splat}", args
1566
+ }
1567
+ | tSTAR
1568
+ {
1569
+ result = block_var :*
1570
+ }
1571
+ | tSTAR tCOMMA f_marg_list
1572
+ {
1573
+ _, _, args = val
1574
+
1575
+ result = block_var :*, args
1576
+ }
1577
+
1578
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1579
+ {
1580
+ result = call_args val
1581
+ }
1582
+ | f_block_kwarg opt_f_block_arg
1583
+ {
1584
+ result = call_args val
1585
+ }
1586
+ | f_kwrest opt_f_block_arg
1587
+ {
1588
+ result = call_args val
1589
+ }
1590
+ | f_block_arg
1591
+ {
1592
+ line = lexer.lineno
1593
+ result = call_args val # TODO: push line down
1594
+ result.line line
1595
+ }
1596
+
1597
+ opt_block_args_tail: tCOMMA block_args_tail
1598
+ {
1599
+ result = args val
1600
+ }
1601
+ | none
1602
+
1603
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1604
+ {
1605
+ result = args val
1606
+ }
1607
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1608
+ {
1609
+ result = args val
1610
+ }
1611
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1612
+ {
1613
+ result = args val
1614
+ }
1615
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1616
+ {
1617
+ result = args val
1618
+ }
1619
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1620
+ {
1621
+ result = args val
1622
+ }
1623
+ | f_arg tCOMMA
1624
+ {
1625
+ result = args(val) << nil
1626
+ }
1627
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1628
+ {
1629
+ result = args val
1630
+ }
1631
+ | f_arg opt_block_args_tail
1632
+ {
1633
+ result = args val
1634
+ }
1635
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1636
+ {
1637
+ result = args val
1638
+ }
1639
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1640
+ {
1641
+ result = args val
1642
+ }
1643
+ | f_block_optarg opt_block_args_tail
1644
+ {
1645
+ result = args val
1646
+ }
1647
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1648
+ {
1649
+ result = args val
1650
+ }
1651
+ | f_rest_arg opt_block_args_tail
1652
+ {
1653
+ result = args val
1654
+ }
1655
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1656
+ {
1657
+ result = args val
1658
+ }
1659
+ | block_args_tail
1660
+ {
1661
+ result = args val
1662
+ }
1663
+
1664
+ opt_block_param: none { result = 0 }
1665
+ | block_param_def
1666
+ {
1667
+ self.lexer.command_start = true
1668
+ }
1669
+
1670
+ block_param_def: tPIPE opt_bv_decl tPIPE
1671
+ {
1672
+ # TODO: current_arg = 0
1673
+ result = args val
1674
+ }
1675
+ | tOROP
1676
+ {
1677
+ result = s(:args).line lexer.lineno
1678
+ }
1679
+ | tPIPE block_param opt_bv_decl tPIPE
1680
+ {
1681
+ # TODO: current_arg = 0
1682
+ result = args val
1683
+ }
1684
+
1685
+ opt_bv_decl: opt_nl
1686
+ | opt_nl tSEMI bv_decls opt_nl
1687
+ {
1688
+ result = args val
1689
+ }
1690
+
1691
+ bv_decls: bvar
1692
+ {
1693
+ result = args val
1694
+ }
1695
+ | bv_decls tCOMMA bvar
1696
+ {
1697
+ result = args val
1698
+ }
1699
+
1700
+ bvar: tIDENTIFIER
1701
+ {
1702
+ id, = val
1703
+ line = lexer.lineno
1704
+ result = s(:shadow, id.to_sym).line line
1705
+ }
1706
+ | f_bad_arg
1707
+
1708
+ lambda: {
1709
+ self.env.extend :dynamic
1710
+ result = [lexer.lineno, lexer.lpar_beg]
1711
+ lexer.paren_nest += 1
1712
+ lexer.lpar_beg = lexer.paren_nest
1713
+ }
1714
+ f_larglist
1715
+ {
1716
+ lexer.cmdarg.push false
1717
+ }
1718
+ lambda_body
1719
+ {
1720
+ (line, lpar), args, _cmdarg, body = val
1721
+ lexer.lpar_beg = lpar
1722
+
1723
+ lexer.cmdarg.pop
1724
+
1725
+ call = s(:lambda).line line
1726
+ result = new_iter call, args, body
1727
+ result.line = line
1728
+ self.env.unextend # TODO: dynapush & dynapop
1729
+ }
1730
+
1731
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1732
+ {
1733
+ result = args val
1734
+ }
1735
+ | f_args
1736
+ {
1737
+ result = val[0]
1738
+ result = 0 if result == s(:args)
1739
+ }
1740
+
1741
+ lambda_body: tLAMBEG compstmt tRCURLY
1742
+ {
1743
+ result = val[1]
1744
+ }
1745
+ | kDO_LAMBDA bodystmt kEND
1746
+ {
1747
+ result = val[1]
1748
+ }
1749
+
1750
+ do_block: k_do_block do_body kEND
1751
+ {
1752
+ (_, line), iter, _ = val
1753
+ result = iter.line line
1754
+ }
1755
+
1756
+ block_call: command do_block
1757
+ {
1758
+ # TODO:
1759
+ ## if (nd_type($1) == NODE_YIELD) {
1760
+ ## compile_error(PARSER_ARG "block given to yield");
1761
+
1762
+ syntax_error "Both block arg and actual block given." if
1763
+ val[0].block_pass?
1764
+
1765
+ val = invert_block_call val if inverted? val
1766
+
1767
+ cmd, blk = val
1768
+
1769
+ result = blk
1770
+ result.insert 1, cmd
1771
+ }
1772
+ | block_call call_op2 operation2 opt_paren_args
1773
+ {
1774
+ result = new_call val[0], val[2].to_sym, val[3]
1775
+ }
1776
+ | block_call call_op2 operation2 opt_paren_args brace_block
1777
+ {
1778
+ iter1, _, name, args, iter2 = val
1779
+
1780
+ call = new_call iter1, name.to_sym, args
1781
+ iter2.insert 1, call
1782
+
1783
+ result = iter2
1784
+ }
1785
+ | block_call call_op2 operation2 command_args do_block
1786
+ {
1787
+ iter1, _, name, args, iter2 = val
1788
+
1789
+ call = new_call iter1, name.to_sym, args
1790
+ iter2.insert 1, call
1791
+
1792
+ result = iter2
1793
+ }
1794
+
1795
+ method_call: fcall
1796
+ {
1797
+ result = self.lexer.lineno
1798
+ }
1799
+ paren_args
1800
+ {
1801
+ call, lineno, args = val
1802
+
1803
+ result = call.concat args.sexp_body if args
1804
+ result.line lineno
1805
+ }
1806
+ | primary_value call_op operation2 opt_paren_args
1807
+ {
1808
+ result = new_call val[0], val[2].to_sym, val[3], val[1]
1809
+ }
1810
+ | primary_value tCOLON2 operation2 paren_args
1811
+ {
1812
+ result = new_call val[0], val[2].to_sym, val[3]
1813
+ }
1814
+ | primary_value tCOLON2 operation3
1815
+ {
1816
+ result = new_call val[0], val[2].to_sym
1817
+ }
1818
+ | primary_value call_op paren_args
1819
+ {
1820
+ result = new_call val[0], :call, val[2], val[1]
1821
+ }
1822
+ | primary_value tCOLON2 paren_args
1823
+ {
1824
+ result = new_call val[0], :call, val[2]
1825
+ }
1826
+ | kSUPER paren_args
1827
+ {
1828
+ result = new_super val[1]
1829
+ }
1830
+ | kSUPER
1831
+ {
1832
+ result = s(:zsuper).line lexer.lineno
1833
+ }
1834
+ | primary_value tLBRACK2 opt_call_args rbracket
1835
+ {
1836
+ result = new_aref val
1837
+ }
1838
+
1839
+ brace_block: tLCURLY
1840
+ {
1841
+ self.env.extend :dynamic
1842
+ result = self.lexer.lineno
1843
+ }
1844
+ brace_body tRCURLY
1845
+ {
1846
+ _, line, body, _ = val
1847
+
1848
+ result = body
1849
+ result.line = line
1850
+
1851
+ self.env.unextend
1852
+ }
1853
+ | k_do
1854
+ {
1855
+ self.env.extend :dynamic
1856
+ result = self.lexer.lineno
1857
+ }
1858
+ do_body kEND
1859
+ {
1860
+ _, line, body, _ = val
1861
+
1862
+ result = body
1863
+ result.line = line
1864
+
1865
+ self.env.unextend
1866
+ }
1867
+
1868
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1869
+ { result = lexer.cmdarg.store(false) }
1870
+ opt_block_param compstmt
1871
+ {
1872
+ line, cmdarg, param, cmpstmt = val
1873
+
1874
+ result = new_brace_body param, cmpstmt, line
1875
+ self.env.unextend
1876
+ lexer.cmdarg.restore cmdarg
1877
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1878
+ }
1879
+
1880
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1881
+ { lexer.cmdarg.push false }
1882
+ opt_block_param
1883
+ bodystmt
1884
+ {
1885
+ line, _cmdarg, param, cmpstmt = val
1886
+
1887
+ result = new_do_body param, cmpstmt, line
1888
+ lexer.cmdarg.pop
1889
+ self.env.unextend
1890
+ }
1891
+
1892
+ case_body: k_when
1893
+ {
1894
+ result = self.lexer.lineno
1895
+ }
1896
+ args then compstmt cases
1897
+ {
1898
+ result = new_when(val[2], val[4])
1899
+ result.line = val[1]
1900
+ result << val[5] if val[5]
1901
+ }
1902
+
1903
+ cases: opt_else | case_body
1904
+
1905
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1906
+ {
1907
+ (_, line), klasses, var, _, body, rest = val
1908
+
1909
+ klasses ||= s(:array)
1910
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1911
+ klasses.line line
1912
+
1913
+ result = new_resbody(klasses, body)
1914
+ result << rest if rest # UGH, rewritten above
1915
+ }
1916
+ |
1917
+ {
1918
+ result = nil
1919
+ }
1920
+
1921
+ exc_list: arg_value
1922
+ {
1923
+ arg, = val
1924
+ result = s(:array, arg).line arg.line
1925
+ }
1926
+ | mrhs
1927
+ | none
1928
+
1929
+ exc_var: tASSOC lhs
1930
+ {
1931
+ result = val[1]
1932
+ }
1933
+ | none
1934
+
1935
+ opt_ensure: k_ensure compstmt
1936
+ {
1937
+ (_, line), body = val
1938
+
1939
+ result = body || s(:nil).line(line)
1940
+ }
1941
+ | none
1942
+
1943
+ literal: numeric
1944
+ {
1945
+ line = lexer.lineno
1946
+ result = s(:lit, val[0])
1947
+ result.line = line
1948
+ }
1949
+ | symbol
1950
+ {
1951
+ line = lexer.lineno
1952
+ result = s(:lit, val[0])
1953
+ result.line = line
1954
+ }
1955
+ | dsym
1956
+
1957
+ strings: string
1958
+ {
1959
+ str, = val
1960
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1961
+ result = str
1962
+ }
1963
+
1964
+ string: tCHAR
1965
+ {
1966
+ debug20 23, val, result
1967
+ }
1968
+ | string1
1969
+ | string string1
1970
+ {
1971
+ result = self.literal_concat val[0], val[1]
1972
+ }
1973
+
1974
+ string1: tSTRING_BEG string_contents tSTRING_END
1975
+ {
1976
+ _, str, (_, func) = val
1977
+
1978
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1979
+
1980
+ result = str
1981
+ }
1982
+ | tSTRING
1983
+ {
1984
+ result = new_string val
1985
+ }
1986
+
1987
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1988
+ {
1989
+ result = new_xstring val
1990
+ # TODO: dedent?!?! SERIOUSLY?!?
1991
+ }
1992
+
1993
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
1994
+ {
1995
+ result = new_regexp val
1996
+ }
1997
+
1998
+ words: tWORDS_BEG tSPACE tSTRING_END
1999
+ {
2000
+ result = s(:array).line lexer.lineno
2001
+ }
2002
+ | tWORDS_BEG word_list tSTRING_END
2003
+ {
2004
+ result = val[1]
2005
+ }
2006
+
2007
+ word_list: none
2008
+ {
2009
+ result = new_word_list
2010
+ }
2011
+ | word_list word tSPACE
2012
+ {
2013
+ result = val[0].dup << new_word_list_entry(val)
2014
+ }
2015
+
2016
+ word: string_content
2017
+ | word string_content
2018
+ {
2019
+ result = self.literal_concat val[0], val[1]
2020
+ }
2021
+
2022
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2023
+ {
2024
+ result = s(:array).line lexer.lineno
2025
+ }
2026
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2027
+ {
2028
+ _, line, list, _, = val
2029
+ list.line = line
2030
+ result = list
2031
+ }
2032
+
2033
+ symbol_list: none
2034
+ {
2035
+ result = new_symbol_list.line lexer.lineno
2036
+ }
2037
+ | symbol_list word tSPACE
2038
+ {
2039
+ list, * = val
2040
+ result = list.dup << new_symbol_list_entry(val)
2041
+ }
2042
+
2043
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2044
+ {
2045
+ result = s(:array).line lexer.lineno
2046
+ }
2047
+ | tQWORDS_BEG qword_list tSTRING_END
2048
+ {
2049
+ result = val[1]
2050
+ }
2051
+
2052
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2053
+ {
2054
+ result = s(:array).line lexer.lineno # FIX
2055
+ }
2056
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2057
+ {
2058
+ result = val[1]
2059
+ }
2060
+
2061
+ qword_list: none
2062
+ {
2063
+ result = new_qword_list
2064
+ }
2065
+ | qword_list tSTRING_CONTENT tSPACE
2066
+ {
2067
+ result = val[0].dup << new_qword_list_entry(val)
2068
+ }
2069
+
2070
+ qsym_list: none
2071
+ {
2072
+ result = new_qsym_list
2073
+ }
2074
+ | qsym_list tSTRING_CONTENT tSPACE
2075
+ {
2076
+ result = val[0].dup << new_qsym_list_entry(val)
2077
+ }
2078
+
2079
+ string_contents: none
2080
+ {
2081
+ result = s(:str, "").line lexer.lineno
2082
+ }
2083
+ | string_contents string_content
2084
+ {
2085
+ v1, v2 = val
2086
+ result = literal_concat v1, v2
2087
+ }
2088
+
2089
+ xstring_contents: none
2090
+ {
2091
+ result = nil
2092
+ }
2093
+ | xstring_contents string_content
2094
+ {
2095
+ v1, v2 = val
2096
+ result = literal_concat v1, v2
2097
+ }
2098
+
2099
+ regexp_contents: none
2100
+ {
2101
+ result = nil
2102
+ }
2103
+ | regexp_contents string_content
2104
+ {
2105
+ v1, v2 = val
2106
+ result = literal_concat v1, v2
2107
+ }
2108
+
2109
+ string_content: tSTRING_CONTENT
2110
+ {
2111
+ result = new_string val
2112
+ }
2113
+ | tSTRING_DVAR
2114
+ {
2115
+ result = lexer.lex_strterm
2116
+
2117
+ lexer.lex_strterm = nil
2118
+ lexer.lex_state = EXPR_BEG
2119
+ }
2120
+ string_dvar
2121
+ {
2122
+ _, strterm, str = val
2123
+ lexer.lex_strterm = strterm
2124
+ result = s(:evstr, str).line str.line
2125
+ }
2126
+ | tSTRING_DBEG
2127
+ {
2128
+ result = [lexer.lex_strterm,
2129
+ lexer.brace_nest,
2130
+ lexer.string_nest, # TODO: remove
2131
+ lexer.lex_state,
2132
+ lexer.lineno,
2133
+ ]
2134
+
2135
+ lexer.cmdarg.push false
2136
+ lexer.cond.push false
2137
+
2138
+ lexer.lex_strterm = nil
2139
+ lexer.brace_nest = 0
2140
+ lexer.string_nest = 0
2141
+
2142
+ lexer.lex_state = EXPR_BEG
2143
+ }
2144
+ compstmt
2145
+ tSTRING_DEND
2146
+ {
2147
+ _, memo, stmt, _ = val
2148
+
2149
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2150
+ # TODO: heredoc_indent
2151
+
2152
+ lexer.lex_strterm = lex_strterm
2153
+ lexer.brace_nest = brace_nest
2154
+ lexer.string_nest = string_nest
2155
+
2156
+ lexer.cmdarg.pop
2157
+ lexer.cond.pop
2158
+
2159
+ lexer.lex_state = oldlex_state
2160
+
2161
+ case stmt
2162
+ when Sexp then
2163
+ case stmt.sexp_type
2164
+ when :str, :dstr, :evstr then
2165
+ result = stmt
2166
+ else
2167
+ result = s(:evstr, stmt).line line
2168
+ end
2169
+ when nil then
2170
+ result = s(:evstr).line line
2171
+ else
2172
+ debug20 25
2173
+ raise "unknown string body: #{stmt.inspect}"
2174
+ end
2175
+ }
2176
+
2177
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2178
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2179
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2180
+ | backref
2181
+
2182
+ symbol: tSYMBEG sym
2183
+ {
2184
+ lexer.lex_state = EXPR_END
2185
+ result = val[1].to_sym
2186
+ }
2187
+ | tSYMBOL
2188
+ {
2189
+ result = val[0].to_sym
2190
+ }
2191
+
2192
+ sym: fname | tIVAR | tGVAR | tCVAR
2193
+
2194
+ dsym: tSYMBEG xstring_contents tSTRING_END
2195
+ {
2196
+ _, result, _ = val
2197
+
2198
+ lexer.lex_state = EXPR_END
2199
+
2200
+ result ||= s(:str, "").line lexer.lineno
2201
+
2202
+ case result.sexp_type
2203
+ when :dstr then
2204
+ result.sexp_type = :dsym
2205
+ when :str then
2206
+ result = s(:lit, result.last.to_sym).line result.line
2207
+ when :evstr then
2208
+ result = s(:dsym, "", result).line result.line
2209
+ else
2210
+ debug20 26, val, result
2211
+ end
2212
+ }
2213
+
2214
+ numeric: simple_numeric
2215
+ | tUMINUS_NUM simple_numeric
2216
+ {
2217
+ result = -val[1] # TODO: pt_testcase
2218
+ }
2219
+
2220
+ simple_numeric: tINTEGER
2221
+ | tFLOAT
2222
+ | tRATIONAL
2223
+ | tIMAGINARY
2224
+
2225
+ user_variable: tIDENTIFIER
2226
+ | tIVAR
2227
+ | tGVAR
2228
+ | tCONSTANT
2229
+ | tCVAR
2230
+
2231
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2232
+ | kSELF { result = s(:self).line lexer.lineno }
2233
+ | kTRUE { result = s(:true).line lexer.lineno }
2234
+ | kFALSE { result = s(:false).line lexer.lineno }
2235
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2236
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2237
+ | k__ENCODING__
2238
+ {
2239
+ l = lexer.lineno
2240
+ result =
2241
+ if defined? Encoding then
2242
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2243
+ else
2244
+ s(:str, "Unsupported!").line l
2245
+ end
2246
+ }
2247
+
2248
+ var_ref: user_variable
2249
+ {
2250
+ var = val[0]
2251
+ result = Sexp === var ? var : self.gettable(var)
2252
+ }
2253
+ | keyword_variable
2254
+ {
2255
+ var = val[0]
2256
+ result = Sexp === var ? var : self.gettable(var)
2257
+ }
2258
+
2259
+ var_lhs: user_variable
2260
+ {
2261
+ result = self.assignable val[0]
2262
+ }
2263
+ | keyword_variable
2264
+ {
2265
+ result = self.assignable val[0]
2266
+ debug20 29, val, result
2267
+ }
2268
+
2269
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2270
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2271
+
2272
+ superclass: tLT
2273
+ {
2274
+ lexer.lex_state = EXPR_BEG
2275
+ lexer.command_start = true
2276
+ }
2277
+ expr_value term
2278
+ {
2279
+ result = val[2]
2280
+ }
2281
+ | none
2282
+ {
2283
+ result = nil
2284
+ }
2285
+
2286
+ f_arglist: tLPAREN2 f_args rparen
2287
+ {
2288
+ result = val[1]
2289
+ self.lexer.lex_state = EXPR_BEG
2290
+ self.lexer.command_start = true
2291
+ }
2292
+ | {
2293
+ result = self.in_kwarg
2294
+ self.in_kwarg = true
2295
+ self.lexer.lex_state |= EXPR_LABEL
2296
+ }
2297
+ f_args term
2298
+ {
2299
+ kwarg, args, _ = val
2300
+
2301
+ self.in_kwarg = kwarg
2302
+ result = args
2303
+ lexer.lex_state = EXPR_BEG
2304
+ lexer.command_start = true
2305
+ }
2306
+
2307
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2308
+ {
2309
+ result = args val
2310
+ }
2311
+ | f_kwarg opt_f_block_arg
2312
+ {
2313
+ result = args val
2314
+ }
2315
+ | f_kwrest opt_f_block_arg
2316
+ {
2317
+ result = args val
2318
+ }
2319
+ | f_block_arg
2320
+
2321
+ opt_args_tail: tCOMMA args_tail
2322
+ {
2323
+ result = val[1]
2324
+ }
2325
+ |
2326
+ {
2327
+ result = nil
2328
+ }
2329
+
2330
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2331
+ {
2332
+ result = args val
2333
+ }
2334
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2335
+ {
2336
+ result = args val
2337
+ }
2338
+ | f_arg tCOMMA f_optarg opt_args_tail
2339
+ {
2340
+ result = args val
2341
+ }
2342
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2343
+ {
2344
+ result = args val
2345
+ }
2346
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2347
+ {
2348
+ result = args val
2349
+ }
2350
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2351
+ {
2352
+ result = args val
2353
+ }
2354
+ | f_arg opt_args_tail
2355
+ {
2356
+ result = args val
2357
+ }
2358
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2359
+ {
2360
+ result = args val
2361
+ }
2362
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2363
+ {
2364
+ result = args val
2365
+ }
2366
+ | f_optarg opt_args_tail
2367
+ {
2368
+ result = args val
2369
+ }
2370
+ | f_optarg tCOMMA f_arg opt_args_tail
2371
+ {
2372
+ result = args val
2373
+ }
2374
+ | f_rest_arg opt_args_tail
2375
+ {
2376
+ result = args val
2377
+ }
2378
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2379
+ {
2380
+ result = args val
2381
+ }
2382
+ | args_tail
2383
+ {
2384
+ result = args val
2385
+ }
2386
+ |
2387
+ {
2388
+ result = args val
2389
+ }
2390
+
2391
+ f_bad_arg: tCONSTANT
2392
+ {
2393
+ yyerror "formal argument cannot be a constant"
2394
+ }
2395
+ | tIVAR
2396
+ {
2397
+ yyerror "formal argument cannot be an instance variable"
2398
+ }
2399
+ | tGVAR
2400
+ {
2401
+ yyerror "formal argument cannot be a global variable"
2402
+ }
2403
+ | tCVAR
2404
+ {
2405
+ yyerror "formal argument cannot be a class variable"
2406
+ }
2407
+
2408
+ f_norm_arg: f_bad_arg
2409
+ | tIDENTIFIER
2410
+ {
2411
+ identifier = val[0].to_sym
2412
+ self.env[identifier] = :lvar
2413
+
2414
+ result = identifier
2415
+ }
2416
+
2417
+ f_arg_asgn: f_norm_arg
2418
+
2419
+ f_arg_item: f_arg_asgn
2420
+ | tLPAREN f_margs rparen
2421
+ {
2422
+ result = val[1]
2423
+ }
2424
+
2425
+ f_arg: f_arg_item
2426
+ {
2427
+ arg, = val
2428
+
2429
+ case arg
2430
+ when Symbol then
2431
+ result = s(:args, arg).line lexer.lineno
2432
+ when Sexp then
2433
+ result = arg
2434
+ else
2435
+ debug20 32
2436
+ raise "Unknown f_arg type: #{val.inspect}"
2437
+ end
2438
+ }
2439
+ | f_arg tCOMMA f_arg_item
2440
+ {
2441
+ list, _, item = val
2442
+
2443
+ if list.sexp_type == :args then
2444
+ result = list
2445
+ else
2446
+ result = s(:args, list).line list.line
2447
+ end
2448
+
2449
+ result << item
2450
+ }
2451
+
2452
+ f_label: tLABEL
2453
+
2454
+ f_kw: f_label arg_value
2455
+ {
2456
+ # TODO: new_kw_arg
2457
+ (label, line), arg = val
2458
+
2459
+ identifier = label.to_sym
2460
+ self.env[identifier] = :lvar
2461
+
2462
+ kwarg = s(:kwarg, identifier, arg).line line
2463
+ result = s(:array, kwarg).line line
2464
+ }
2465
+ | f_label
2466
+ {
2467
+ (label, line), = val
2468
+
2469
+ id = label.to_sym
2470
+ self.env[id] = :lvar
2471
+
2472
+ result = s(:array, s(:kwarg, id).line(line)).line line
2473
+ }
2474
+
2475
+ f_block_kw: f_label primary_value
2476
+ {
2477
+ # TODO: new_kw_arg
2478
+ (label, line), expr = val
2479
+ id = label.to_sym
2480
+ self.env[id] = :lvar
2481
+
2482
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2483
+ }
2484
+ | f_label
2485
+ {
2486
+ # TODO: new_kw_arg
2487
+ (label, line), = val
2488
+ id = label.to_sym
2489
+ self.env[id] = :lvar
2490
+
2491
+ result = s(:array, s(:kwarg, id).line(line)).line line
2492
+ }
2493
+
2494
+ f_block_kwarg: f_block_kw
2495
+ | f_block_kwarg tCOMMA f_block_kw
2496
+ {
2497
+ list, _, item = val
2498
+ result = list << item.last
2499
+ }
2500
+
2501
+ f_kwarg: f_kw
2502
+ | f_kwarg tCOMMA f_kw
2503
+ {
2504
+ result = args val
2505
+ }
2506
+
2507
+ kwrest_mark: tPOW
2508
+ | tDSTAR
2509
+
2510
+ f_kwrest: kwrest_mark tIDENTIFIER
2511
+ {
2512
+ name = val[1].to_sym
2513
+ self.assignable name
2514
+ result = :"**#{name}"
2515
+ }
2516
+ | kwrest_mark
2517
+ {
2518
+ result = :"**"
2519
+ }
2520
+
2521
+ f_opt: f_arg_asgn tEQL arg_value
2522
+ {
2523
+ result = self.assignable val[0], val[2]
2524
+ # TODO: detect duplicate names
2525
+ }
2526
+
2527
+ f_block_opt: f_arg_asgn tEQL primary_value
2528
+ {
2529
+ result = self.assignable val[0], val[2]
2530
+ }
2531
+
2532
+ f_block_optarg: f_block_opt
2533
+ {
2534
+ optblk, = val
2535
+ result = s(:block, optblk).line optblk.line
2536
+ }
2537
+ | f_block_optarg tCOMMA f_block_opt
2538
+ {
2539
+ optarg, _, optblk = val
2540
+ result = optarg
2541
+ result << optblk
2542
+ }
2543
+
2544
+ f_optarg: f_opt
2545
+ {
2546
+ opt, = val
2547
+ result = s(:block, opt).line opt.line
2548
+ }
2549
+ | f_optarg tCOMMA f_opt
2550
+ {
2551
+ result = self.block_append val[0], val[2]
2552
+ }
2553
+
2554
+ restarg_mark: tSTAR2 | tSTAR
2555
+
2556
+ f_rest_arg: restarg_mark tIDENTIFIER
2557
+ {
2558
+ # TODO: differs from parse.y - needs tests
2559
+ name = val[1].to_sym
2560
+ self.assignable name
2561
+ result = :"*#{name}"
2562
+ }
2563
+ | restarg_mark
2564
+ {
2565
+ name = :"*"
2566
+ self.env[name] = :lvar
2567
+ result = name
2568
+ }
2569
+
2570
+ blkarg_mark: tAMPER2 | tAMPER
2571
+
2572
+ f_block_arg: blkarg_mark tIDENTIFIER
2573
+ {
2574
+ identifier = val[1].to_sym
2575
+
2576
+ self.env[identifier] = :lvar
2577
+ result = "&#{identifier}".to_sym
2578
+ }
2579
+
2580
+ opt_f_block_arg: tCOMMA f_block_arg
2581
+ {
2582
+ result = val[1]
2583
+ }
2584
+ |
2585
+ {
2586
+ result = nil
2587
+ }
2588
+
2589
+ singleton: var_ref
2590
+ | tLPAREN2
2591
+ {
2592
+ lexer.lex_state = EXPR_BEG
2593
+ }
2594
+ expr rparen
2595
+ {
2596
+ result = val[2]
2597
+ yyerror "Can't define single method for literals." if
2598
+ result.sexp_type == :lit
2599
+ }
2600
+
2601
+ assoc_list: none
2602
+ {
2603
+ result = s(:array).line lexer.lineno
2604
+ }
2605
+ | assocs trailer
2606
+
2607
+ assocs: assoc
2608
+ | assocs tCOMMA assoc
2609
+ {
2610
+ list = val[0].dup
2611
+ more = val[2].sexp_body
2612
+ list.push(*more) unless more.empty?
2613
+ result = list
2614
+ result.sexp_type = :hash
2615
+ }
2616
+
2617
+ assoc: arg_value tASSOC arg_value
2618
+ {
2619
+ v1, _, v2 = val
2620
+ result = s(:array, v1, v2).line v1.line
2621
+ }
2622
+ | tLABEL arg_value
2623
+ {
2624
+ (label, line), arg = val
2625
+
2626
+ lit = s(:lit, label.to_sym).line line
2627
+ result = s(:array, lit, arg).line line
2628
+ }
2629
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2630
+ {
2631
+ _, sym, _, value = val
2632
+ sym.sexp_type = :dsym
2633
+ result = s(:array, sym, value).line sym.line
2634
+ }
2635
+ | tDSTAR arg_value
2636
+ {
2637
+ _, arg = val
2638
+ line = arg.line
2639
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2640
+ }
2641
+
2642
+ operation: tIDENTIFIER | tCONSTANT | tFID
2643
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2644
+ operation3: tIDENTIFIER | tFID | op
2645
+ dot_or_colon: tDOT | tCOLON2
2646
+ call_op: tDOT
2647
+ | tLONELY # TODO: rename tANDDOT?
2648
+
2649
+ call_op2: call_op
2650
+ | tCOLON2
2651
+
2652
+ opt_terms: | terms
2653
+ opt_nl: | tNL
2654
+ rparen: opt_nl tRPAREN
2655
+ rbracket: opt_nl tRBRACK
2656
+ trailer: | tNL | tCOMMA
2657
+
2658
+ term: tSEMI { yyerrok }
2659
+ | tNL
2660
+
2661
+ terms: term
2662
+ | terms tSEMI { yyerrok }
2663
+
2664
+ none: { result = nil; }
2665
+ end
2666
+
2667
+ ---- inner
2668
+
2669
+ require "ruby_lexer"
2670
+ require "ruby_parser_extras"
2671
+ include RubyLexer::State::Values
2672
+
2673
+ # :stopdoc:
2674
+
2675
+ # Local Variables: **
2676
+ # racc-token-length-max:14 **
2677
+ # End: **