ruby_parser 3.14.2 → 3.17.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,2715 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby27Parser
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
+ | tLPAREN2 args tCOMMA args_forward rparen
1013
+ {
1014
+ yyerror "Unexpected ..." unless
1015
+ self.lexer.is_local_id(:"*") &&
1016
+ self.lexer.is_local_id(:"**") &&
1017
+ self.lexer.is_local_id(:"&")
1018
+
1019
+ result = call_args val
1020
+ }
1021
+ | tLPAREN2 args_forward rparen
1022
+ {
1023
+ yyerror "Unexpected ..." unless
1024
+ self.lexer.is_local_id(:"*") &&
1025
+ self.lexer.is_local_id(:"**") &&
1026
+ self.lexer.is_local_id(:"&")
1027
+
1028
+ result = call_args val
1029
+ }
1030
+
1031
+ opt_paren_args: none
1032
+ | paren_args
1033
+
1034
+ opt_call_args: none
1035
+ | call_args
1036
+ | args tCOMMA
1037
+ {
1038
+ result = args val
1039
+ }
1040
+ | args tCOMMA assocs tCOMMA
1041
+ {
1042
+ result = args [val[0], array_to_hash(val[2])]
1043
+ }
1044
+ | assocs tCOMMA
1045
+ {
1046
+ result = args [array_to_hash(val[0])]
1047
+ }
1048
+
1049
+ call_args: command
1050
+ {
1051
+ warning "parenthesize argument(s) for future version"
1052
+ result = call_args val
1053
+ }
1054
+ | args opt_block_arg
1055
+ {
1056
+ result = call_args val
1057
+ }
1058
+ | assocs opt_block_arg
1059
+ {
1060
+ result = call_args [array_to_hash(val[0]), val[1]]
1061
+ }
1062
+ | args tCOMMA assocs opt_block_arg
1063
+ {
1064
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1065
+ }
1066
+ | block_arg
1067
+ {
1068
+ result = call_args val
1069
+ }
1070
+
1071
+ command_args: {
1072
+ # parse26.y line 2200
1073
+
1074
+ # If call_args starts with a open paren '(' or
1075
+ # '[', look-ahead reading of the letters calls
1076
+ # CMDARG_PUSH(0), but the push must be done
1077
+ # after CMDARG_PUSH(1). So this code makes them
1078
+ # consistent by first cancelling the premature
1079
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1080
+ # finally redoing CMDARG_PUSH(0).
1081
+
1082
+ result = yychar = self.last_token_type.first
1083
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1084
+ lexer.cmdarg.pop if lookahead
1085
+ lexer.cmdarg.push true
1086
+ lexer.cmdarg.push false if lookahead
1087
+ }
1088
+ call_args
1089
+ {
1090
+ yychar, args = val
1091
+
1092
+ # call_args can be followed by tLBRACE_ARG (that
1093
+ # does CMDARG_PUSH(0) in the lexer) but the push
1094
+ # must be done after CMDARG_POP() in the parser.
1095
+ # So this code does CMDARG_POP() to pop 0 pushed
1096
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1097
+ # by command_args, and CMDARG_PUSH(0) to restore
1098
+ # back the flag set by tLBRACE_ARG.
1099
+
1100
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1101
+ lexer.cmdarg.pop if lookahead
1102
+ lexer.cmdarg.pop
1103
+ lexer.cmdarg.push false if lookahead
1104
+ result = args
1105
+ }
1106
+
1107
+ block_arg: tAMPER arg_value
1108
+ {
1109
+ _, arg = val
1110
+ result = s(:block_pass, arg).line arg.line
1111
+ }
1112
+
1113
+ opt_block_arg: tCOMMA block_arg
1114
+ {
1115
+ result = val[1]
1116
+ }
1117
+ | none
1118
+
1119
+ args: arg_value
1120
+ {
1121
+ arg, = val
1122
+ lineno = arg.line || lexer.lineno # HACK
1123
+
1124
+ result = s(:array, arg).line lineno
1125
+ }
1126
+ | tSTAR arg_value
1127
+ {
1128
+ _, arg = val
1129
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1130
+ }
1131
+ | args tCOMMA arg_value
1132
+ {
1133
+ args, _, id = val
1134
+ result = self.list_append args, id
1135
+ }
1136
+ | args tCOMMA tSTAR arg_value
1137
+ {
1138
+ # TODO: the line number from tSTAR has been dropped
1139
+ args, _, _, id = val
1140
+ line = lexer.lineno
1141
+ result = self.list_append args, s(:splat, id).line(line)
1142
+ }
1143
+
1144
+ mrhs_arg: mrhs
1145
+ {
1146
+ result = new_masgn_arg val[0]
1147
+ }
1148
+ | arg_value
1149
+ {
1150
+ result = new_masgn_arg val[0], :wrap
1151
+ }
1152
+
1153
+ mrhs: args tCOMMA arg_value
1154
+ {
1155
+ result = val[0] << val[2]
1156
+ }
1157
+ | args tCOMMA tSTAR arg_value
1158
+ {
1159
+ # TODO: make all tXXXX terminals include lexer.lineno
1160
+ arg, _, _, splat = val
1161
+ result = self.arg_concat arg, splat
1162
+ }
1163
+ | tSTAR arg_value
1164
+ {
1165
+ _, arg = val
1166
+ result = s(:splat, arg).line arg.line
1167
+ }
1168
+
1169
+ primary: literal
1170
+ | strings
1171
+ | xstring
1172
+ | regexp
1173
+ | words
1174
+ | qwords
1175
+ | symbols
1176
+ | qsymbols
1177
+ | var_ref
1178
+ | backref
1179
+ | tFID
1180
+ {
1181
+ msg, = val
1182
+ result = new_call nil, msg.to_sym
1183
+ }
1184
+ | k_begin
1185
+ {
1186
+ lexer.cmdarg.push false
1187
+ result = self.lexer.lineno
1188
+ }
1189
+ bodystmt k_end
1190
+ {
1191
+ lexer.cmdarg.pop
1192
+ result = new_begin val
1193
+ }
1194
+ | tLPAREN_ARG
1195
+ {
1196
+ lexer.lex_state = EXPR_ENDARG
1197
+ result = lexer.lineno
1198
+ }
1199
+ rparen
1200
+ {
1201
+ _, line, _ = val
1202
+ result = s(:begin).line line
1203
+ }
1204
+ | tLPAREN_ARG
1205
+ stmt
1206
+ {
1207
+ lexer.lex_state = EXPR_ENDARG
1208
+ }
1209
+ rparen
1210
+ {
1211
+ _, stmt, _, _, = val
1212
+ # warning "(...) interpreted as grouped expression"
1213
+ result = stmt
1214
+ }
1215
+ | tLPAREN compstmt tRPAREN
1216
+ {
1217
+ _, stmt, _ = val
1218
+ result = stmt
1219
+ result ||= s(:nil).line lexer.lineno
1220
+ result.paren = true
1221
+ }
1222
+ | primary_value tCOLON2 tCONSTANT
1223
+ {
1224
+ expr, _, id = val
1225
+
1226
+ result = s(:colon2, expr, id.to_sym).line expr.line
1227
+ }
1228
+ | tCOLON3 tCONSTANT
1229
+ {
1230
+ _, id = val
1231
+
1232
+ result = s(:colon3, id.to_sym).line lexer.lineno
1233
+ }
1234
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1235
+ {
1236
+ _, line, args, _ = val
1237
+ result = args || s(:array)
1238
+ result.sexp_type = :array # aref_args is :args
1239
+ result.line line
1240
+ }
1241
+ | tLBRACE
1242
+ {
1243
+ result = self.lexer.lineno
1244
+ }
1245
+ assoc_list tRCURLY
1246
+ {
1247
+ result = new_hash val
1248
+ }
1249
+ | k_return
1250
+ {
1251
+ (_, line), = val
1252
+ result = s(:return).line line
1253
+ }
1254
+ | kYIELD tLPAREN2 call_args rparen
1255
+ {
1256
+ result = new_yield val[2]
1257
+ }
1258
+ | kYIELD tLPAREN2 rparen
1259
+ {
1260
+ result = new_yield
1261
+ }
1262
+ | kYIELD
1263
+ {
1264
+ result = new_yield
1265
+ }
1266
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1267
+ {
1268
+ (_, line), _, _, arg, _ = val
1269
+
1270
+ result = s(:defined, arg).line line
1271
+ }
1272
+ | kNOT tLPAREN2 expr rparen
1273
+ {
1274
+ _, _, lhs, _ = val
1275
+ result = new_call lhs, :"!"
1276
+ }
1277
+ | kNOT tLPAREN2 rparen
1278
+ {
1279
+ debug20 14, val, result
1280
+ }
1281
+ | fcall brace_block
1282
+ {
1283
+ call, iter = val
1284
+
1285
+ iter.insert 1, call
1286
+ result = iter
1287
+ # FIX: probably not: call.line = iter.line
1288
+ }
1289
+ | method_call
1290
+ | method_call brace_block
1291
+ {
1292
+ call, iter = val[0], val[1]
1293
+ block_dup_check call, iter
1294
+ iter.insert 1, call # FIX
1295
+ result = iter
1296
+ }
1297
+ | tLAMBDA lambda
1298
+ {
1299
+ result = val[1] # TODO: fix lineno
1300
+ }
1301
+ | k_if expr_value then compstmt if_tail k_end
1302
+ {
1303
+ _, c, _, t, f, _ = val
1304
+ result = new_if c, t, f
1305
+ }
1306
+ | k_unless expr_value then compstmt opt_else k_end
1307
+ {
1308
+ _, c, _, t, f, _ = val
1309
+ result = new_if c, f, t
1310
+ }
1311
+ | k_while expr_value_do compstmt k_end
1312
+ {
1313
+ _, cond, body, _ = val
1314
+ result = new_while body, cond, true
1315
+ }
1316
+ | k_until expr_value_do compstmt k_end
1317
+ {
1318
+ _, cond, body, _ = val
1319
+ result = new_until body, cond, true
1320
+ }
1321
+ | k_case expr_value opt_terms case_body k_end
1322
+ {
1323
+ (_, line), expr, _, body, _ = val
1324
+ result = new_case expr, body, line
1325
+ }
1326
+ | k_case opt_terms case_body k_end
1327
+ {
1328
+ (_, line), _, body, _ = val
1329
+ result = new_case nil, body, line
1330
+ }
1331
+ | k_for for_var kIN expr_value_do compstmt k_end
1332
+ {
1333
+ _, var, _, iter, body, _ = val
1334
+ result = new_for iter, var, body
1335
+ }
1336
+ | k_class
1337
+ {
1338
+ result = self.lexer.lineno
1339
+ }
1340
+ cpath superclass
1341
+ {
1342
+ self.comments.push self.lexer.comments
1343
+ if (self.in_def || self.in_single > 0) then
1344
+ yyerror "class definition in method body"
1345
+ end
1346
+ self.env.extend
1347
+ }
1348
+ bodystmt k_end
1349
+ {
1350
+ result = new_class val
1351
+ self.env.unextend
1352
+ self.lexer.comments # we don't care about comments in the body
1353
+ }
1354
+ | k_class tLSHFT
1355
+ {
1356
+ result = self.lexer.lineno
1357
+ }
1358
+ expr
1359
+ {
1360
+ result = self.in_def
1361
+ self.in_def = false
1362
+ }
1363
+ term
1364
+ {
1365
+ result = self.in_single
1366
+ self.in_single = 0
1367
+ self.env.extend
1368
+ }
1369
+ bodystmt k_end
1370
+ {
1371
+ result = new_sclass val
1372
+ self.env.unextend
1373
+ self.lexer.comments # we don't care about comments in the body
1374
+ }
1375
+ | k_module
1376
+ {
1377
+ result = self.lexer.lineno
1378
+ }
1379
+ cpath
1380
+ {
1381
+ self.comments.push self.lexer.comments
1382
+ yyerror "module definition in method body" if
1383
+ self.in_def or self.in_single > 0
1384
+
1385
+ self.env.extend
1386
+ }
1387
+ bodystmt k_end
1388
+ {
1389
+ result = new_module val
1390
+ self.env.unextend
1391
+ self.lexer.comments # we don't care about comments in the body
1392
+ }
1393
+ | k_def fname
1394
+ {
1395
+ result = self.in_def
1396
+
1397
+ self.in_def = true # group = local_push
1398
+ self.env.extend
1399
+ lexer.cmdarg.push false
1400
+ lexer.cond.push false
1401
+
1402
+ self.comments.push self.lexer.comments
1403
+ }
1404
+ f_arglist bodystmt { result = lexer.lineno } k_end
1405
+ {
1406
+ in_def = val[2]
1407
+
1408
+ result = new_defn val
1409
+
1410
+ lexer.cond.pop # group = local_pop
1411
+ lexer.cmdarg.pop
1412
+ self.env.unextend
1413
+ self.in_def = in_def
1414
+
1415
+ self.lexer.comments # we don't care about comments in the body
1416
+ }
1417
+ | k_def singleton dot_or_colon
1418
+ {
1419
+ lexer.lex_state = EXPR_FNAME
1420
+ }
1421
+ fname
1422
+ {
1423
+ result = [self.in_def, lexer.lineno]
1424
+
1425
+ self.in_single += 1 # TODO: remove?
1426
+
1427
+ self.in_def = true # local_push
1428
+ self.env.extend
1429
+ lexer.cmdarg.push false
1430
+ lexer.cond.push false
1431
+
1432
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1433
+ self.comments.push self.lexer.comments
1434
+ }
1435
+ f_arglist bodystmt k_end
1436
+ {
1437
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1438
+
1439
+ result = new_defs val
1440
+
1441
+ lexer.cond.pop # group = local_pop
1442
+ lexer.cmdarg.pop
1443
+ self.env.unextend
1444
+ self.in_def = in_def
1445
+
1446
+ self.in_single -= 1
1447
+
1448
+ # TODO: restore cur_arg ? what's cur_arg?
1449
+
1450
+ self.lexer.comments # we don't care about comments in the body
1451
+ }
1452
+ | kBREAK
1453
+ {
1454
+ (_, line), = val
1455
+ result = s(:break).line line
1456
+ }
1457
+ | kNEXT
1458
+ {
1459
+ (_, line), = val
1460
+ result = s(:next).line line
1461
+ }
1462
+ | kREDO
1463
+ {
1464
+ (_, line), = val
1465
+ result = s(:redo).line line
1466
+ }
1467
+ | kRETRY
1468
+ {
1469
+ (_, line), = val
1470
+ result = s(:retry).line line
1471
+ }
1472
+
1473
+ primary_value: primary
1474
+ {
1475
+ result = value_expr(val[0])
1476
+ }
1477
+
1478
+ # These are really stupid
1479
+ k_begin: kBEGIN
1480
+ k_if: kIF
1481
+ k_unless: kUNLESS
1482
+ k_while: kWHILE
1483
+ k_until: kUNTIL
1484
+ k_case: kCASE
1485
+ k_for: kFOR
1486
+ k_class: kCLASS
1487
+ k_module: kMODULE
1488
+ k_def: kDEF
1489
+ k_do: kDO
1490
+ k_do_block: kDO_BLOCK
1491
+ k_rescue: kRESCUE
1492
+ k_ensure: kENSURE
1493
+ k_when: kWHEN
1494
+ k_else: kELSE
1495
+ k_elsif: kELSIF
1496
+ k_end: kEND
1497
+ k_return: kRETURN
1498
+
1499
+ then: term
1500
+ | kTHEN
1501
+ | term kTHEN
1502
+
1503
+ do: term
1504
+ | kDO_COND
1505
+
1506
+ if_tail: opt_else
1507
+ | k_elsif expr_value then compstmt if_tail
1508
+ {
1509
+ (_, line), c, _, t, rest = val
1510
+
1511
+ result = s(:if, c, t, rest).line line
1512
+ }
1513
+
1514
+ opt_else: none
1515
+ | kELSE compstmt
1516
+ {
1517
+ result = val[1]
1518
+ }
1519
+
1520
+ for_var: lhs
1521
+ | mlhs
1522
+ {
1523
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1524
+ }
1525
+
1526
+ f_marg: f_norm_arg
1527
+ | tLPAREN f_margs rparen
1528
+ {
1529
+ result = val[1]
1530
+ }
1531
+
1532
+ f_marg_list: f_marg
1533
+ {
1534
+ sym, = val
1535
+
1536
+ result = s(:array, sym).line lexer.lineno
1537
+ }
1538
+ | f_marg_list tCOMMA f_marg
1539
+ {
1540
+ result = list_append val[0], val[2]
1541
+ }
1542
+
1543
+ f_margs: f_marg_list
1544
+ {
1545
+ args, = val
1546
+
1547
+ result = block_var args
1548
+ }
1549
+ | f_marg_list tCOMMA tSTAR f_norm_arg
1550
+ {
1551
+ args, _, _, splat = val
1552
+
1553
+ result = block_var args, "*#{splat}".to_sym
1554
+ }
1555
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1556
+ {
1557
+ args, _, _, splat, _, args2 = val
1558
+
1559
+ result = block_var args, "*#{splat}".to_sym, args2
1560
+ }
1561
+ | f_marg_list tCOMMA tSTAR
1562
+ {
1563
+ args, _, _ = val
1564
+
1565
+ result = block_var args, :*
1566
+ }
1567
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1568
+ {
1569
+ args, _, _, _, args2 = val
1570
+
1571
+ result = block_var args, :*, args2
1572
+ }
1573
+ | tSTAR f_norm_arg
1574
+ {
1575
+ _, splat = val
1576
+
1577
+ result = block_var :"*#{splat}"
1578
+ }
1579
+ | tSTAR f_norm_arg tCOMMA f_marg_list
1580
+ {
1581
+ _, splat, _, args = val
1582
+
1583
+ result = block_var :"*#{splat}", args
1584
+ }
1585
+ | tSTAR
1586
+ {
1587
+ result = block_var :*
1588
+ }
1589
+ | tSTAR tCOMMA f_marg_list
1590
+ {
1591
+ _, _, args = val
1592
+
1593
+ result = block_var :*, args
1594
+ }
1595
+
1596
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1597
+ {
1598
+ result = call_args val
1599
+ }
1600
+ | f_block_kwarg opt_f_block_arg
1601
+ {
1602
+ result = call_args val
1603
+ }
1604
+ | f_kwrest opt_f_block_arg
1605
+ {
1606
+ result = call_args val
1607
+ }
1608
+ | f_block_arg
1609
+ {
1610
+ line = lexer.lineno
1611
+ result = call_args val # TODO: push line down
1612
+ result.line line
1613
+ }
1614
+
1615
+ opt_block_args_tail: tCOMMA block_args_tail
1616
+ {
1617
+ result = args val
1618
+ }
1619
+ | none
1620
+
1621
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1622
+ {
1623
+ result = args val
1624
+ }
1625
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1626
+ {
1627
+ result = args val
1628
+ }
1629
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1630
+ {
1631
+ result = args val
1632
+ }
1633
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1634
+ {
1635
+ result = args val
1636
+ }
1637
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1638
+ {
1639
+ result = args val
1640
+ }
1641
+ | f_arg tCOMMA
1642
+ {
1643
+ result = args(val) << nil
1644
+ }
1645
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1646
+ {
1647
+ result = args val
1648
+ }
1649
+ | f_arg opt_block_args_tail
1650
+ {
1651
+ result = args val
1652
+ }
1653
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1654
+ {
1655
+ result = args val
1656
+ }
1657
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1658
+ {
1659
+ result = args val
1660
+ }
1661
+ | f_block_optarg opt_block_args_tail
1662
+ {
1663
+ result = args val
1664
+ }
1665
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1666
+ {
1667
+ result = args val
1668
+ }
1669
+ | f_rest_arg opt_block_args_tail
1670
+ {
1671
+ result = args val
1672
+ }
1673
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1674
+ {
1675
+ result = args val
1676
+ }
1677
+ | block_args_tail
1678
+ {
1679
+ result = args val
1680
+ }
1681
+
1682
+ opt_block_param: none { result = 0 }
1683
+ | block_param_def
1684
+ {
1685
+ self.lexer.command_start = true
1686
+ }
1687
+
1688
+ block_param_def: tPIPE opt_bv_decl tPIPE
1689
+ {
1690
+ # TODO: current_arg = 0
1691
+ result = args val
1692
+ }
1693
+ | tOROP
1694
+ {
1695
+ result = s(:args).line lexer.lineno
1696
+ }
1697
+ | tPIPE block_param opt_bv_decl tPIPE
1698
+ {
1699
+ # TODO: current_arg = 0
1700
+ result = args val
1701
+ }
1702
+
1703
+ opt_bv_decl: opt_nl
1704
+ | opt_nl tSEMI bv_decls opt_nl
1705
+ {
1706
+ result = args val
1707
+ }
1708
+
1709
+ bv_decls: bvar
1710
+ {
1711
+ result = args val
1712
+ }
1713
+ | bv_decls tCOMMA bvar
1714
+ {
1715
+ result = args val
1716
+ }
1717
+
1718
+ bvar: tIDENTIFIER
1719
+ {
1720
+ id, = val
1721
+ line = lexer.lineno
1722
+ result = s(:shadow, id.to_sym).line line
1723
+ }
1724
+ | f_bad_arg
1725
+
1726
+ lambda: {
1727
+ self.env.extend :dynamic
1728
+ result = [lexer.lineno, lexer.lpar_beg]
1729
+ lexer.paren_nest += 1
1730
+ lexer.lpar_beg = lexer.paren_nest
1731
+ }
1732
+ f_larglist
1733
+ {
1734
+ lexer.cmdarg.push false
1735
+ }
1736
+ lambda_body
1737
+ {
1738
+ (line, lpar), args, _cmdarg, body = val
1739
+ lexer.lpar_beg = lpar
1740
+
1741
+ lexer.cmdarg.pop
1742
+
1743
+ call = s(:lambda).line line
1744
+ result = new_iter call, args, body
1745
+ result.line = line
1746
+ self.env.unextend # TODO: dynapush & dynapop
1747
+ }
1748
+
1749
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1750
+ {
1751
+ result = args val
1752
+ }
1753
+ | f_args
1754
+ {
1755
+ result = val[0]
1756
+ result = 0 if result == s(:args)
1757
+ }
1758
+
1759
+ lambda_body: tLAMBEG compstmt tRCURLY
1760
+ {
1761
+ result = val[1]
1762
+ }
1763
+ | kDO_LAMBDA bodystmt kEND
1764
+ {
1765
+ result = val[1]
1766
+ }
1767
+
1768
+ do_block: k_do_block do_body kEND
1769
+ {
1770
+ (_, line), iter, _ = val
1771
+ result = iter.line line
1772
+ }
1773
+
1774
+ block_call: command do_block
1775
+ {
1776
+ # TODO:
1777
+ ## if (nd_type($1) == NODE_YIELD) {
1778
+ ## compile_error(PARSER_ARG "block given to yield");
1779
+
1780
+ syntax_error "Both block arg and actual block given." if
1781
+ val[0].block_pass?
1782
+
1783
+ val = invert_block_call val if inverted? val
1784
+
1785
+ cmd, blk = val
1786
+
1787
+ result = blk
1788
+ result.insert 1, cmd
1789
+ }
1790
+ | block_call call_op2 operation2 opt_paren_args
1791
+ {
1792
+ result = new_call val[0], val[2].to_sym, val[3]
1793
+ }
1794
+ | block_call call_op2 operation2 opt_paren_args brace_block
1795
+ {
1796
+ iter1, _, name, args, iter2 = val
1797
+
1798
+ call = new_call iter1, name.to_sym, args
1799
+ iter2.insert 1, call
1800
+
1801
+ result = iter2
1802
+ }
1803
+ | block_call call_op2 operation2 command_args do_block
1804
+ {
1805
+ iter1, _, name, args, iter2 = val
1806
+
1807
+ call = new_call iter1, name.to_sym, args
1808
+ iter2.insert 1, call
1809
+
1810
+ result = iter2
1811
+ }
1812
+
1813
+ method_call: fcall
1814
+ {
1815
+ result = self.lexer.lineno
1816
+ }
1817
+ paren_args
1818
+ {
1819
+ call, lineno, args = val
1820
+
1821
+ result = call.concat args.sexp_body if args
1822
+ result.line lineno
1823
+ }
1824
+ | primary_value call_op operation2 opt_paren_args
1825
+ {
1826
+ result = new_call val[0], val[2].to_sym, val[3], val[1]
1827
+ }
1828
+ | primary_value tCOLON2 operation2 paren_args
1829
+ {
1830
+ result = new_call val[0], val[2].to_sym, val[3]
1831
+ }
1832
+ | primary_value tCOLON2 operation3
1833
+ {
1834
+ result = new_call val[0], val[2].to_sym
1835
+ }
1836
+ | primary_value call_op paren_args
1837
+ {
1838
+ result = new_call val[0], :call, val[2], val[1]
1839
+ }
1840
+ | primary_value tCOLON2 paren_args
1841
+ {
1842
+ result = new_call val[0], :call, val[2]
1843
+ }
1844
+ | kSUPER paren_args
1845
+ {
1846
+ result = new_super val[1]
1847
+ }
1848
+ | kSUPER
1849
+ {
1850
+ result = s(:zsuper).line lexer.lineno
1851
+ }
1852
+ | primary_value tLBRACK2 opt_call_args rbracket
1853
+ {
1854
+ result = new_aref val
1855
+ }
1856
+
1857
+ brace_block: tLCURLY
1858
+ {
1859
+ self.env.extend :dynamic
1860
+ result = self.lexer.lineno
1861
+ }
1862
+ brace_body tRCURLY
1863
+ {
1864
+ _, line, body, _ = val
1865
+
1866
+ result = body
1867
+ result.line = line
1868
+
1869
+ self.env.unextend
1870
+ }
1871
+ | k_do
1872
+ {
1873
+ self.env.extend :dynamic
1874
+ result = self.lexer.lineno
1875
+ }
1876
+ do_body kEND
1877
+ {
1878
+ _, line, body, _ = val
1879
+
1880
+ result = body
1881
+ result.line = line
1882
+
1883
+ self.env.unextend
1884
+ }
1885
+
1886
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1887
+ { result = lexer.cmdarg.store(false) }
1888
+ opt_block_param compstmt
1889
+ {
1890
+ line, cmdarg, param, cmpstmt = val
1891
+
1892
+ result = new_brace_body param, cmpstmt, line
1893
+ self.env.unextend
1894
+ lexer.cmdarg.restore cmdarg
1895
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1896
+ }
1897
+
1898
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1899
+ { lexer.cmdarg.push false }
1900
+ opt_block_param
1901
+ bodystmt
1902
+ {
1903
+ line, _cmdarg, param, cmpstmt = val
1904
+
1905
+ result = new_do_body param, cmpstmt, line
1906
+ lexer.cmdarg.pop
1907
+ self.env.unextend
1908
+ }
1909
+
1910
+ case_body: k_when
1911
+ {
1912
+ result = self.lexer.lineno
1913
+ }
1914
+ args then compstmt cases
1915
+ {
1916
+ result = new_when(val[2], val[4])
1917
+ result.line = val[1]
1918
+ result << val[5] if val[5]
1919
+ }
1920
+
1921
+ cases: opt_else | case_body
1922
+
1923
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1924
+ {
1925
+ (_, line), klasses, var, _, body, rest = val
1926
+
1927
+ klasses ||= s(:array)
1928
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1929
+ klasses.line line
1930
+
1931
+ result = new_resbody(klasses, body)
1932
+ result << rest if rest # UGH, rewritten above
1933
+ }
1934
+ |
1935
+ {
1936
+ result = nil
1937
+ }
1938
+
1939
+ exc_list: arg_value
1940
+ {
1941
+ arg, = val
1942
+ result = s(:array, arg).line arg.line
1943
+ }
1944
+ | mrhs
1945
+ | none
1946
+
1947
+ exc_var: tASSOC lhs
1948
+ {
1949
+ result = val[1]
1950
+ }
1951
+ | none
1952
+
1953
+ opt_ensure: k_ensure compstmt
1954
+ {
1955
+ (_, line), body = val
1956
+
1957
+ result = body || s(:nil).line(line)
1958
+ }
1959
+ | none
1960
+
1961
+ literal: numeric
1962
+ {
1963
+ line = lexer.lineno
1964
+ result = s(:lit, val[0])
1965
+ result.line = line
1966
+ }
1967
+ | symbol
1968
+ {
1969
+ line = lexer.lineno
1970
+ result = s(:lit, val[0])
1971
+ result.line = line
1972
+ }
1973
+ | dsym
1974
+
1975
+ strings: string
1976
+ {
1977
+ str, = val
1978
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1979
+ result = str
1980
+ }
1981
+
1982
+ string: tCHAR
1983
+ {
1984
+ debug20 23, val, result
1985
+ }
1986
+ | string1
1987
+ | string string1
1988
+ {
1989
+ result = self.literal_concat val[0], val[1]
1990
+ }
1991
+
1992
+ string1: tSTRING_BEG string_contents tSTRING_END
1993
+ {
1994
+ _, str, (_, func) = val
1995
+
1996
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1997
+
1998
+ result = str
1999
+ }
2000
+ | tSTRING
2001
+ {
2002
+ result = new_string val
2003
+ }
2004
+
2005
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2006
+ {
2007
+ result = new_xstring val
2008
+ # TODO: dedent?!?! SERIOUSLY?!?
2009
+ }
2010
+
2011
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2012
+ {
2013
+ result = new_regexp val
2014
+ }
2015
+
2016
+ words: tWORDS_BEG tSPACE tSTRING_END
2017
+ {
2018
+ result = s(:array).line lexer.lineno
2019
+ }
2020
+ | tWORDS_BEG word_list tSTRING_END
2021
+ {
2022
+ result = val[1]
2023
+ }
2024
+
2025
+ word_list: none
2026
+ {
2027
+ result = new_word_list
2028
+ }
2029
+ | word_list word tSPACE
2030
+ {
2031
+ result = val[0].dup << new_word_list_entry(val)
2032
+ }
2033
+
2034
+ word: string_content
2035
+ | word string_content
2036
+ {
2037
+ result = self.literal_concat val[0], val[1]
2038
+ }
2039
+
2040
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2041
+ {
2042
+ result = s(:array).line lexer.lineno
2043
+ }
2044
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2045
+ {
2046
+ _, line, list, _, = val
2047
+ list.line = line
2048
+ result = list
2049
+ }
2050
+
2051
+ symbol_list: none
2052
+ {
2053
+ result = new_symbol_list.line lexer.lineno
2054
+ }
2055
+ | symbol_list word tSPACE
2056
+ {
2057
+ list, * = val
2058
+ result = list.dup << new_symbol_list_entry(val)
2059
+ }
2060
+
2061
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2062
+ {
2063
+ result = s(:array).line lexer.lineno
2064
+ }
2065
+ | tQWORDS_BEG qword_list tSTRING_END
2066
+ {
2067
+ result = val[1]
2068
+ }
2069
+
2070
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2071
+ {
2072
+ result = s(:array).line lexer.lineno # FIX
2073
+ }
2074
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2075
+ {
2076
+ result = val[1]
2077
+ }
2078
+
2079
+ qword_list: none
2080
+ {
2081
+ result = new_qword_list
2082
+ }
2083
+ | qword_list tSTRING_CONTENT tSPACE
2084
+ {
2085
+ result = val[0].dup << new_qword_list_entry(val)
2086
+ }
2087
+
2088
+ qsym_list: none
2089
+ {
2090
+ result = new_qsym_list
2091
+ }
2092
+ | qsym_list tSTRING_CONTENT tSPACE
2093
+ {
2094
+ result = val[0].dup << new_qsym_list_entry(val)
2095
+ }
2096
+
2097
+ string_contents: none
2098
+ {
2099
+ result = s(:str, "").line lexer.lineno
2100
+ }
2101
+ | string_contents string_content
2102
+ {
2103
+ v1, v2 = val
2104
+ result = literal_concat v1, v2
2105
+ }
2106
+
2107
+ xstring_contents: none
2108
+ {
2109
+ result = nil
2110
+ }
2111
+ | xstring_contents string_content
2112
+ {
2113
+ v1, v2 = val
2114
+ result = literal_concat v1, v2
2115
+ }
2116
+
2117
+ regexp_contents: none
2118
+ {
2119
+ result = nil
2120
+ }
2121
+ | regexp_contents string_content
2122
+ {
2123
+ v1, v2 = val
2124
+ result = literal_concat v1, v2
2125
+ }
2126
+
2127
+ string_content: tSTRING_CONTENT
2128
+ {
2129
+ result = new_string val
2130
+ }
2131
+ | tSTRING_DVAR
2132
+ {
2133
+ result = lexer.lex_strterm
2134
+
2135
+ lexer.lex_strterm = nil
2136
+ lexer.lex_state = EXPR_BEG
2137
+ }
2138
+ string_dvar
2139
+ {
2140
+ _, strterm, str = val
2141
+ lexer.lex_strterm = strterm
2142
+ result = s(:evstr, str).line str.line
2143
+ }
2144
+ | tSTRING_DBEG
2145
+ {
2146
+ result = [lexer.lex_strterm,
2147
+ lexer.brace_nest,
2148
+ lexer.string_nest, # TODO: remove
2149
+ lexer.lex_state,
2150
+ lexer.lineno,
2151
+ ]
2152
+
2153
+ lexer.cmdarg.push false
2154
+ lexer.cond.push false
2155
+
2156
+ lexer.lex_strterm = nil
2157
+ lexer.brace_nest = 0
2158
+ lexer.string_nest = 0
2159
+
2160
+ lexer.lex_state = EXPR_BEG
2161
+ }
2162
+ compstmt
2163
+ tSTRING_DEND
2164
+ {
2165
+ _, memo, stmt, _ = val
2166
+
2167
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2168
+ # TODO: heredoc_indent
2169
+
2170
+ lexer.lex_strterm = lex_strterm
2171
+ lexer.brace_nest = brace_nest
2172
+ lexer.string_nest = string_nest
2173
+
2174
+ lexer.cmdarg.pop
2175
+ lexer.cond.pop
2176
+
2177
+ lexer.lex_state = oldlex_state
2178
+
2179
+ case stmt
2180
+ when Sexp then
2181
+ case stmt.sexp_type
2182
+ when :str, :dstr, :evstr then
2183
+ result = stmt
2184
+ else
2185
+ result = s(:evstr, stmt).line line
2186
+ end
2187
+ when nil then
2188
+ result = s(:evstr).line line
2189
+ else
2190
+ debug20 25
2191
+ raise "unknown string body: #{stmt.inspect}"
2192
+ end
2193
+ }
2194
+
2195
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2196
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2197
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2198
+ | backref
2199
+
2200
+ symbol: tSYMBEG sym
2201
+ {
2202
+ lexer.lex_state = EXPR_END
2203
+ result = val[1].to_sym
2204
+ }
2205
+ | tSYMBOL
2206
+ {
2207
+ result = val[0].to_sym
2208
+ }
2209
+
2210
+ sym: fname | tIVAR | tGVAR | tCVAR
2211
+
2212
+ dsym: tSYMBEG xstring_contents tSTRING_END
2213
+ {
2214
+ _, result, _ = val
2215
+
2216
+ lexer.lex_state = EXPR_END
2217
+
2218
+ result ||= s(:str, "").line lexer.lineno
2219
+
2220
+ case result.sexp_type
2221
+ when :dstr then
2222
+ result.sexp_type = :dsym
2223
+ when :str then
2224
+ result = s(:lit, result.last.to_sym).line result.line
2225
+ when :evstr then
2226
+ result = s(:dsym, "", result).line result.line
2227
+ else
2228
+ debug20 26, val, result
2229
+ end
2230
+ }
2231
+
2232
+ numeric: simple_numeric
2233
+ | tUMINUS_NUM simple_numeric
2234
+ {
2235
+ result = -val[1] # TODO: pt_testcase
2236
+ }
2237
+
2238
+ simple_numeric: tINTEGER
2239
+ | tFLOAT
2240
+ | tRATIONAL
2241
+ | tIMAGINARY
2242
+
2243
+ user_variable: tIDENTIFIER
2244
+ | tIVAR
2245
+ | tGVAR
2246
+ | tCONSTANT
2247
+ | tCVAR
2248
+
2249
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2250
+ | kSELF { result = s(:self).line lexer.lineno }
2251
+ | kTRUE { result = s(:true).line lexer.lineno }
2252
+ | kFALSE { result = s(:false).line lexer.lineno }
2253
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2254
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2255
+ | k__ENCODING__
2256
+ {
2257
+ l = lexer.lineno
2258
+ result =
2259
+ if defined? Encoding then
2260
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2261
+ else
2262
+ s(:str, "Unsupported!").line l
2263
+ end
2264
+ }
2265
+
2266
+ var_ref: user_variable
2267
+ {
2268
+ var = val[0]
2269
+ result = Sexp === var ? var : self.gettable(var)
2270
+ }
2271
+ | keyword_variable
2272
+ {
2273
+ var = val[0]
2274
+ result = Sexp === var ? var : self.gettable(var)
2275
+ }
2276
+
2277
+ var_lhs: user_variable
2278
+ {
2279
+ result = self.assignable val[0]
2280
+ }
2281
+ | keyword_variable
2282
+ {
2283
+ result = self.assignable val[0]
2284
+ debug20 29, val, result
2285
+ }
2286
+
2287
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2288
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2289
+
2290
+ superclass: tLT
2291
+ {
2292
+ lexer.lex_state = EXPR_BEG
2293
+ lexer.command_start = true
2294
+ }
2295
+ expr_value term
2296
+ {
2297
+ result = val[2]
2298
+ }
2299
+ | none
2300
+ {
2301
+ result = nil
2302
+ }
2303
+
2304
+ f_arglist: tLPAREN2 f_args rparen
2305
+ {
2306
+ result = val[1]
2307
+ self.lexer.lex_state = EXPR_BEG
2308
+ self.lexer.command_start = true
2309
+ }
2310
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
2311
+ {
2312
+ result = args val
2313
+
2314
+ self.lexer.lex_state = EXPR_BEG
2315
+ self.lexer.command_start = true
2316
+ }
2317
+ | tLPAREN2 args_forward rparen
2318
+ {
2319
+ result = args val
2320
+
2321
+ self.lexer.lex_state = EXPR_BEG
2322
+ self.lexer.command_start = true
2323
+ }
2324
+ | {
2325
+ result = self.in_kwarg
2326
+ self.in_kwarg = true
2327
+ self.lexer.lex_state |= EXPR_LABEL
2328
+ }
2329
+ f_args term
2330
+ {
2331
+ kwarg, args, _ = val
2332
+
2333
+ self.in_kwarg = kwarg
2334
+ result = args
2335
+ lexer.lex_state = EXPR_BEG
2336
+ lexer.command_start = true
2337
+ }
2338
+
2339
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2340
+ {
2341
+ result = args val
2342
+ }
2343
+ | f_kwarg opt_f_block_arg
2344
+ {
2345
+ result = args val
2346
+ }
2347
+ | f_kwrest opt_f_block_arg
2348
+ {
2349
+ result = args val
2350
+ }
2351
+ | f_block_arg
2352
+
2353
+ opt_args_tail: tCOMMA args_tail
2354
+ {
2355
+ result = val[1]
2356
+ }
2357
+ |
2358
+ {
2359
+ result = nil
2360
+ }
2361
+
2362
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2363
+ {
2364
+ result = args val
2365
+ }
2366
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2367
+ {
2368
+ result = args val
2369
+ }
2370
+ | f_arg tCOMMA f_optarg opt_args_tail
2371
+ {
2372
+ result = args val
2373
+ }
2374
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2375
+ {
2376
+ result = args val
2377
+ }
2378
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2379
+ {
2380
+ result = args val
2381
+ }
2382
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2383
+ {
2384
+ result = args val
2385
+ }
2386
+ | f_arg opt_args_tail
2387
+ {
2388
+ result = args val
2389
+ }
2390
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2391
+ {
2392
+ result = args val
2393
+ }
2394
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2395
+ {
2396
+ result = args val
2397
+ }
2398
+ | f_optarg opt_args_tail
2399
+ {
2400
+ result = args val
2401
+ }
2402
+ | f_optarg tCOMMA f_arg opt_args_tail
2403
+ {
2404
+ result = args val
2405
+ }
2406
+ | f_rest_arg opt_args_tail
2407
+ {
2408
+ result = args val
2409
+ }
2410
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2411
+ {
2412
+ result = args val
2413
+ }
2414
+ | args_tail
2415
+ {
2416
+ result = args val
2417
+ }
2418
+ |
2419
+ {
2420
+ result = args val
2421
+ }
2422
+
2423
+ args_forward: tBDOT3
2424
+ {
2425
+ result = s(:forward_args).line lexer.lineno
2426
+ }
2427
+
2428
+ f_bad_arg: tCONSTANT
2429
+ {
2430
+ yyerror "formal argument cannot be a constant"
2431
+ }
2432
+ | tIVAR
2433
+ {
2434
+ yyerror "formal argument cannot be an instance variable"
2435
+ }
2436
+ | tGVAR
2437
+ {
2438
+ yyerror "formal argument cannot be a global variable"
2439
+ }
2440
+ | tCVAR
2441
+ {
2442
+ yyerror "formal argument cannot be a class variable"
2443
+ }
2444
+
2445
+ f_norm_arg: f_bad_arg
2446
+ | tIDENTIFIER
2447
+ {
2448
+ identifier = val[0].to_sym
2449
+ self.env[identifier] = :lvar
2450
+
2451
+ result = identifier
2452
+ }
2453
+
2454
+ f_arg_asgn: f_norm_arg
2455
+
2456
+ f_arg_item: f_arg_asgn
2457
+ | tLPAREN f_margs rparen
2458
+ {
2459
+ result = val[1]
2460
+ }
2461
+
2462
+ f_arg: f_arg_item
2463
+ {
2464
+ arg, = val
2465
+
2466
+ case arg
2467
+ when Symbol then
2468
+ result = s(:args, arg).line lexer.lineno
2469
+ when Sexp then
2470
+ result = arg
2471
+ else
2472
+ debug20 32
2473
+ raise "Unknown f_arg type: #{val.inspect}"
2474
+ end
2475
+ }
2476
+ | f_arg tCOMMA f_arg_item
2477
+ {
2478
+ list, _, item = val
2479
+
2480
+ if list.sexp_type == :args then
2481
+ result = list
2482
+ else
2483
+ result = s(:args, list).line list.line
2484
+ end
2485
+
2486
+ result << item
2487
+ }
2488
+
2489
+ f_label: tLABEL
2490
+
2491
+ f_kw: f_label arg_value
2492
+ {
2493
+ # TODO: new_kw_arg
2494
+ (label, line), arg = val
2495
+
2496
+ identifier = label.to_sym
2497
+ self.env[identifier] = :lvar
2498
+
2499
+ kwarg = s(:kwarg, identifier, arg).line line
2500
+ result = s(:array, kwarg).line line
2501
+ }
2502
+ | f_label
2503
+ {
2504
+ (label, line), = val
2505
+
2506
+ id = label.to_sym
2507
+ self.env[id] = :lvar
2508
+
2509
+ result = s(:array, s(:kwarg, id).line(line)).line line
2510
+ }
2511
+
2512
+ f_block_kw: f_label primary_value
2513
+ {
2514
+ # TODO: new_kw_arg
2515
+ (label, line), expr = val
2516
+ id = label.to_sym
2517
+ self.env[id] = :lvar
2518
+
2519
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2520
+ }
2521
+ | f_label
2522
+ {
2523
+ # TODO: new_kw_arg
2524
+ (label, line), = val
2525
+ id = label.to_sym
2526
+ self.env[id] = :lvar
2527
+
2528
+ result = s(:array, s(:kwarg, id).line(line)).line line
2529
+ }
2530
+
2531
+ f_block_kwarg: f_block_kw
2532
+ | f_block_kwarg tCOMMA f_block_kw
2533
+ {
2534
+ list, _, item = val
2535
+ result = list << item.last
2536
+ }
2537
+
2538
+ f_kwarg: f_kw
2539
+ | f_kwarg tCOMMA f_kw
2540
+ {
2541
+ result = args val
2542
+ }
2543
+
2544
+ kwrest_mark: tPOW
2545
+ | tDSTAR
2546
+
2547
+ f_kwrest: kwrest_mark tIDENTIFIER
2548
+ {
2549
+ name = val[1].to_sym
2550
+ self.assignable name
2551
+ result = :"**#{name}"
2552
+ }
2553
+ | kwrest_mark
2554
+ {
2555
+ result = :"**"
2556
+ self.env[result] = :lvar
2557
+ }
2558
+
2559
+ f_opt: f_arg_asgn tEQL arg_value
2560
+ {
2561
+ result = self.assignable val[0], val[2]
2562
+ # TODO: detect duplicate names
2563
+ }
2564
+
2565
+ f_block_opt: f_arg_asgn tEQL primary_value
2566
+ {
2567
+ result = self.assignable val[0], val[2]
2568
+ }
2569
+
2570
+ f_block_optarg: f_block_opt
2571
+ {
2572
+ optblk, = val
2573
+ result = s(:block, optblk).line optblk.line
2574
+ }
2575
+ | f_block_optarg tCOMMA f_block_opt
2576
+ {
2577
+ optarg, _, optblk = val
2578
+ result = optarg
2579
+ result << optblk
2580
+ }
2581
+
2582
+ f_optarg: f_opt
2583
+ {
2584
+ opt, = val
2585
+ result = s(:block, opt).line opt.line
2586
+ }
2587
+ | f_optarg tCOMMA f_opt
2588
+ {
2589
+ result = self.block_append val[0], val[2]
2590
+ }
2591
+
2592
+ restarg_mark: tSTAR2 | tSTAR
2593
+
2594
+ f_rest_arg: restarg_mark tIDENTIFIER
2595
+ {
2596
+ # TODO: differs from parse.y - needs tests
2597
+ name = val[1].to_sym
2598
+ self.assignable name
2599
+ result = :"*#{name}"
2600
+ }
2601
+ | restarg_mark
2602
+ {
2603
+ name = :"*"
2604
+ self.env[name] = :lvar
2605
+ result = name
2606
+ }
2607
+
2608
+ blkarg_mark: tAMPER2 | tAMPER
2609
+
2610
+ f_block_arg: blkarg_mark tIDENTIFIER
2611
+ {
2612
+ identifier = val[1].to_sym
2613
+
2614
+ self.env[identifier] = :lvar
2615
+ result = "&#{identifier}".to_sym
2616
+ }
2617
+
2618
+ opt_f_block_arg: tCOMMA f_block_arg
2619
+ {
2620
+ result = val[1]
2621
+ }
2622
+ |
2623
+ {
2624
+ result = nil
2625
+ }
2626
+
2627
+ singleton: var_ref
2628
+ | tLPAREN2
2629
+ {
2630
+ lexer.lex_state = EXPR_BEG
2631
+ }
2632
+ expr rparen
2633
+ {
2634
+ result = val[2]
2635
+ yyerror "Can't define single method for literals." if
2636
+ result.sexp_type == :lit
2637
+ }
2638
+
2639
+ assoc_list: none
2640
+ {
2641
+ result = s(:array).line lexer.lineno
2642
+ }
2643
+ | assocs trailer
2644
+
2645
+ assocs: assoc
2646
+ | assocs tCOMMA assoc
2647
+ {
2648
+ list = val[0].dup
2649
+ more = val[2].sexp_body
2650
+ list.push(*more) unless more.empty?
2651
+ result = list
2652
+ result.sexp_type = :hash
2653
+ }
2654
+
2655
+ assoc: arg_value tASSOC arg_value
2656
+ {
2657
+ v1, _, v2 = val
2658
+ result = s(:array, v1, v2).line v1.line
2659
+ }
2660
+ | tLABEL arg_value
2661
+ {
2662
+ (label, line), arg = val
2663
+
2664
+ lit = s(:lit, label.to_sym).line line
2665
+ result = s(:array, lit, arg).line line
2666
+ }
2667
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2668
+ {
2669
+ _, sym, _, value = val
2670
+ sym.sexp_type = :dsym
2671
+ result = s(:array, sym, value).line sym.line
2672
+ }
2673
+ | tDSTAR arg_value
2674
+ {
2675
+ _, arg = val
2676
+ line = arg.line
2677
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2678
+ }
2679
+
2680
+ operation: tIDENTIFIER | tCONSTANT | tFID
2681
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2682
+ operation3: tIDENTIFIER | tFID | op
2683
+ dot_or_colon: tDOT | tCOLON2
2684
+ call_op: tDOT
2685
+ | tLONELY # TODO: rename tANDDOT?
2686
+
2687
+ call_op2: call_op
2688
+ | tCOLON2
2689
+
2690
+ opt_terms: | terms
2691
+ opt_nl: | tNL
2692
+ rparen: opt_nl tRPAREN
2693
+ rbracket: opt_nl tRBRACK
2694
+ trailer: | tNL | tCOMMA
2695
+
2696
+ term: tSEMI { yyerrok }
2697
+ | tNL
2698
+
2699
+ terms: term
2700
+ | terms tSEMI { yyerrok }
2701
+
2702
+ none: { result = nil; }
2703
+ end
2704
+
2705
+ ---- inner
2706
+
2707
+ require "ruby_lexer"
2708
+ require "ruby_parser_extras"
2709
+ include RubyLexer::State::Values
2710
+
2711
+ # :stopdoc:
2712
+
2713
+ # Local Variables: **
2714
+ # racc-token-length-max:14 **
2715
+ # End: **