ruby_parser 3.15.1 → 3.18.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3476 @@
1
+ # -*- racc -*-
2
+
3
+ #if V == 30
4
+ class Ruby30Parser
5
+ #else
6
+ fail "version not specified or supported on code generation"
7
+ #endif
8
+
9
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
10
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
11
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
12
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
13
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
14
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
15
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
16
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
17
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
18
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
19
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
20
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
21
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
22
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
23
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
24
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
25
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
26
+ tRATIONAL tIMAGINARY
27
+ tLABEL_END
28
+ tLONELY
29
+ tBDOT2 tBDOT3
30
+
31
+ preclow
32
+ nonassoc tLOWEST
33
+ nonassoc tLBRACE_ARG
34
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
35
+ left kOR kAND
36
+ right kNOT
37
+ nonassoc kDEFINED
38
+ right tEQL tOP_ASGN
39
+ left kRESCUE_MOD
40
+ right tEH tCOLON
41
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
42
+ left tOROP
43
+ left tANDOP
44
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
45
+ left tGT tGEQ tLT tLEQ
46
+ left tPIPE tCARET
47
+ left tAMPER2
48
+ left tLSHFT tRSHFT
49
+ left tPLUS tMINUS
50
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
51
+ right tUMINUS_NUM tUMINUS
52
+ right tPOW
53
+ right tBANG tTILDE tUPLUS
54
+ prechigh
55
+
56
+ rule
57
+
58
+ program: {
59
+ self.lexer.lex_state = EXPR_BEG
60
+ }
61
+ top_compstmt
62
+ {
63
+ result = new_compstmt val
64
+
65
+ lexer.cond.pop # local_pop
66
+ lexer.cmdarg.pop
67
+ }
68
+
69
+ top_compstmt: top_stmts opt_terms
70
+ {
71
+ stmt, _ = val
72
+ result = stmt
73
+ }
74
+
75
+ top_stmts: none
76
+ | top_stmt
77
+ | top_stmts terms top_stmt
78
+ {
79
+ result = self.block_append val[0], val[2]
80
+ }
81
+ | error top_stmt
82
+
83
+ top_stmt: stmt
84
+ | klBEGIN
85
+ {
86
+ if (self.in_def || self.in_single > 0) then
87
+ debug 11
88
+ yyerror "BEGIN in method"
89
+ end
90
+ self.env.extend
91
+ }
92
+ begin_block
93
+ {
94
+ (_, lineno), _, iter = val
95
+ iter.line lineno
96
+
97
+ (_, preexe,) = iter
98
+ preexe.line lineno
99
+
100
+ result = iter
101
+ }
102
+
103
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
104
+ {
105
+ _, line, stmt, _ = val
106
+ result = new_iter s(:preexe).line(line), 0, stmt
107
+ }
108
+
109
+ bodystmt: compstmt opt_rescue k_else
110
+ {
111
+ res = _values[-2]
112
+ yyerror "else without rescue is useless" unless res
113
+ }
114
+ compstmt
115
+ opt_ensure
116
+ {
117
+ body, resc, _, _, els, ens = val
118
+
119
+ result = new_body [body, resc, els, ens]
120
+ }
121
+ | compstmt opt_rescue opt_ensure
122
+ {
123
+ body, resc, ens = val
124
+
125
+ result = new_body [body, resc, nil, ens]
126
+ }
127
+
128
+ compstmt: stmts opt_terms
129
+ {
130
+ result = new_compstmt val
131
+ }
132
+
133
+ stmts: none
134
+ | stmt_or_begin # TODO: newline_node ?
135
+ | stmts terms stmt_or_begin
136
+ {
137
+ result = self.block_append val[0], val[2]
138
+ }
139
+ | error stmt
140
+ {
141
+ result = val[1]
142
+ debug 12
143
+ }
144
+
145
+ stmt_or_begin: stmt
146
+ | klBEGIN
147
+ {
148
+ yyerror "BEGIN is permitted only at toplevel"
149
+ }
150
+ begin_block
151
+ {
152
+ result = val[2] # wtf?
153
+ }
154
+
155
+ stmt: kALIAS fitem
156
+ {
157
+ lexer.lex_state = EXPR_FNAME
158
+ }
159
+ fitem
160
+ {
161
+ (_, line), lhs, _, rhs = val
162
+ result = s(:alias, lhs, rhs).line(line).line line
163
+ }
164
+ | kALIAS tGVAR tGVAR
165
+ {
166
+ (_, line), (lhs, _), (rhs, _) = val
167
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
168
+ }
169
+ | kALIAS tGVAR tBACK_REF
170
+ {
171
+ (_, line), (lhs, _), (rhs, _) = val
172
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
173
+ }
174
+ | kALIAS tGVAR tNTH_REF
175
+ {
176
+ yyerror "can't make alias for the number variables"
177
+ }
178
+ | kUNDEF undef_list
179
+ {
180
+ result = val[1]
181
+ }
182
+ | stmt kIF_MOD expr_value
183
+ {
184
+ t, _, c = val
185
+ result = new_if c, t, nil
186
+ }
187
+ | stmt kUNLESS_MOD expr_value
188
+ {
189
+ f, _, c = val
190
+ result = new_if c, nil, f
191
+ }
192
+ | stmt kWHILE_MOD expr_value
193
+ {
194
+ e, _, c = val
195
+ result = new_while e, c, true
196
+ }
197
+ | stmt kUNTIL_MOD expr_value
198
+ {
199
+ e, _, c = val
200
+ result = new_until e, c, true
201
+ }
202
+ | stmt kRESCUE_MOD stmt
203
+ {
204
+ body, _, resbody = val
205
+
206
+ resbody = new_resbody s(:array).line(resbody.line), resbody
207
+ result = new_rescue body, resbody
208
+ }
209
+ | klEND tLCURLY compstmt tRCURLY
210
+ {
211
+ (_, line), _, stmt, _ = val
212
+
213
+ if (self.in_def || self.in_single > 0) then
214
+ debug 13
215
+ yyerror "END in method; use at_exit"
216
+ end
217
+
218
+ result = new_iter s(:postexe).line(line), 0, stmt
219
+ }
220
+ | command_asgn
221
+ | mlhs tEQL command_call
222
+ {
223
+ result = new_masgn val[0], val[2], :wrap
224
+ }
225
+ | lhs tEQL mrhs
226
+ {
227
+ lhs, _, rhs = val
228
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
229
+ }
230
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
231
+ {
232
+ # unwraps s(:to_ary, rhs)
233
+ lhs, _, (_, rhs), _, resbody = val
234
+
235
+ resbody = new_resbody s(:array).line(resbody.line), resbody
236
+
237
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
238
+ }
239
+ | mlhs tEQL mrhs_arg
240
+ {
241
+ result = new_masgn val[0], val[2]
242
+ }
243
+ | expr
244
+
245
+ command_asgn: lhs tEQL command_rhs
246
+ {
247
+ result = new_assign val[0], val[2]
248
+ }
249
+ # | lhs tEQL command_asgn
250
+ # {
251
+ # result = new_assign val[0], val[2]
252
+ # }
253
+ | var_lhs tOP_ASGN command_rhs
254
+ {
255
+ result = new_op_asgn val
256
+ }
257
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
258
+ {
259
+ result = new_op_asgn1 val
260
+ }
261
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
262
+ {
263
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
264
+
265
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
266
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
267
+ result.line prim.line
268
+ }
269
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
270
+ {
271
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
272
+
273
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
274
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
275
+ result.line prim.line
276
+ }
277
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
278
+ {
279
+ lhs1, _, (lhs2, line), (id, _), rhs = val
280
+
281
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
282
+ }
283
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
284
+ {
285
+ lhs1, _, (lhs2, line), (id, _), rhs = val
286
+
287
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
288
+ }
289
+ | backref tOP_ASGN command_rhs
290
+ {
291
+ self.backref_assign_error val[0]
292
+ }
293
+
294
+ command_rhs: command_call =tOP_ASGN
295
+ {
296
+ expr, = val
297
+ result = value_expr expr
298
+ }
299
+ | command_call kRESCUE_MOD stmt
300
+ {
301
+ expr, (_, line), resbody = val
302
+
303
+ expr = value_expr expr
304
+ ary = s(:array).line line
305
+ result = new_rescue(expr, new_resbody(ary, resbody))
306
+ }
307
+ | command_asgn
308
+
309
+ expr: command_call
310
+ | expr kAND expr
311
+ {
312
+ lhs, _, rhs = val
313
+ result = logical_op :and, lhs, rhs
314
+ }
315
+ | expr kOR expr
316
+ {
317
+ lhs, _, rhs = val
318
+ result = logical_op :or, lhs, rhs
319
+ }
320
+ | kNOT opt_nl expr
321
+ {
322
+ (_, line), _, expr = val
323
+ result = new_call(expr, :"!").line line
324
+ # REFACTOR: call_uni_op
325
+ }
326
+ | tBANG command_call
327
+ {
328
+ _, cmd = val
329
+ result = new_call(cmd, :"!").line cmd.line
330
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
331
+ # REFACTOR: call_uni_op -- see parse26.y
332
+ }
333
+ | arg tASSOC
334
+ {
335
+ # value_expr($1);
336
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
337
+ self.lexer.command_start = false
338
+ result = self.in_kwarg
339
+ self.in_kwarg = true
340
+ self.env.extend
341
+ }
342
+ p_expr
343
+ {
344
+ lhs, _, in_kwarg, rhs = val
345
+
346
+ self.env.unextend
347
+ self.in_kwarg = in_kwarg
348
+
349
+ rhs = new_in rhs, nil, nil, rhs.line
350
+ result = new_case lhs, rhs, rhs.line
351
+ }
352
+ | arg
353
+ kIN
354
+ {
355
+ # TODO? value_expr($1);
356
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
357
+ self.lexer.command_start = false
358
+ result = self.in_kwarg
359
+ self.in_kwarg = true
360
+ self.env.extend
361
+ }
362
+ p_expr
363
+ {
364
+ self.env.unextend
365
+
366
+ expr, _, old_kwarg, pat = val
367
+
368
+ expr = value_expr expr
369
+
370
+ self.in_kwarg = old_kwarg
371
+ pat_in = new_in pat, nil, nil, expr.line
372
+ result = new_case expr, pat_in, expr.line
373
+ }
374
+ | arg =tLBRACE_ARG
375
+
376
+ def_name: fname
377
+ {
378
+ # TODO: numparam_name(p, fname);
379
+
380
+ (id, line), = val
381
+ old_in_def = self.in_def
382
+
383
+ self.in_def = true # group = local_push
384
+ self.env.extend
385
+ lexer.cmdarg.push false
386
+ lexer.cond.push false
387
+
388
+ result = [id.to_sym, line, old_in_def]
389
+ }
390
+ defn_head: k_def def_name
391
+ {
392
+ _, name = val
393
+ result = name
394
+ }
395
+ defs_head: k_def singleton dot_or_colon
396
+ {
397
+ lexer.lex_state = EXPR_FNAME
398
+ }
399
+ def_name
400
+ {
401
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
402
+ self.in_single += 1 # TODO: remove?
403
+
404
+ # self.in_def = true # local_push
405
+ # self.env.extend
406
+ # lexer.cmdarg.push false
407
+ # lexer.cond.push false
408
+
409
+ _, recv, _, _, name = val
410
+
411
+ result = [recv, name]
412
+ }
413
+
414
+ expr_value: expr
415
+ {
416
+ result = value_expr(val[0])
417
+ }
418
+
419
+ expr_value_do: {
420
+ lexer.cond.push true
421
+ }
422
+ expr_value do
423
+ {
424
+ lexer.cond.pop
425
+ }
426
+ {
427
+ _, expr, _, _ = val
428
+ result = expr
429
+ }
430
+
431
+ command_call: command
432
+ | block_command
433
+
434
+ block_command: block_call
435
+ | block_call call_op2 operation2 command_args
436
+ {
437
+ blk, _, (msg, _line), args = val
438
+ result = new_call(blk, msg.to_sym, args).line blk.line
439
+ }
440
+
441
+ cmd_brace_block: tLBRACE_ARG
442
+ {
443
+ # self.env.extend(:dynamic)
444
+ result = self.lexer.lineno
445
+ }
446
+ brace_body tRCURLY
447
+ {
448
+ _, line, body, _ = val
449
+
450
+ result = body
451
+ result.line line
452
+
453
+ # self.env.unextend
454
+ }
455
+
456
+ fcall: operation
457
+ {
458
+ (msg, line), = val
459
+ result = new_call(nil, msg.to_sym).line line
460
+ }
461
+
462
+ command: fcall command_args =tLOWEST
463
+ {
464
+ call, args = val
465
+ result = call.concat args.sexp_body
466
+ }
467
+ | fcall command_args cmd_brace_block
468
+ {
469
+ call, args, block = val
470
+
471
+ result = call.concat args.sexp_body
472
+
473
+ if block then
474
+ block_dup_check result, block
475
+
476
+ result, operation = block, result
477
+ result.insert 1, operation
478
+ end
479
+ }
480
+ | primary_value call_op operation2 command_args =tLOWEST
481
+ {
482
+ lhs, callop, (op, _), args = val
483
+
484
+ result = new_call lhs, op.to_sym, args, callop
485
+ result.line lhs.line
486
+ }
487
+ | primary_value call_op operation2 command_args cmd_brace_block
488
+ {
489
+ recv, _, (msg, _line), args, block = val
490
+ call = new_call recv, msg.to_sym, args, val[1]
491
+
492
+ block_dup_check call, block
493
+
494
+ block.insert 1, call
495
+ result = block
496
+ }
497
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
498
+ {
499
+ lhs, _, (id, line), args = val
500
+
501
+ result = new_call lhs, id.to_sym, args
502
+ result.line line
503
+ }
504
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
505
+ {
506
+ recv, _, (msg, _line), args, block = val
507
+ call = new_call recv, msg.to_sym, args
508
+
509
+ block_dup_check call, block
510
+
511
+ block.insert 1, call
512
+ result = block
513
+ }
514
+ | kSUPER command_args
515
+ {
516
+ result = new_super val[1]
517
+ }
518
+ | kYIELD command_args
519
+ {
520
+ (_, line), args = val
521
+ result = new_yield args
522
+ result.line line # TODO: push to new_yield
523
+ }
524
+ | k_return call_args
525
+ {
526
+ line = val[0].last
527
+ result = s(:return, ret_args(val[1])).line(line)
528
+ }
529
+ | kBREAK call_args
530
+ {
531
+ (_, line), args = val
532
+ result = s(:break, ret_args(args)).line line
533
+ }
534
+ | kNEXT call_args
535
+ {
536
+ line = val[0].last
537
+ result = s(:next, ret_args(val[1])).line(line)
538
+ }
539
+
540
+ mlhs: mlhs_basic
541
+ | tLPAREN mlhs_inner rparen
542
+ {
543
+ result = val[1]
544
+ }
545
+
546
+ mlhs_inner: mlhs_basic
547
+ | tLPAREN mlhs_inner rparen
548
+ {
549
+ _, arg, _ = val
550
+ l = arg.line
551
+
552
+ result = s(:masgn, s(:array, arg).line(l)).line l
553
+ }
554
+
555
+ mlhs_basic: mlhs_head
556
+ {
557
+ head, = val
558
+ result = s(:masgn, head).line head.line
559
+ }
560
+ | mlhs_head mlhs_item
561
+ {
562
+ lhs, rhs = val
563
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
564
+ }
565
+ | mlhs_head tSTAR mlhs_node
566
+ {
567
+ head, _, tail = val
568
+ head << s(:splat, tail).line(tail.line)
569
+ result = s(:masgn, head).line head.line
570
+ }
571
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
572
+ {
573
+ ary1, _, splat, _, ary2 = val
574
+
575
+ result = list_append ary1, s(:splat, splat).line(splat.line)
576
+ result.concat ary2.sexp_body
577
+ result = s(:masgn, result).line result.line
578
+ }
579
+ | mlhs_head tSTAR
580
+ {
581
+ head, _ = val
582
+ l = head.line
583
+ result = s(:masgn, head << s(:splat).line(l)).line l
584
+ }
585
+ | mlhs_head tSTAR tCOMMA mlhs_post
586
+ {
587
+ head, _, _, post = val
588
+ ary = list_append head, s(:splat).line(head.line)
589
+ ary.concat post.sexp_body
590
+ result = s(:masgn, ary).line ary.line
591
+ }
592
+ | tSTAR mlhs_node
593
+ {
594
+ _, node = val
595
+ l = node.line
596
+ splat = s(:splat, node).line l
597
+ ary = s(:array, splat).line l
598
+ result = s(:masgn, ary).line l
599
+ }
600
+ | tSTAR mlhs_node tCOMMA mlhs_post
601
+ {
602
+ _, node, _, post = val
603
+
604
+ splat = s(:splat, node).line node.line
605
+ ary = s(:array, splat).line splat.line
606
+ ary.concat post.sexp_body
607
+ result = s(:masgn, ary).line ary.line
608
+ }
609
+ | tSTAR
610
+ {
611
+ l = lexer.lineno
612
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
613
+ }
614
+ | tSTAR tCOMMA mlhs_post
615
+ {
616
+ _, _, post = val
617
+ l = post.line
618
+
619
+ splat = s(:splat).line l
620
+ ary = s(:array, splat, *post.sexp_body).line l
621
+ result = s(:masgn, ary).line l
622
+ }
623
+
624
+ mlhs_item: mlhs_node
625
+ | tLPAREN mlhs_inner rparen
626
+ {
627
+ result = val[1]
628
+ }
629
+
630
+ mlhs_head: mlhs_item tCOMMA
631
+ {
632
+ lhs, _ = val
633
+ result = s(:array, lhs).line lhs.line
634
+ }
635
+ | mlhs_head mlhs_item tCOMMA
636
+ {
637
+ result = val[0] << val[1].compact
638
+ }
639
+
640
+ mlhs_post: mlhs_item
641
+ {
642
+ item, = val
643
+ result = s(:array, item).line item.line
644
+ }
645
+ | mlhs_post tCOMMA mlhs_item
646
+ {
647
+ result = list_append val[0], val[2]
648
+ }
649
+
650
+ mlhs_node: user_variable
651
+ {
652
+ result = self.assignable val[0]
653
+ }
654
+ | keyword_variable
655
+ {
656
+ result = self.assignable val[0]
657
+ }
658
+ | primary_value tLBRACK2 opt_call_args rbracket
659
+ {
660
+ result = self.aryset val[0], val[2]
661
+ }
662
+ | primary_value call_op tIDENTIFIER
663
+ {
664
+ lhs, call_op, (id, _line) = val
665
+
666
+ result = new_attrasgn lhs, id, call_op
667
+ }
668
+ | primary_value tCOLON2 tIDENTIFIER
669
+ {
670
+ recv, _, (id, _line) = val
671
+ result = new_attrasgn recv, id
672
+ }
673
+ | primary_value call_op tCONSTANT
674
+ {
675
+ lhs, call_op, (id, _line) = val
676
+
677
+ result = new_attrasgn lhs, id, call_op
678
+ }
679
+ | primary_value tCOLON2 tCONSTANT
680
+ {
681
+ if (self.in_def || self.in_single > 0) then
682
+ debug 14
683
+ yyerror "dynamic constant assignment"
684
+ end
685
+
686
+ expr, _, (id, _line) = val
687
+ l = expr.line
688
+
689
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
690
+ }
691
+ | tCOLON3 tCONSTANT
692
+ {
693
+ if (self.in_def || self.in_single > 0) then
694
+ debug 15
695
+ yyerror "dynamic constant assignment"
696
+ end
697
+
698
+ _, (id, l) = val
699
+
700
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
701
+ }
702
+ | backref
703
+ {
704
+ ref, = val
705
+
706
+ self.backref_assign_error ref
707
+ }
708
+
709
+ lhs: user_variable
710
+ {
711
+ var, = val
712
+
713
+ result = self.assignable var
714
+ }
715
+ | keyword_variable
716
+ {
717
+ var, = val
718
+
719
+ result = self.assignable var
720
+
721
+ debug 16
722
+ }
723
+ | primary_value tLBRACK2 opt_call_args rbracket
724
+ {
725
+ lhs, _, args, _ = val
726
+
727
+ result = self.aryset lhs, args
728
+ }
729
+ | primary_value call_op tIDENTIFIER # REFACTOR
730
+ {
731
+ lhs, op, (id, _line) = val
732
+
733
+ result = new_attrasgn lhs, id, op
734
+ }
735
+ | primary_value tCOLON2 tIDENTIFIER
736
+ {
737
+ lhs, _, (id, _line) = val
738
+
739
+ result = new_attrasgn lhs, id
740
+ }
741
+ | primary_value call_op tCONSTANT # REFACTOR?
742
+ {
743
+ lhs, call_op, (id, _line) = val
744
+
745
+ result = new_attrasgn lhs, id, call_op
746
+ }
747
+ | primary_value tCOLON2 tCONSTANT
748
+ {
749
+ expr, _, (id, _line) = val
750
+
751
+ if (self.in_def || self.in_single > 0) then
752
+ debug 17
753
+ yyerror "dynamic constant assignment"
754
+ end
755
+
756
+ l = expr.line
757
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
758
+ }
759
+ | tCOLON3 tCONSTANT
760
+ {
761
+ _, (id, l) = val
762
+
763
+ if (self.in_def || self.in_single > 0) then
764
+ debug 18
765
+ yyerror "dynamic constant assignment"
766
+ end
767
+
768
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
769
+ }
770
+ | backref
771
+ {
772
+ self.backref_assign_error val[0]
773
+ }
774
+
775
+ cname: tIDENTIFIER
776
+ {
777
+ yyerror "class/module name must be CONSTANT"
778
+ }
779
+ | tCONSTANT
780
+
781
+ cpath: tCOLON3 cname
782
+ {
783
+ _, (name, line) = val
784
+ result = s(:colon3, name.to_sym).line line
785
+ }
786
+ | cname
787
+ {
788
+ (id, line), = val
789
+ result = [id.to_sym, line] # TODO: sexp?
790
+ }
791
+ | primary_value tCOLON2 cname
792
+ {
793
+ pval, _, (name, _line) = val
794
+
795
+ result = s(:colon2, pval, name.to_sym)
796
+ result.line pval.line
797
+ }
798
+
799
+ fname: tIDENTIFIER | tCONSTANT | tFID
800
+ | op
801
+ {
802
+ lexer.lex_state = EXPR_END
803
+ }
804
+
805
+ | reswords
806
+
807
+ fitem: fname
808
+ {
809
+ (id, line), = val
810
+
811
+ result = s(:lit, id.to_sym).line line
812
+ }
813
+ | symbol
814
+
815
+ undef_list: fitem
816
+ {
817
+ result = new_undef val[0]
818
+ }
819
+ |
820
+ undef_list tCOMMA
821
+ {
822
+ lexer.lex_state = EXPR_FNAME
823
+ }
824
+ fitem
825
+ {
826
+ result = new_undef val[0], val[3]
827
+ }
828
+
829
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
830
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
831
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
832
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
833
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
834
+
835
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
836
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
837
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
838
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
839
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
840
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
841
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
842
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
843
+ | kUNTIL
844
+
845
+ arg: lhs tEQL arg_rhs
846
+ {
847
+ result = new_assign val[0], val[2]
848
+ }
849
+ | var_lhs tOP_ASGN arg_rhs
850
+ {
851
+ result = new_op_asgn val
852
+ }
853
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
854
+ {
855
+ result = new_op_asgn1 val
856
+ }
857
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
858
+ {
859
+ result = new_op_asgn2 val
860
+ }
861
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
862
+ {
863
+ result = new_op_asgn2 val
864
+ }
865
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
866
+ {
867
+ lhs, _, (id, _line), (op, _), rhs = val
868
+
869
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
870
+ }
871
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
872
+ {
873
+ lhs1, _, (lhs2, _line), op, rhs = val
874
+
875
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
876
+ result = new_const_op_asgn [lhs, op, rhs]
877
+ }
878
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
879
+ {
880
+ _, (lhs, line), op, rhs = val
881
+
882
+ lhs = s(:colon3, lhs.to_sym).line line
883
+ result = new_const_op_asgn [lhs, op, rhs]
884
+ }
885
+ | backref tOP_ASGN arg_rhs
886
+ {
887
+ # TODO: lhs = var_field val[0]
888
+ asgn = new_op_asgn val
889
+ result = self.backref_assign_error asgn
890
+ }
891
+ | arg tDOT2 arg
892
+ {
893
+ v1, v2 = val[0], val[2]
894
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
895
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
896
+ else
897
+ result = s(:dot2, v1, v2).line v1.line
898
+ end
899
+ }
900
+ | arg tDOT3 arg
901
+ {
902
+ v1, v2 = val[0], val[2]
903
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
904
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
905
+ else
906
+ result = s(:dot3, v1, v2).line v1.line
907
+ end
908
+ }
909
+ | arg tDOT2
910
+ {
911
+ v1, _ = val
912
+ v2 = nil
913
+
914
+ result = s(:dot2, v1, v2).line v1.line
915
+ }
916
+ | arg tDOT3
917
+ {
918
+ v1, _ = val
919
+ v2 = nil
920
+
921
+ result = s(:dot3, v1, v2).line v1.line
922
+ }
923
+
924
+ | tBDOT2 arg
925
+ {
926
+ _, v2, = val
927
+ v1 = nil
928
+
929
+ result = s(:dot2, v1, v2).line v2.line
930
+ }
931
+ | tBDOT3 arg
932
+ {
933
+ _, v2 = val
934
+ v1 = nil
935
+
936
+ result = s(:dot3, v1, v2).line v2.line
937
+ }
938
+
939
+ | arg tPLUS arg
940
+ {
941
+ result = new_call val[0], :+, argl(val[2])
942
+ }
943
+ | arg tMINUS arg
944
+ {
945
+ result = new_call val[0], :-, argl(val[2])
946
+ }
947
+ | arg tSTAR2 arg # TODO: rename
948
+ {
949
+ result = new_call val[0], :*, argl(val[2])
950
+ }
951
+ | arg tDIVIDE arg
952
+ {
953
+ result = new_call val[0], :"/", argl(val[2])
954
+ }
955
+ | arg tPERCENT arg
956
+ {
957
+ result = new_call val[0], :"%", argl(val[2])
958
+ }
959
+ | arg tPOW arg
960
+ {
961
+ result = new_call val[0], :**, argl(val[2])
962
+ }
963
+ | tUMINUS_NUM simple_numeric tPOW arg
964
+ {
965
+ _, (num, line), _, arg = val
966
+ lit = s(:lit, num).line line
967
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
968
+
969
+ }
970
+ | tUPLUS arg
971
+ {
972
+ result = new_call val[1], :"+@"
973
+ }
974
+ | tUMINUS arg
975
+ {
976
+ result = new_call val[1], :"-@"
977
+ }
978
+ | arg tPIPE arg
979
+ {
980
+ result = new_call val[0], :"|", argl(val[2])
981
+ }
982
+ | arg tCARET arg
983
+ {
984
+ result = new_call val[0], :"^", argl(val[2])
985
+ }
986
+ | arg tAMPER2 arg
987
+ {
988
+ result = new_call val[0], :"&", argl(val[2])
989
+ }
990
+ | arg tCMP arg
991
+ {
992
+ result = new_call val[0], :"<=>", argl(val[2])
993
+ }
994
+ | rel_expr =tCMP
995
+ | arg tEQ arg
996
+ {
997
+ result = new_call val[0], :"==", argl(val[2])
998
+ }
999
+ | arg tEQQ arg
1000
+ {
1001
+ result = new_call val[0], :"===", argl(val[2])
1002
+ }
1003
+ | arg tNEQ arg
1004
+ {
1005
+ result = new_call val[0], :"!=", argl(val[2])
1006
+ }
1007
+ | arg tMATCH arg
1008
+ {
1009
+ lhs, _, rhs = val
1010
+ result = new_match lhs, rhs
1011
+ }
1012
+ | arg tNMATCH arg
1013
+ {
1014
+ lhs, _, rhs = val
1015
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
1016
+ }
1017
+ | tBANG arg
1018
+ {
1019
+ _, arg = val
1020
+ result = new_call arg, :"!"
1021
+ result.line arg.line
1022
+ }
1023
+ | tTILDE arg
1024
+ {
1025
+ result = new_call value_expr(val[1]), :"~"
1026
+ }
1027
+ | arg tLSHFT arg
1028
+ {
1029
+ val[0] = value_expr val[0]
1030
+ val[2] = value_expr val[2]
1031
+ result = new_call val[0], :"\<\<", argl(val[2])
1032
+ }
1033
+ | arg tRSHFT arg
1034
+ {
1035
+ val[0] = value_expr val[0]
1036
+ val[2] = value_expr val[2]
1037
+ result = new_call val[0], :">>", argl(val[2])
1038
+ }
1039
+ | arg tANDOP arg
1040
+ {
1041
+ result = logical_op :and, val[0], val[2]
1042
+ }
1043
+ | arg tOROP arg
1044
+ {
1045
+ result = logical_op :or, val[0], val[2]
1046
+ }
1047
+ | kDEFINED opt_nl arg
1048
+ {
1049
+ (_, line), _, arg = val
1050
+ result = s(:defined, arg).line line
1051
+ }
1052
+ | arg tEH arg opt_nl tCOLON arg
1053
+ {
1054
+ c, _, t, _, _, f = val
1055
+ result = s(:if, c, t, f).line c.line
1056
+ }
1057
+ | defn_head f_opt_paren_args tEQL arg
1058
+ {
1059
+ (name, line, in_def), args, _, body = val
1060
+
1061
+ result = s(:defn, name, args, body).line line
1062
+
1063
+ local_pop in_def
1064
+ endless_method_name result
1065
+ }
1066
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1067
+ {
1068
+ (name, line, in_def), args, _, body, _, resbody = val
1069
+
1070
+ result = s(:defn, name, args,
1071
+ new_rescue(body,
1072
+ new_resbody(s(:array).line(line),
1073
+ resbody))).line line
1074
+
1075
+ local_pop in_def
1076
+ endless_method_name result
1077
+ }
1078
+ | defs_head f_opt_paren_args tEQL arg
1079
+ {
1080
+ (recv, (name, line, in_def)), args, _, body = val
1081
+
1082
+ result = s(:defs, recv, name, args, body).line(line)
1083
+
1084
+ self.in_single -= 1
1085
+ local_pop in_def
1086
+ endless_method_name result
1087
+ }
1088
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1089
+ {
1090
+ (recv, (name, line, in_def)), args, _, body, _, resbody = val
1091
+
1092
+ result = s(:defs, recv, name, args,
1093
+ new_rescue(body,
1094
+ new_resbody(s(:array).line(line),
1095
+ resbody))).line line
1096
+
1097
+ local_pop in_def
1098
+ endless_method_name result
1099
+ }
1100
+ | primary
1101
+
1102
+ relop: tGT
1103
+ | tLT
1104
+ | tGEQ
1105
+ | tLEQ
1106
+
1107
+ rel_expr: arg relop arg =tGT
1108
+ {
1109
+ lhs, (op, _), rhs = val
1110
+ result = new_call lhs, op.to_sym, argl(rhs)
1111
+ }
1112
+ | rel_expr relop arg =tGT
1113
+ {
1114
+ lhs, (op, _), rhs = val
1115
+ warn "comparison '%s' after comparison", op
1116
+ result = new_call lhs, op.to_sym, argl(rhs)
1117
+ }
1118
+
1119
+ arg_value: arg
1120
+ {
1121
+ result = value_expr(val[0])
1122
+ }
1123
+
1124
+ aref_args: none
1125
+ | args trailer
1126
+ {
1127
+ result = args [val[0]]
1128
+ }
1129
+ | args tCOMMA assocs trailer
1130
+ {
1131
+ result = args [val[0], array_to_hash(val[2])]
1132
+ }
1133
+ | assocs trailer
1134
+ {
1135
+ result = args [array_to_hash(val[0])]
1136
+ }
1137
+
1138
+ arg_rhs: arg =tOP_ASGN
1139
+ | arg kRESCUE_MOD arg
1140
+ {
1141
+ body, (_, line), resbody = val
1142
+ body = value_expr body
1143
+ resbody = remove_begin resbody
1144
+
1145
+ ary = s(:array).line line
1146
+ result = new_rescue(body, new_resbody(ary, resbody))
1147
+ }
1148
+
1149
+ paren_args: tLPAREN2 opt_call_args rparen
1150
+ {
1151
+ _, args, _ = val
1152
+ result = args
1153
+ }
1154
+ | tLPAREN2 args tCOMMA args_forward rparen
1155
+ {
1156
+ yyerror "Unexpected ..." unless
1157
+ self.lexer.is_local_id(:"*") &&
1158
+ self.lexer.is_local_id(:"**") &&
1159
+ self.lexer.is_local_id(:"&")
1160
+
1161
+ result = call_args val
1162
+ }
1163
+ | tLPAREN2 args_forward rparen
1164
+ {
1165
+ yyerror "Unexpected ..." unless
1166
+ self.lexer.is_local_id(:"*") &&
1167
+ self.lexer.is_local_id(:"**") &&
1168
+ self.lexer.is_local_id(:"&")
1169
+
1170
+ result = call_args val
1171
+ }
1172
+
1173
+ opt_paren_args: none
1174
+ | paren_args
1175
+
1176
+ opt_call_args: none
1177
+ | call_args
1178
+ | args tCOMMA
1179
+ {
1180
+ result = args val
1181
+ }
1182
+ | args tCOMMA assocs tCOMMA
1183
+ {
1184
+ result = args [val[0], array_to_hash(val[2])]
1185
+ }
1186
+ | assocs tCOMMA
1187
+ {
1188
+ result = args [array_to_hash(val[0])]
1189
+ }
1190
+
1191
+ call_args: command
1192
+ {
1193
+ warning "parenthesize argument(s) for future version"
1194
+ result = call_args val
1195
+ }
1196
+ | args opt_block_arg
1197
+ {
1198
+ result = call_args val
1199
+ }
1200
+ | assocs opt_block_arg
1201
+ {
1202
+ result = call_args [array_to_hash(val[0]), val[1]]
1203
+ }
1204
+ | args tCOMMA assocs opt_block_arg
1205
+ {
1206
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1207
+ }
1208
+ | block_arg
1209
+ {
1210
+ result = call_args val
1211
+ }
1212
+
1213
+ command_args: {
1214
+ # parse26.y line 2200
1215
+
1216
+ # If call_args starts with a open paren '(' or
1217
+ # '[', look-ahead reading of the letters calls
1218
+ # CMDARG_PUSH(0), but the push must be done
1219
+ # after CMDARG_PUSH(1). So this code makes them
1220
+ # consistent by first cancelling the premature
1221
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1222
+ # finally redoing CMDARG_PUSH(0).
1223
+
1224
+ result = yychar = self.last_token_type.first
1225
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1226
+ lexer.cmdarg.pop if lookahead
1227
+ lexer.cmdarg.push true
1228
+ lexer.cmdarg.push false if lookahead
1229
+ }
1230
+ call_args
1231
+ {
1232
+ yychar, args = val
1233
+
1234
+ # call_args can be followed by tLBRACE_ARG (that
1235
+ # does CMDARG_PUSH(0) in the lexer) but the push
1236
+ # must be done after CMDARG_POP() in the parser.
1237
+ # So this code does CMDARG_POP() to pop 0 pushed
1238
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1239
+ # by command_args, and CMDARG_PUSH(0) to restore
1240
+ # back the flag set by tLBRACE_ARG.
1241
+
1242
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1243
+ lexer.cmdarg.pop if lookahead
1244
+ lexer.cmdarg.pop
1245
+ lexer.cmdarg.push false if lookahead
1246
+ result = args
1247
+ }
1248
+
1249
+ block_arg: tAMPER arg_value
1250
+ {
1251
+ _, arg = val
1252
+ result = s(:block_pass, arg).line arg.line
1253
+ }
1254
+
1255
+ opt_block_arg: tCOMMA block_arg
1256
+ {
1257
+ result = val[1]
1258
+ }
1259
+ | none
1260
+
1261
+ args: arg_value
1262
+ {
1263
+ arg, = val
1264
+ lineno = arg.line || lexer.lineno # HACK
1265
+
1266
+ result = s(:array, arg).line lineno
1267
+ }
1268
+ | tSTAR arg_value
1269
+ {
1270
+ _, arg = val
1271
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1272
+ }
1273
+ | args tCOMMA arg_value
1274
+ {
1275
+ args, _, id = val
1276
+ result = self.list_append args, id
1277
+ }
1278
+ | args tCOMMA tSTAR arg_value
1279
+ {
1280
+ # TODO: the line number from tSTAR has been dropped
1281
+ args, _, _, id = val
1282
+ line = lexer.lineno
1283
+ result = self.list_append args, s(:splat, id).line(line)
1284
+ }
1285
+
1286
+ mrhs_arg: mrhs
1287
+ {
1288
+ result = new_masgn_arg val[0]
1289
+ }
1290
+ | arg_value
1291
+ {
1292
+ result = new_masgn_arg val[0], :wrap
1293
+ }
1294
+
1295
+ mrhs: args tCOMMA arg_value
1296
+ {
1297
+ result = val[0] << val[2]
1298
+ }
1299
+ | args tCOMMA tSTAR arg_value
1300
+ {
1301
+ # TODO: make all tXXXX terminals include lexer.lineno
1302
+ arg, _, _, splat = val
1303
+ result = self.arg_concat arg, splat
1304
+ }
1305
+ | tSTAR arg_value
1306
+ {
1307
+ _, arg = val
1308
+ result = s(:splat, arg).line arg.line
1309
+ }
1310
+
1311
+ primary: literal
1312
+ | strings
1313
+ | xstring
1314
+ | regexp
1315
+ | words
1316
+ | qwords
1317
+ | symbols
1318
+ | qsymbols
1319
+ | var_ref
1320
+ | backref
1321
+ | tFID
1322
+ {
1323
+ (msg, line), = val
1324
+ result = new_call nil, msg.to_sym
1325
+ result.line line
1326
+ }
1327
+ | k_begin
1328
+ {
1329
+ lexer.cmdarg.push false
1330
+ result = self.lexer.lineno
1331
+ }
1332
+ bodystmt k_end
1333
+ {
1334
+ lexer.cmdarg.pop
1335
+ result = new_begin val
1336
+ }
1337
+ | tLPAREN_ARG
1338
+ {
1339
+ lexer.lex_state = EXPR_ENDARG
1340
+ result = lexer.lineno
1341
+ }
1342
+ rparen
1343
+ {
1344
+ _, line, _ = val
1345
+ result = s(:begin).line line
1346
+ }
1347
+ | tLPAREN_ARG
1348
+ stmt
1349
+ {
1350
+ lexer.lex_state = EXPR_ENDARG
1351
+ }
1352
+ rparen
1353
+ {
1354
+ _, stmt, _, _, = val
1355
+ # warning "(...) interpreted as grouped expression"
1356
+ result = stmt
1357
+ }
1358
+ | tLPAREN compstmt tRPAREN
1359
+ {
1360
+ _, stmt, _ = val
1361
+ result = stmt
1362
+ result ||= s(:nil).line lexer.lineno
1363
+ result.paren = true
1364
+ }
1365
+ | primary_value tCOLON2 tCONSTANT
1366
+ {
1367
+ expr, _, (id, _line) = val
1368
+
1369
+ result = s(:colon2, expr, id.to_sym).line expr.line
1370
+ }
1371
+ | tCOLON3 tCONSTANT
1372
+ {
1373
+ _, (id, line) = val
1374
+
1375
+ result = s(:colon3, id.to_sym).line line
1376
+ }
1377
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1378
+ {
1379
+ _, line, args, _ = val
1380
+ result = args || s(:array)
1381
+ result.sexp_type = :array # aref_args is :args
1382
+ result.line line
1383
+ }
1384
+ | tLBRACE
1385
+ {
1386
+ result = self.lexer.lineno
1387
+ }
1388
+ assoc_list tRCURLY
1389
+ {
1390
+ result = new_hash val
1391
+ }
1392
+ | k_return
1393
+ {
1394
+ (_, line), = val
1395
+ result = s(:return).line line
1396
+ }
1397
+ | kYIELD tLPAREN2 call_args rparen
1398
+ {
1399
+ (_, line), _, args, _ = val
1400
+
1401
+ result = new_yield(args).line line
1402
+ }
1403
+ | kYIELD tLPAREN2 rparen
1404
+ {
1405
+ (_, line), _, _ = val
1406
+
1407
+ result = new_yield.line line
1408
+ }
1409
+ | kYIELD
1410
+ {
1411
+ (_, line), = val
1412
+
1413
+ result = new_yield.line line
1414
+ }
1415
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1416
+ {
1417
+ (_, line), _, _, arg, _ = val
1418
+
1419
+ result = s(:defined, arg).line line
1420
+ }
1421
+ | kNOT tLPAREN2 expr rparen
1422
+ {
1423
+ _, _, lhs, _ = val
1424
+ result = new_call lhs, :"!"
1425
+ }
1426
+ | kNOT tLPAREN2 rparen
1427
+ {
1428
+ debug 19
1429
+ }
1430
+ | fcall brace_block
1431
+ {
1432
+ call, iter = val
1433
+
1434
+ iter.insert 1, call
1435
+ result = iter
1436
+ # FIX: probably not: call.line = iter.line
1437
+ }
1438
+ | method_call
1439
+ | method_call brace_block
1440
+ {
1441
+ call, iter = val[0], val[1]
1442
+ block_dup_check call, iter
1443
+ iter.insert 1, call # FIX
1444
+ result = iter
1445
+ }
1446
+ | lambda
1447
+ {
1448
+ expr, = val
1449
+ result = expr
1450
+ }
1451
+ | k_if expr_value then compstmt if_tail k_end
1452
+ {
1453
+ _, c, _, t, f, _ = val
1454
+ result = new_if c, t, f
1455
+ }
1456
+ | k_unless expr_value then compstmt opt_else k_end
1457
+ {
1458
+ _, c, _, t, f, _ = val
1459
+ result = new_if c, f, t
1460
+ }
1461
+ | k_while expr_value_do compstmt k_end
1462
+ {
1463
+ _, cond, body, _ = val
1464
+ result = new_while body, cond, true
1465
+ }
1466
+ | k_until expr_value_do compstmt k_end
1467
+ {
1468
+ _, cond, body, _ = val
1469
+ result = new_until body, cond, true
1470
+ }
1471
+ | k_case expr_value opt_terms case_body k_end
1472
+ {
1473
+ (_, line), expr, _, body, _ = val
1474
+ result = new_case expr, body, line
1475
+ }
1476
+ | k_case opt_terms case_body k_end
1477
+ {
1478
+ (_, line), _, body, _ = val
1479
+ result = new_case nil, body, line
1480
+ }
1481
+ | k_case expr_value opt_terms p_case_body k_end
1482
+ {
1483
+ (_, line), expr, _, body, _ = val
1484
+
1485
+ result = new_case expr, body, line
1486
+ }
1487
+ | k_for for_var kIN expr_value_do compstmt k_end
1488
+ {
1489
+ _, var, _, iter, body, _ = val
1490
+ result = new_for iter, var, body
1491
+ }
1492
+ | k_class
1493
+ {
1494
+ result = self.lexer.lineno
1495
+ }
1496
+ cpath superclass
1497
+ {
1498
+ if (self.in_def || self.in_single > 0) then
1499
+ yyerror "class definition in method body"
1500
+ end
1501
+ self.env.extend
1502
+ }
1503
+ bodystmt k_end
1504
+ {
1505
+ result = new_class val
1506
+ self.env.unextend
1507
+ self.lexer.ignore_body_comments
1508
+ }
1509
+ | k_class tLSHFT
1510
+ {
1511
+ result = self.lexer.lineno
1512
+ }
1513
+ expr
1514
+ {
1515
+ result = self.in_def
1516
+ self.in_def = false
1517
+ }
1518
+ term
1519
+ {
1520
+ result = self.in_single
1521
+ self.in_single = 0
1522
+ self.env.extend
1523
+ }
1524
+ bodystmt k_end
1525
+ {
1526
+ result = new_sclass val
1527
+ self.env.unextend
1528
+ self.lexer.ignore_body_comments
1529
+ }
1530
+ | k_module
1531
+ {
1532
+ result = self.lexer.lineno
1533
+ }
1534
+ cpath
1535
+ {
1536
+ yyerror "module definition in method body" if
1537
+ self.in_def or self.in_single > 0
1538
+
1539
+ self.env.extend
1540
+ }
1541
+ bodystmt k_end
1542
+ {
1543
+ result = new_module val
1544
+ self.env.unextend
1545
+ self.lexer.ignore_body_comments
1546
+ }
1547
+ | defn_head f_arglist bodystmt k_end
1548
+ {
1549
+ # [ [:f, 1, false], s(:args)...]
1550
+ # =>
1551
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1552
+ val.insert 1, val.first.pop
1553
+ val.insert 0, [:k_def, 666]
1554
+
1555
+ result, in_def = new_defn val
1556
+
1557
+ lexer.cond.pop # group = local_pop
1558
+ lexer.cmdarg.pop
1559
+ self.env.unextend
1560
+ self.in_def = in_def
1561
+
1562
+ self.lexer.ignore_body_comments
1563
+ }
1564
+ | defs_head f_arglist bodystmt k_end
1565
+ {
1566
+ # [ [recv, [:name, 1, false]], s(:args...]
1567
+ # =>
1568
+ # [ recv, [:name, 1, false], s(:args...]
1569
+ # =>
1570
+ # [ recv, [:name, 1], false, s(:args...]
1571
+ # =>
1572
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1573
+
1574
+ val.prepend(*val.shift)
1575
+ val.insert 2, val[1].pop
1576
+ val.insert 0, [:k_def, 666]
1577
+
1578
+ result, in_def = new_defs val
1579
+
1580
+ lexer.cond.pop # group = local_pop
1581
+ lexer.cmdarg.pop
1582
+ self.env.unextend
1583
+ self.in_def = in_def
1584
+
1585
+ self.in_single -= 1
1586
+
1587
+ # TODO: restore cur_arg ? what's cur_arg?
1588
+
1589
+ self.lexer.ignore_body_comments
1590
+ }
1591
+ | kBREAK
1592
+ {
1593
+ (_, line), = val
1594
+ result = s(:break).line line
1595
+ }
1596
+ | kNEXT
1597
+ {
1598
+ (_, line), = val
1599
+ result = s(:next).line line
1600
+ }
1601
+ | kREDO
1602
+ {
1603
+ (_, line), = val
1604
+ result = s(:redo).line line
1605
+ }
1606
+ | kRETRY
1607
+ {
1608
+ (_, line), = val
1609
+ result = s(:retry).line line
1610
+ }
1611
+
1612
+ primary_value: primary
1613
+ {
1614
+ result = value_expr(val[0])
1615
+ }
1616
+
1617
+ # These are really stupid
1618
+ k_begin: kBEGIN
1619
+ k_if: kIF
1620
+ k_unless: kUNLESS
1621
+ k_while: kWHILE
1622
+ k_until: kUNTIL
1623
+ k_case: kCASE
1624
+ k_for: kFOR
1625
+ k_class: kCLASS
1626
+ {
1627
+ self.comments.push self.lexer.comments
1628
+ }
1629
+ k_module: kMODULE
1630
+ {
1631
+ self.comments.push self.lexer.comments
1632
+ }
1633
+ k_def: kDEF
1634
+ {
1635
+ self.comments.push self.lexer.comments
1636
+ }
1637
+ k_do: kDO
1638
+ k_do_block: kDO_BLOCK
1639
+ k_rescue: kRESCUE
1640
+ k_ensure: kENSURE
1641
+ k_when: kWHEN
1642
+ k_else: kELSE
1643
+ k_elsif: kELSIF
1644
+ k_end: kEND
1645
+ k_return: kRETURN
1646
+
1647
+ then: term
1648
+ | kTHEN
1649
+ | term kTHEN
1650
+
1651
+ do: term
1652
+ | kDO_COND
1653
+
1654
+ if_tail: opt_else
1655
+ | k_elsif expr_value then compstmt if_tail
1656
+ {
1657
+ (_, line), c, _, t, rest = val
1658
+
1659
+ result = s(:if, c, t, rest).line line
1660
+ }
1661
+
1662
+ opt_else: none
1663
+ | kELSE compstmt
1664
+ {
1665
+ result = val[1]
1666
+ }
1667
+
1668
+ for_var: lhs
1669
+ | mlhs
1670
+ {
1671
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1672
+ }
1673
+
1674
+ f_marg: f_norm_arg
1675
+ | tLPAREN f_margs rparen
1676
+ {
1677
+ result = val[1]
1678
+ }
1679
+
1680
+ f_marg_list: f_marg
1681
+ {
1682
+ sym, = val
1683
+
1684
+ result = s(:array, sym).line lexer.lineno
1685
+ }
1686
+ | f_marg_list tCOMMA f_marg
1687
+ {
1688
+ result = list_append val[0], val[2]
1689
+ }
1690
+
1691
+ f_margs: f_marg_list
1692
+ {
1693
+ args, = val
1694
+
1695
+ result = block_var args
1696
+ }
1697
+ | f_marg_list tCOMMA f_rest_marg
1698
+ {
1699
+ args, _, rest = val
1700
+
1701
+ result = block_var args, rest
1702
+ }
1703
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1704
+ {
1705
+ lhs, _, splat, _, rhs = val
1706
+
1707
+ result = block_var lhs, splat, rhs
1708
+ }
1709
+ | f_rest_marg
1710
+ {
1711
+ rest, = val
1712
+
1713
+ result = block_var rest
1714
+ }
1715
+ | f_rest_marg tCOMMA f_marg_list
1716
+ {
1717
+ splat, _, rest = val
1718
+
1719
+ result = block_var splat, rest
1720
+ }
1721
+
1722
+ f_rest_marg: tSTAR f_norm_arg
1723
+ {
1724
+ _, (id, line) = val
1725
+
1726
+ result = args ["*#{id}".to_sym]
1727
+ result.line line
1728
+ }
1729
+ | tSTAR
1730
+ {
1731
+ result = args [:*]
1732
+ result.line lexer.lineno # FIX: tSTAR -> line
1733
+ }
1734
+
1735
+ f_any_kwrest: f_kwrest
1736
+ | f_no_kwarg
1737
+
1738
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1739
+ {
1740
+ result = call_args val
1741
+ }
1742
+ | f_block_kwarg opt_f_block_arg
1743
+ {
1744
+ result = call_args val
1745
+ }
1746
+ | f_any_kwrest opt_f_block_arg
1747
+ {
1748
+ result = call_args val
1749
+ }
1750
+ | f_block_arg
1751
+ {
1752
+ (id, line), = val
1753
+ result = call_args [id]
1754
+ result.line line
1755
+ }
1756
+
1757
+ opt_block_args_tail: tCOMMA block_args_tail
1758
+ {
1759
+ result = args val
1760
+ }
1761
+ | none
1762
+
1763
+ excessed_comma: tCOMMA
1764
+ {
1765
+ result = s(:WTF_COMMA!)
1766
+ }
1767
+
1768
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1769
+ {
1770
+ result = args val
1771
+ }
1772
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1773
+ {
1774
+ result = args val
1775
+ }
1776
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1777
+ {
1778
+ result = args val
1779
+ }
1780
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1781
+ {
1782
+ result = args val
1783
+ }
1784
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1785
+ {
1786
+ result = args val
1787
+ }
1788
+ | f_arg excessed_comma
1789
+ {
1790
+ arg, _ = val
1791
+ result = arg << nil
1792
+ }
1793
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1794
+ {
1795
+ result = args val
1796
+ }
1797
+ | f_arg opt_block_args_tail
1798
+ {
1799
+ result = args val
1800
+ }
1801
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1802
+ {
1803
+ result = args val
1804
+ }
1805
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1806
+ {
1807
+ result = args val
1808
+ }
1809
+ | f_block_optarg opt_block_args_tail
1810
+ {
1811
+ result = args val
1812
+ }
1813
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1814
+ {
1815
+ result = args val
1816
+ }
1817
+ | f_rest_arg opt_block_args_tail
1818
+ {
1819
+ result = args val
1820
+ }
1821
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1822
+ {
1823
+ result = args val
1824
+ }
1825
+ | block_args_tail
1826
+ {
1827
+ result = args val
1828
+ }
1829
+
1830
+ opt_block_param: none { result = 0 }
1831
+ | block_param_def
1832
+ {
1833
+ self.lexer.command_start = true
1834
+ }
1835
+
1836
+ block_param_def: tPIPE opt_bv_decl tPIPE
1837
+ {
1838
+ # TODO: current_arg = 0
1839
+ result = args val
1840
+ }
1841
+ | tOROP
1842
+ {
1843
+ result = s(:args).line lexer.lineno
1844
+ }
1845
+ | tPIPE block_param opt_bv_decl tPIPE
1846
+ {
1847
+ # TODO: current_arg = 0
1848
+ result = args val
1849
+ }
1850
+
1851
+ opt_bv_decl: opt_nl
1852
+ | opt_nl tSEMI bv_decls opt_nl
1853
+ {
1854
+ result = args val
1855
+ }
1856
+
1857
+ bv_decls: bvar
1858
+ {
1859
+ result = args val
1860
+ }
1861
+ | bv_decls tCOMMA bvar
1862
+ {
1863
+ result = args val
1864
+ }
1865
+
1866
+ bvar: tIDENTIFIER
1867
+ {
1868
+ (id, line), = val
1869
+ result = s(:shadow, id.to_sym).line line
1870
+ }
1871
+ | f_bad_arg
1872
+
1873
+ lambda: tLAMBDA
1874
+ {
1875
+ self.env.extend :dynamic
1876
+ result = [lexer.lineno, lexer.lpar_beg]
1877
+ lexer.paren_nest += 1
1878
+ lexer.lpar_beg = lexer.paren_nest
1879
+ }
1880
+ f_larglist
1881
+ {
1882
+ lexer.cmdarg.push false
1883
+ }
1884
+ lambda_body
1885
+ {
1886
+ _, (line, lpar), args, _cmdarg, body = val
1887
+ lexer.lpar_beg = lpar
1888
+
1889
+ lexer.cmdarg.pop
1890
+
1891
+ call = s(:lambda).line line
1892
+ result = new_iter call, args, body
1893
+ result.line line
1894
+ self.env.unextend # TODO: dynapush & dynapop
1895
+ }
1896
+
1897
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1898
+ {
1899
+ result = args val
1900
+ }
1901
+ | f_args
1902
+ {
1903
+ result = val[0]
1904
+ result = 0 if result == s(:args)
1905
+ }
1906
+
1907
+ lambda_body: tLAMBEG compstmt tRCURLY
1908
+ {
1909
+ result = val[1]
1910
+ }
1911
+ | kDO_LAMBDA bodystmt kEND
1912
+ {
1913
+ result = val[1]
1914
+ }
1915
+
1916
+ do_block: k_do_block do_body kEND
1917
+ {
1918
+ (_, line), iter, _ = val
1919
+ result = iter.line line
1920
+ }
1921
+
1922
+ block_call: command do_block
1923
+ {
1924
+ # TODO:
1925
+ ## if (nd_type($1) == NODE_YIELD) {
1926
+ ## compile_error(PARSER_ARG "block given to yield");
1927
+
1928
+ cmd, blk = val
1929
+
1930
+ syntax_error "Both block arg and actual block given." if
1931
+ cmd.block_pass?
1932
+
1933
+ if inverted? val then
1934
+ val = invert_block_call val
1935
+ cmd, blk = val
1936
+ end
1937
+
1938
+ result = blk
1939
+ result.insert 1, cmd
1940
+ }
1941
+ | block_call call_op2 operation2 opt_paren_args
1942
+ {
1943
+ lhs, _, (id, _line), args = val
1944
+
1945
+ result = new_call lhs, id.to_sym, args
1946
+ }
1947
+ | block_call call_op2 operation2 opt_paren_args brace_block
1948
+ {
1949
+ iter1, _, (name, _line), args, iter2 = val
1950
+
1951
+ call = new_call iter1, name.to_sym, args
1952
+ iter2.insert 1, call
1953
+
1954
+ result = iter2
1955
+ }
1956
+ | block_call call_op2 operation2 command_args do_block
1957
+ {
1958
+ iter1, _, (name, _line), args, iter2 = val
1959
+
1960
+ call = new_call iter1, name.to_sym, args
1961
+ iter2.insert 1, call
1962
+
1963
+ result = iter2
1964
+ }
1965
+
1966
+ method_call: fcall paren_args
1967
+ {
1968
+ call, args = val
1969
+
1970
+ result = call.concat args.sexp_body if args
1971
+ }
1972
+ | primary_value call_op operation2 opt_paren_args
1973
+ {
1974
+ recv, call_op, (op, _line), args = val
1975
+
1976
+ result = new_call recv, op.to_sym, args, call_op
1977
+ }
1978
+ | primary_value tCOLON2 operation2 paren_args
1979
+ {
1980
+ recv, _, (op, _line), args = val
1981
+
1982
+ result = new_call recv, op.to_sym, args
1983
+ }
1984
+ | primary_value tCOLON2 operation3
1985
+ {
1986
+ lhs, _, (id, _line) = val
1987
+
1988
+ result = new_call lhs, id.to_sym
1989
+ }
1990
+ | primary_value call_op paren_args
1991
+ {
1992
+ result = new_call val[0], :call, val[2], val[1]
1993
+ }
1994
+ | primary_value tCOLON2 paren_args
1995
+ {
1996
+ result = new_call val[0], :call, val[2]
1997
+ }
1998
+ | kSUPER paren_args
1999
+ {
2000
+ result = new_super val[1]
2001
+ }
2002
+ | kSUPER
2003
+ {
2004
+ result = s(:zsuper).line lexer.lineno
2005
+ }
2006
+ | primary_value tLBRACK2 opt_call_args rbracket
2007
+ {
2008
+ result = new_aref val
2009
+ }
2010
+
2011
+ brace_block: tLCURLY
2012
+ {
2013
+ self.env.extend :dynamic
2014
+ result = self.lexer.lineno
2015
+ }
2016
+ brace_body tRCURLY
2017
+ {
2018
+ _, line, body, _ = val
2019
+
2020
+ result = body
2021
+ result.line line
2022
+
2023
+ self.env.unextend
2024
+ }
2025
+ | k_do
2026
+ {
2027
+ self.env.extend :dynamic
2028
+ result = self.lexer.lineno
2029
+ }
2030
+ do_body kEND
2031
+ {
2032
+ _, line, body, _ = val
2033
+
2034
+ result = body
2035
+ result.line line
2036
+
2037
+ self.env.unextend
2038
+ }
2039
+
2040
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2041
+ { result = lexer.cmdarg.store(false) }
2042
+ opt_block_param compstmt
2043
+ {
2044
+ line, cmdarg, param, cmpstmt = val
2045
+
2046
+ result = new_brace_body param, cmpstmt, line
2047
+ self.env.unextend
2048
+ lexer.cmdarg.restore cmdarg
2049
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
2050
+ }
2051
+
2052
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2053
+ { lexer.cmdarg.push false }
2054
+ opt_block_param
2055
+ bodystmt
2056
+ {
2057
+ line, _cmdarg, param, cmpstmt = val
2058
+
2059
+ result = new_do_body param, cmpstmt, line
2060
+ lexer.cmdarg.pop
2061
+ self.env.unextend
2062
+ }
2063
+
2064
+ case_args: arg_value
2065
+ {
2066
+ arg, = val
2067
+
2068
+ result = s(:array, arg).line arg.line
2069
+ }
2070
+ | tSTAR arg_value
2071
+ {
2072
+ _, arg = val
2073
+
2074
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2075
+ }
2076
+ | case_args tCOMMA arg_value
2077
+ {
2078
+ args, _, id = val
2079
+
2080
+ result = self.list_append args, id
2081
+ }
2082
+ | case_args tCOMMA tSTAR arg_value
2083
+ {
2084
+ args, _, _, id = val
2085
+
2086
+ result = self.list_append args, s(:splat, id).line(id.line)
2087
+ }
2088
+
2089
+ case_body: k_when
2090
+ {
2091
+ result = self.lexer.lineno
2092
+ }
2093
+ case_args then compstmt cases
2094
+ {
2095
+ result = new_when(val[2], val[4])
2096
+ result.line val[1]
2097
+ result << val[5] if val[5]
2098
+ }
2099
+
2100
+ cases: opt_else | case_body
2101
+ ######################################################################
2102
+
2103
+ p_case_body: kIN
2104
+ {
2105
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2106
+ self.lexer.command_start = false
2107
+ result = self.in_kwarg
2108
+ self.in_kwarg = true
2109
+ push_pvtbl
2110
+ push_pktbl
2111
+ }
2112
+ p_top_expr then
2113
+ {
2114
+ pop_pktbl
2115
+ pop_pvtbl
2116
+ old_kwargs = _values[-3]
2117
+ self.in_kwarg = old_kwargs
2118
+ }
2119
+ compstmt
2120
+ p_cases
2121
+ {
2122
+ (_, line), _, pat, _, _, body, cases = val
2123
+
2124
+ result = new_in pat, body, cases, line
2125
+ }
2126
+
2127
+ p_cases: opt_else
2128
+ | p_case_body
2129
+
2130
+ p_top_expr: p_top_expr_body
2131
+ | p_top_expr_body kIF_MOD expr_value
2132
+ {
2133
+ body, _, cond = val
2134
+ body = remove_begin body
2135
+
2136
+ result = s(:if, cond, body, nil).line body.line
2137
+ }
2138
+ | p_top_expr_body kUNLESS_MOD expr_value
2139
+ {
2140
+ body, _, cond = val
2141
+ body = remove_begin body
2142
+
2143
+ result = s(:if, cond, nil, body).line body.line
2144
+ }
2145
+
2146
+ p_top_expr_body: p_expr
2147
+ | p_expr tCOMMA
2148
+ {
2149
+ expr, _ = val
2150
+
2151
+ tail = new_array_pattern_tail nil, true, nil, nil
2152
+ result = new_array_pattern nil, expr, tail, expr.line
2153
+ }
2154
+ | p_expr tCOMMA p_args
2155
+ {
2156
+ expr, _, args = val
2157
+
2158
+ result = new_array_pattern nil, expr, args, expr.line
2159
+ }
2160
+ | p_find
2161
+ {
2162
+ find, = val
2163
+
2164
+ result = new_find_pattern nil, find
2165
+ }
2166
+ | p_args_tail
2167
+ {
2168
+ args, = val
2169
+ result = new_array_pattern nil, nil, args, args.line
2170
+ }
2171
+ | p_kwargs
2172
+ {
2173
+ kwargs, = val
2174
+ result = new_hash_pattern nil, kwargs, kwargs.line
2175
+ }
2176
+
2177
+ p_expr: p_as
2178
+
2179
+ p_as: p_expr tASSOC p_variable
2180
+ {
2181
+ # NODE *n = NEW_LIST($1, &@$);
2182
+ # n = list_append(p, n, $3);
2183
+ # $$ = new_hash(p, n, &@$);
2184
+
2185
+ expr, _, var = val
2186
+
2187
+ id = var.last
2188
+
2189
+ self.env[id] = :lvar # HACK: need to extend env
2190
+ lhs = s(:lasgn, id).line var.line
2191
+
2192
+ result = new_assign lhs, expr
2193
+ }
2194
+ | p_alt
2195
+
2196
+ p_alt: p_alt tPIPE p_expr_basic
2197
+ {
2198
+ lhs, _, rhs = val
2199
+
2200
+ result = s(:or, lhs, rhs).line lhs.line
2201
+ }
2202
+ | p_expr_basic
2203
+
2204
+ p_lparen: tLPAREN2 { push_pktbl }
2205
+ p_lbracket: tLBRACK2 { push_pktbl }
2206
+
2207
+ p_expr_basic: p_value
2208
+ | p_const p_lparen p_args tRPAREN
2209
+ {
2210
+ lhs, _, args, _ = val
2211
+
2212
+ pop_pktbl
2213
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2214
+ }
2215
+ | p_const p_lparen p_find tRPAREN
2216
+ {
2217
+ const, _, find, _ = val
2218
+
2219
+ pop_pktbl
2220
+ result = new_find_pattern(const, find).line const.line
2221
+ }
2222
+ | p_const p_lparen p_kwargs tRPAREN
2223
+ {
2224
+ lhs, _, kwargs, _ = val
2225
+
2226
+ pop_pktbl
2227
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2228
+ }
2229
+ | p_const tLPAREN2 tRPAREN
2230
+ {
2231
+ const, _, _ = val
2232
+
2233
+ tail = new_array_pattern_tail nil, nil, nil, nil
2234
+ result = new_array_pattern const, nil, tail, const.line
2235
+ }
2236
+ | p_const p_lbracket p_args rbracket
2237
+ {
2238
+ const, _, pre_arg, _ = val
2239
+
2240
+ pop_pktbl
2241
+ result = new_array_pattern const, nil, pre_arg, const.line
2242
+ }
2243
+ | p_const p_lbracket p_find rbracket
2244
+ {
2245
+ const, _, find, _ = val
2246
+
2247
+ pop_pktbl
2248
+ result = new_find_pattern(const, find).line const.line
2249
+ }
2250
+ | p_const p_lbracket p_kwargs rbracket
2251
+ {
2252
+ const, _, kwargs, _ = val
2253
+
2254
+ result = new_hash_pattern const, kwargs, const.line
2255
+ }
2256
+ | p_const tLBRACK2 rbracket
2257
+ {
2258
+ const, _, _ = val
2259
+
2260
+ tail = new_array_pattern_tail nil, nil, nil, nil
2261
+ result = new_array_pattern const, nil, tail, const.line
2262
+ }
2263
+ | tLBRACK p_args rbracket
2264
+ {
2265
+ _, pat, _ = val
2266
+
2267
+ result = new_array_pattern nil, nil, pat, pat.line
2268
+ }
2269
+ | tLBRACK p_find rbracket
2270
+ {
2271
+ _, find, _ = val
2272
+
2273
+ result = new_find_pattern nil, find
2274
+ }
2275
+ | tLBRACK rbracket
2276
+ {
2277
+ (_, line), _ = val
2278
+
2279
+ result = s(:array_pat).line line
2280
+ }
2281
+ | tLBRACE
2282
+ {
2283
+ push_pktbl
2284
+ result = self.in_kwarg
2285
+ self.in_kwarg = false
2286
+ }
2287
+ p_kwargs rbrace
2288
+ {
2289
+ _, in_kwarg, kwargs, _ = val
2290
+
2291
+ pop_pktbl
2292
+ self.in_kwarg = in_kwarg
2293
+
2294
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2295
+ }
2296
+ | tLBRACE rbrace
2297
+ {
2298
+ (_, line), _ = val
2299
+
2300
+ tail = new_hash_pattern_tail nil, nil, line
2301
+ result = new_hash_pattern nil, tail, line
2302
+ }
2303
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2304
+ {
2305
+ _, _, expr, _ = val
2306
+
2307
+ pop_pktbl
2308
+ result = expr
2309
+ }
2310
+
2311
+ p_args: p_expr
2312
+ {
2313
+ expr, = val
2314
+
2315
+ ary = s(:array_TAIL, expr).line expr.line
2316
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2317
+ }
2318
+ | p_args_head
2319
+ {
2320
+ head, = val
2321
+
2322
+ result = new_array_pattern_tail head, true, nil, nil
2323
+ }
2324
+ | p_args_head p_arg
2325
+ {
2326
+ head, tail = val
2327
+
2328
+ both = array_pat_concat head, tail
2329
+
2330
+ result = new_array_pattern_tail both, nil, nil, nil
2331
+ result.line head.line
2332
+ }
2333
+ | p_args_head tSTAR tIDENTIFIER
2334
+ {
2335
+ head, _, (id, _line) = val
2336
+
2337
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2338
+ result.line head.line
2339
+ }
2340
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2341
+ {
2342
+ head, _, (id, _line), _, post = val
2343
+
2344
+ result = new_array_pattern_tail head, true, id.to_sym, post
2345
+ result.line head.line
2346
+ }
2347
+ | p_args_head tSTAR
2348
+ {
2349
+ expr, _ = val
2350
+
2351
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2352
+ }
2353
+ | p_args_head tSTAR tCOMMA p_args_post
2354
+ {
2355
+ head, _, _, post = val
2356
+
2357
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2358
+ }
2359
+ | p_args_tail
2360
+
2361
+ p_args_head: p_arg tCOMMA
2362
+ {
2363
+ arg, _ = val
2364
+ result = arg
2365
+ }
2366
+ | p_args_head p_arg tCOMMA
2367
+ {
2368
+ head, tail, _ = val
2369
+
2370
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2371
+ result.line head.line
2372
+ }
2373
+
2374
+ p_args_tail: p_rest
2375
+ {
2376
+ (id, line), = val
2377
+
2378
+ result = new_array_pattern_tail nil, true, id, nil
2379
+ result.line line
2380
+ }
2381
+ | p_rest tCOMMA p_args_post
2382
+ {
2383
+ (id, line), _, rhs = val
2384
+
2385
+ result = new_array_pattern_tail nil, true, id, rhs
2386
+ result.line line
2387
+ }
2388
+
2389
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2390
+ {
2391
+ lhs, _, mid, _, rhs = val
2392
+
2393
+ result = new_find_pattern_tail lhs, mid, rhs
2394
+ }
2395
+
2396
+ p_rest: tSTAR tIDENTIFIER
2397
+ {
2398
+ _, (id, line) = val
2399
+
2400
+ result = [id.to_sym, line]
2401
+ }
2402
+ | tSTAR
2403
+ {
2404
+ (_id, line), = val
2405
+
2406
+ result = [nil, line]
2407
+ }
2408
+
2409
+ p_args_post: p_arg
2410
+ | p_args_post tCOMMA p_arg
2411
+ {
2412
+ lhs, _, rhs = val
2413
+
2414
+ result = array_pat_concat lhs, rhs
2415
+ }
2416
+
2417
+ p_arg: p_expr
2418
+ {
2419
+ expr, = val
2420
+ expr = s(:array_TAIL, expr).line expr.line unless
2421
+ expr.sexp_type == :array_TAIL
2422
+ result = expr
2423
+ }
2424
+
2425
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2426
+ {
2427
+ kw_arg, _, rest = val
2428
+ # TODO? new_unique_key_hash(p, $1, &@$)
2429
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2430
+ }
2431
+ | p_kwarg
2432
+ {
2433
+ kwarg, = val
2434
+ # TODO? new_unique_key_hash(p, $1, &@$)
2435
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2436
+ }
2437
+ | p_kwarg tCOMMA
2438
+ {
2439
+ kwarg, _ = val
2440
+ # TODO? new_unique_key_hash(p, $1, &@$)
2441
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2442
+ }
2443
+ | p_any_kwrest
2444
+ {
2445
+ rest, = val
2446
+
2447
+ result = new_hash_pattern_tail nil, rest, rest.line
2448
+ }
2449
+
2450
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2451
+ | p_kwarg tCOMMA p_kw
2452
+ {
2453
+ kwarg, _, kw = val
2454
+ kwarg.concat kw.sexp_body
2455
+ result = kwarg
2456
+ }
2457
+
2458
+ p_kw: p_kw_label p_expr
2459
+ {
2460
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2461
+ lhs, rhs = val
2462
+
2463
+ result = s(:PAIR, lhs, rhs).line lhs.line
2464
+ }
2465
+ | p_kw_label
2466
+ {
2467
+ lhs, = val
2468
+
2469
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2470
+
2471
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2472
+ # yyerror1(&@1, "key must be valid as local variables");
2473
+ # }
2474
+
2475
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2476
+ # assignable(p, $1, 0, &@$));
2477
+
2478
+ case lhs.sexp_type
2479
+ when :lit then
2480
+ assignable [lhs.value, lhs.line]
2481
+ else
2482
+ # TODO or done?
2483
+ debug 666
2484
+ end
2485
+
2486
+ # TODO PAIR -> LIST ?
2487
+ result = s(:PAIR, lhs, nil).line lhs.line
2488
+ }
2489
+
2490
+ p_kw_label: tLABEL
2491
+ {
2492
+ (id, line), = val
2493
+
2494
+ result = s(:lit, id.to_sym).line line
2495
+ }
2496
+
2497
+ p_kwrest: kwrest_mark tIDENTIFIER
2498
+ {
2499
+ _, (id, line) = val
2500
+
2501
+ name = id.to_sym
2502
+ self.assignable [name, line]
2503
+ result = s(:kwrest, :"**#{name}").line line
2504
+ }
2505
+ | kwrest_mark
2506
+ {
2507
+ (_, line), = val
2508
+
2509
+ result = s(:kwrest, :"**").line line
2510
+ }
2511
+
2512
+ p_kwnorest: kwrest_mark kNIL
2513
+ {
2514
+ (_, line), _ = val
2515
+
2516
+ # TODO: or s(:norest)? s(:**nil)?
2517
+ result = s(:kwrest, :"**nil").line line
2518
+ }
2519
+
2520
+ p_any_kwrest: p_kwrest
2521
+ | p_kwnorest
2522
+
2523
+ p_value: p_primitive
2524
+ | p_primitive tDOT2 p_primitive
2525
+ {
2526
+ lhs, _, rhs = val
2527
+
2528
+ lhs = value_expr lhs
2529
+ rhs = value_expr rhs
2530
+
2531
+ result = s(:dot2, lhs, rhs).line lhs.line
2532
+ }
2533
+ | p_primitive tDOT3 p_primitive
2534
+ {
2535
+ lhs, _, rhs = val
2536
+
2537
+ lhs = value_expr lhs
2538
+ rhs = value_expr rhs
2539
+
2540
+ result = s(:dot3, lhs, rhs).line lhs.line
2541
+ }
2542
+ | p_primitive tDOT2
2543
+ {
2544
+ v1, _ = val
2545
+
2546
+ result = s(:dot2, v1, nil).line v1.line
2547
+ }
2548
+ | p_primitive tDOT3
2549
+ {
2550
+ v1, _ = val
2551
+
2552
+ result = s(:dot3, v1, nil).line v1.line
2553
+ }
2554
+ | p_variable
2555
+ | p_var_ref
2556
+ | p_const
2557
+ | tBDOT2 p_primitive
2558
+ {
2559
+ _, v1 = val
2560
+
2561
+ result = s(:dot2, nil, v1).line v1.line
2562
+ }
2563
+ | tBDOT3 p_primitive
2564
+ {
2565
+ _, v1 = val
2566
+
2567
+ result = s(:dot3, nil, v1).line v1.line
2568
+ }
2569
+
2570
+ p_primitive: literal
2571
+ | strings
2572
+ | xstring
2573
+ | regexp
2574
+ | words
2575
+ | qwords
2576
+ | symbols
2577
+ | qsymbols
2578
+ | keyword_variable
2579
+ {
2580
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2581
+ var, = val
2582
+
2583
+ result = var
2584
+ }
2585
+ | lambda
2586
+
2587
+ p_variable: tIDENTIFIER
2588
+ {
2589
+ (id, line), = val
2590
+
2591
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2592
+ # TODO: assignable(p, $1, 0, &@$);
2593
+ result = s(:lvar, id.to_sym).line line
2594
+ }
2595
+
2596
+ p_var_ref: tCARET tIDENTIFIER
2597
+ {
2598
+ _, (id, line) = val
2599
+
2600
+ # TODO: check id against env for lvar or dvar
2601
+
2602
+ result = s(:lvar, id.to_sym).line line
2603
+ }
2604
+
2605
+ p_const: tCOLON3 cname
2606
+ {
2607
+ _, (id, line) = val
2608
+ result = s(:colon3, id.to_sym).line line
2609
+ }
2610
+ | p_const tCOLON2 cname
2611
+ {
2612
+ lhs, _, (id, _line) = val
2613
+
2614
+ l = lhs.line
2615
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2616
+ }
2617
+ | tCONSTANT
2618
+ {
2619
+ # TODO $$ = gettable(p, $1, &@$);
2620
+ (id, line), = val
2621
+ result = s(:const, id.to_sym).line line
2622
+ }
2623
+ ######################################################################
2624
+
2625
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2626
+ {
2627
+ (_, line), klasses, var, _, body, rest = val
2628
+
2629
+ klasses ||= s(:array)
2630
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2631
+ klasses.line line
2632
+
2633
+ result = new_resbody(klasses, body)
2634
+ result << rest if rest # UGH, rewritten above
2635
+ }
2636
+ |
2637
+ {
2638
+ result = nil
2639
+ }
2640
+
2641
+ exc_list: arg_value
2642
+ {
2643
+ arg, = val
2644
+ result = s(:array, arg).line arg.line
2645
+ }
2646
+ | mrhs
2647
+ | none
2648
+
2649
+ exc_var: tASSOC lhs
2650
+ {
2651
+ result = val[1]
2652
+ }
2653
+ | none
2654
+
2655
+ opt_ensure: k_ensure compstmt
2656
+ {
2657
+ (_, line), body = val
2658
+
2659
+ result = body || s(:nil).line(line)
2660
+ }
2661
+ | none
2662
+
2663
+ literal: numeric
2664
+ {
2665
+ (lit, line), = val
2666
+ result = s(:lit, lit).line line
2667
+ }
2668
+ | symbol
2669
+
2670
+ strings: string
2671
+ {
2672
+ str, = val
2673
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2674
+ result = str
2675
+ }
2676
+
2677
+ string: tCHAR
2678
+ {
2679
+ debug 36
2680
+ }
2681
+ | string1
2682
+ | string string1
2683
+ {
2684
+ result = self.literal_concat val[0], val[1]
2685
+ }
2686
+
2687
+ string1: tSTRING_BEG string_contents tSTRING_END
2688
+ {
2689
+ (_, line), str, (_, func) = val
2690
+
2691
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2692
+
2693
+ result = str.line line
2694
+ }
2695
+ | tSTRING
2696
+ {
2697
+ result = new_string val
2698
+ }
2699
+
2700
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2701
+ {
2702
+ result = new_xstring val
2703
+ # TODO: dedent?!?! SERIOUSLY?!?
2704
+ }
2705
+
2706
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2707
+ {
2708
+ result = new_regexp val
2709
+ }
2710
+
2711
+ words: tWORDS_BEG tSPACE tSTRING_END
2712
+ {
2713
+ (_, line), _, _ = val
2714
+
2715
+ result = s(:array).line line
2716
+ }
2717
+ | tWORDS_BEG word_list tSTRING_END
2718
+ {
2719
+ (_, line), list, _ = val
2720
+
2721
+ result = list.line line
2722
+ }
2723
+
2724
+ word_list: none
2725
+ {
2726
+ result = new_word_list
2727
+ }
2728
+ | word_list word tSPACE
2729
+ {
2730
+ result = val[0].dup << new_word_list_entry(val)
2731
+ }
2732
+
2733
+ word: string_content
2734
+ | word string_content
2735
+ {
2736
+ result = self.literal_concat val[0], val[1]
2737
+ }
2738
+
2739
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2740
+ {
2741
+ (_, line), _, _ = val
2742
+
2743
+ result = s(:array).line line
2744
+ }
2745
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2746
+ {
2747
+ (_, line), list, _, = val
2748
+ list.line line
2749
+ result = list
2750
+ }
2751
+
2752
+ symbol_list: none
2753
+ {
2754
+ result = new_symbol_list
2755
+ }
2756
+ | symbol_list word tSPACE
2757
+ {
2758
+ list, * = val
2759
+ result = list.dup << new_symbol_list_entry(val)
2760
+ }
2761
+
2762
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2763
+ {
2764
+ (_, line), _, _ = val
2765
+
2766
+ result = s(:array).line line
2767
+ }
2768
+ | tQWORDS_BEG qword_list tSTRING_END
2769
+ {
2770
+ (_, line), list, _ = val
2771
+
2772
+ result = list.line line
2773
+ }
2774
+
2775
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2776
+ {
2777
+ (_, line), _, _ = val
2778
+
2779
+ result = s(:array).line line
2780
+ }
2781
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2782
+ {
2783
+ (_, line), list, _ = val
2784
+
2785
+ result = list.line line
2786
+ }
2787
+
2788
+ qword_list: none
2789
+ {
2790
+ result = new_qword_list
2791
+ }
2792
+ | qword_list tSTRING_CONTENT tSPACE
2793
+ {
2794
+ result = val[0].dup << new_qword_list_entry(val)
2795
+ }
2796
+
2797
+ qsym_list: none
2798
+ {
2799
+ result = new_qsym_list
2800
+ }
2801
+ | qsym_list tSTRING_CONTENT tSPACE
2802
+ {
2803
+ result = val[0].dup << new_qsym_list_entry(val)
2804
+ }
2805
+
2806
+ string_contents: none
2807
+ {
2808
+ line = prev_value_to_lineno _values.last
2809
+ result = s(:str, +"").line line
2810
+ }
2811
+ | string_contents string_content
2812
+ {
2813
+ v1, v2 = val
2814
+ result = literal_concat v1, v2
2815
+ }
2816
+
2817
+ xstring_contents: none
2818
+ {
2819
+ result = nil
2820
+ }
2821
+ | xstring_contents string_content
2822
+ {
2823
+ v1, v2 = val
2824
+ result = literal_concat v1, v2
2825
+ }
2826
+
2827
+ regexp_contents: none
2828
+ {
2829
+ result = nil
2830
+ }
2831
+ | regexp_contents string_content
2832
+ {
2833
+ v1, v2 = val
2834
+ result = literal_concat v1, v2
2835
+ }
2836
+
2837
+ string_content: tSTRING_CONTENT
2838
+ {
2839
+ result = new_string val
2840
+ }
2841
+ | tSTRING_DVAR
2842
+ {
2843
+ result = lexer.lex_strterm
2844
+
2845
+ lexer.lex_strterm = nil
2846
+ lexer.lex_state = EXPR_BEG
2847
+ }
2848
+ string_dvar
2849
+ {
2850
+ _, strterm, str = val
2851
+ lexer.lex_strterm = strterm
2852
+ result = s(:evstr, str).line str.line
2853
+ }
2854
+ | tSTRING_DBEG
2855
+ {
2856
+ result = [lexer.lex_strterm,
2857
+ lexer.brace_nest,
2858
+ lexer.string_nest, # TODO: remove
2859
+ lexer.lex_state,
2860
+ lexer.lineno,
2861
+ ]
2862
+
2863
+ lexer.cmdarg.push false
2864
+ lexer.cond.push false
2865
+
2866
+ lexer.lex_strterm = nil
2867
+ lexer.brace_nest = 0
2868
+ lexer.string_nest = 0
2869
+
2870
+ lexer.lex_state = EXPR_BEG
2871
+ }
2872
+ compstmt
2873
+ tSTRING_DEND
2874
+ {
2875
+ _, memo, stmt, _ = val
2876
+
2877
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2878
+ # TODO: heredoc_indent
2879
+
2880
+ lexer.lex_strterm = lex_strterm
2881
+ lexer.brace_nest = brace_nest
2882
+ lexer.string_nest = string_nest
2883
+
2884
+ lexer.cond.pop
2885
+ lexer.cmdarg.pop
2886
+
2887
+ lexer.lex_state = oldlex_state
2888
+
2889
+ case stmt
2890
+ when Sexp then
2891
+ case stmt.sexp_type
2892
+ when :str, :dstr, :evstr then
2893
+ result = stmt
2894
+ else
2895
+ result = s(:evstr, stmt).line line
2896
+ end
2897
+ when nil then
2898
+ result = s(:evstr).line line
2899
+ else
2900
+ debug 37
2901
+ raise "unknown string body: #{stmt.inspect}"
2902
+ end
2903
+ }
2904
+
2905
+ string_dvar: tGVAR
2906
+ {
2907
+ (id, line), = val
2908
+ result = s(:gvar, id.to_sym).line line
2909
+ }
2910
+ | tIVAR
2911
+ {
2912
+ (id, line), = val
2913
+ result = s(:ivar, id.to_sym).line line
2914
+ }
2915
+ | tCVAR
2916
+ {
2917
+ (id, line), = val
2918
+ result = s(:cvar, id.to_sym).line line
2919
+ }
2920
+ | backref
2921
+
2922
+ symbol: ssym
2923
+ | dsym
2924
+
2925
+ ssym: tSYMBEG sym
2926
+ {
2927
+ _, (id, line) = val
2928
+
2929
+ lexer.lex_state = EXPR_END
2930
+ result = s(:lit, id.to_sym).line line
2931
+ }
2932
+ | tSYMBOL
2933
+ {
2934
+ (id, line), = val
2935
+
2936
+ lexer.lex_state = EXPR_END
2937
+ result = s(:lit, id.to_sym).line line
2938
+ }
2939
+
2940
+ sym: fname | tIVAR | tGVAR | tCVAR
2941
+
2942
+ dsym: tSYMBEG string_contents tSTRING_END
2943
+ {
2944
+ _, result, _ = val
2945
+
2946
+ lexer.lex_state = EXPR_END
2947
+
2948
+ result ||= s(:str, "").line lexer.lineno
2949
+
2950
+ case result.sexp_type
2951
+ when :dstr then
2952
+ result.sexp_type = :dsym
2953
+ when :str then
2954
+ result = s(:lit, result.last.to_sym).line result.line
2955
+ when :evstr then
2956
+ result = s(:dsym, "", result).line result.line
2957
+ else
2958
+ debug 38
2959
+ end
2960
+ }
2961
+
2962
+ numeric: simple_numeric
2963
+ | tUMINUS_NUM simple_numeric =tLOWEST
2964
+ {
2965
+ _, (num, line) = val
2966
+ result = [-num, line]
2967
+ }
2968
+
2969
+ simple_numeric: tINTEGER
2970
+ | tFLOAT
2971
+ | tRATIONAL
2972
+ | tIMAGINARY
2973
+
2974
+ user_variable: tIDENTIFIER
2975
+ | tIVAR
2976
+ | tGVAR
2977
+ | tCONSTANT
2978
+ | tCVAR
2979
+
2980
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2981
+ | kSELF { result = s(:self).line lexer.lineno }
2982
+ | kTRUE { result = s(:true).line lexer.lineno }
2983
+ | kFALSE { result = s(:false).line lexer.lineno }
2984
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2985
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2986
+ | k__ENCODING__
2987
+ {
2988
+ l = lexer.lineno
2989
+ result =
2990
+ if defined? Encoding then
2991
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2992
+ else
2993
+ s(:str, "Unsupported!").line l
2994
+ end
2995
+ }
2996
+
2997
+ var_ref: user_variable
2998
+ {
2999
+ raise "NO: #{val.inspect}" if Sexp === val.first
3000
+ (var, line), = val
3001
+ result = Sexp === var ? var : self.gettable(var)
3002
+
3003
+ result.line line
3004
+ }
3005
+ | keyword_variable
3006
+ {
3007
+ var = val[0]
3008
+ result = Sexp === var ? var : self.gettable(var)
3009
+ }
3010
+
3011
+ var_lhs: user_variable
3012
+ {
3013
+ result = self.assignable val[0]
3014
+ }
3015
+ | keyword_variable
3016
+ {
3017
+ result = self.assignable val[0]
3018
+ debug 39
3019
+ }
3020
+
3021
+ backref: tNTH_REF
3022
+ {
3023
+ (ref, line), = val
3024
+ result = s(:nth_ref, ref).line line
3025
+ }
3026
+ | tBACK_REF
3027
+ {
3028
+ (ref, line), = val
3029
+ result = s(:back_ref, ref).line line
3030
+ }
3031
+
3032
+ superclass: tLT
3033
+ {
3034
+ lexer.lex_state = EXPR_BEG
3035
+ lexer.command_start = true
3036
+ }
3037
+ expr_value term
3038
+ {
3039
+ result = val[2]
3040
+ }
3041
+ | none
3042
+ {
3043
+ result = nil
3044
+ }
3045
+
3046
+ f_opt_paren_args: f_paren_args
3047
+ | none
3048
+ {
3049
+ result = end_args val
3050
+ }
3051
+
3052
+ f_paren_args: tLPAREN2 f_args rparen
3053
+ {
3054
+ result = end_args val
3055
+ }
3056
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3057
+ {
3058
+ result = end_args val
3059
+ }
3060
+ | tLPAREN2 args_forward rparen
3061
+ {
3062
+ result = end_args val
3063
+ }
3064
+
3065
+ f_arglist: f_paren_args
3066
+ | {
3067
+ result = self.in_kwarg
3068
+ self.in_kwarg = true
3069
+ self.lexer.lex_state |= EXPR_LABEL
3070
+ }
3071
+ f_args term
3072
+ {
3073
+ result = end_args val
3074
+ }
3075
+
3076
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
3077
+ {
3078
+ result = args val
3079
+ }
3080
+ | f_kwarg opt_f_block_arg
3081
+ {
3082
+ result = args val
3083
+ }
3084
+ | f_any_kwrest opt_f_block_arg
3085
+ {
3086
+ result = args val
3087
+ }
3088
+ | f_block_arg
3089
+
3090
+ opt_args_tail: tCOMMA args_tail
3091
+ {
3092
+ result = val[1]
3093
+ }
3094
+ |
3095
+ {
3096
+ result = nil
3097
+ }
3098
+
3099
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
3100
+ {
3101
+ result = args val
3102
+ }
3103
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3104
+ {
3105
+ result = args val
3106
+ }
3107
+ | f_arg tCOMMA f_optarg opt_args_tail
3108
+ {
3109
+ result = args val
3110
+ }
3111
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
3112
+ {
3113
+ result = args val
3114
+ }
3115
+ | f_arg tCOMMA f_rest_arg opt_args_tail
3116
+ {
3117
+ result = args val
3118
+ }
3119
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3120
+ {
3121
+ result = args val
3122
+ }
3123
+ | f_arg opt_args_tail
3124
+ {
3125
+ result = args val
3126
+ }
3127
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
3128
+ {
3129
+ result = args val
3130
+ }
3131
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3132
+ {
3133
+ result = args val
3134
+ }
3135
+ | f_optarg opt_args_tail
3136
+ {
3137
+ result = args val
3138
+ }
3139
+ | f_optarg tCOMMA f_arg opt_args_tail
3140
+ {
3141
+ result = args val
3142
+ }
3143
+ | f_rest_arg opt_args_tail
3144
+ {
3145
+ result = args val
3146
+ }
3147
+ | f_rest_arg tCOMMA f_arg opt_args_tail
3148
+ {
3149
+ result = args val
3150
+ }
3151
+ | args_tail
3152
+ {
3153
+ result = args val
3154
+ }
3155
+ |
3156
+ {
3157
+ result = args val
3158
+ # result.line lexer.lineno
3159
+ }
3160
+
3161
+ args_forward: tBDOT3
3162
+ {
3163
+ result = s(:forward_args).line lexer.lineno
3164
+ }
3165
+
3166
+ f_bad_arg: tCONSTANT
3167
+ {
3168
+ yyerror "formal argument cannot be a constant"
3169
+ }
3170
+ | tIVAR
3171
+ {
3172
+ yyerror "formal argument cannot be an instance variable"
3173
+ }
3174
+ | tGVAR
3175
+ {
3176
+ yyerror "formal argument cannot be a global variable"
3177
+ }
3178
+ | tCVAR
3179
+ {
3180
+ yyerror "formal argument cannot be a class variable"
3181
+ }
3182
+
3183
+ f_norm_arg: f_bad_arg
3184
+ | tIDENTIFIER
3185
+ {
3186
+ (id, line), = val
3187
+ identifier = id.to_sym
3188
+ self.env[identifier] = :lvar
3189
+
3190
+ result = [identifier, line]
3191
+ }
3192
+
3193
+ f_arg_asgn: f_norm_arg
3194
+
3195
+ f_arg_item: f_arg_asgn
3196
+ | tLPAREN f_margs rparen
3197
+ {
3198
+ _, margs, _ = val
3199
+
3200
+ result = margs
3201
+ }
3202
+
3203
+ f_arg: f_arg_item
3204
+ {
3205
+ result = new_arg val
3206
+ }
3207
+ | f_arg tCOMMA f_arg_item
3208
+ {
3209
+ list, _, item = val
3210
+
3211
+ if list.sexp_type == :args then
3212
+ result = list
3213
+ else
3214
+ result = s(:args, list).line list.line
3215
+ end
3216
+
3217
+ result << (Sexp === item ? item : item.first)
3218
+ }
3219
+
3220
+ f_label: tLABEL
3221
+
3222
+ f_kw: f_label arg_value
3223
+ {
3224
+ # TODO: new_kw_arg
3225
+ (label, line), arg = val
3226
+
3227
+ identifier = label.to_sym
3228
+ self.env[identifier] = :lvar
3229
+
3230
+ kwarg = s(:kwarg, identifier, arg).line line
3231
+ result = s(:array, kwarg).line line
3232
+ }
3233
+ | f_label
3234
+ {
3235
+ (label, line), = val
3236
+
3237
+ id = label.to_sym
3238
+ self.env[id] = :lvar
3239
+
3240
+ result = s(:array, s(:kwarg, id).line(line)).line line
3241
+ }
3242
+
3243
+ f_block_kw: f_label primary_value
3244
+ {
3245
+ # TODO: new_kw_arg
3246
+ (label, line), expr = val
3247
+ id = label.to_sym
3248
+ self.env[id] = :lvar
3249
+
3250
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
3251
+ }
3252
+ | f_label
3253
+ {
3254
+ # TODO: new_kw_arg
3255
+ (label, line), = val
3256
+ id = label.to_sym
3257
+ self.env[id] = :lvar
3258
+
3259
+ result = s(:array, s(:kwarg, id).line(line)).line line
3260
+ }
3261
+
3262
+ f_block_kwarg: f_block_kw
3263
+ | f_block_kwarg tCOMMA f_block_kw
3264
+ {
3265
+ list, _, item = val
3266
+ result = list << item.last
3267
+ }
3268
+
3269
+ f_kwarg: f_kw
3270
+ | f_kwarg tCOMMA f_kw
3271
+ {
3272
+ result = args val
3273
+ }
3274
+
3275
+ kwrest_mark: tPOW
3276
+ | tDSTAR
3277
+
3278
+ f_no_kwarg: kwrest_mark kNIL
3279
+ {
3280
+ (_, line), _ = val
3281
+ result = [:"**nil", line]
3282
+ }
3283
+
3284
+ f_kwrest: kwrest_mark tIDENTIFIER
3285
+ {
3286
+ _, (id, line) = val
3287
+
3288
+ name = id.to_sym
3289
+ self.assignable [name, line]
3290
+ result = [:"**#{name}", line]
3291
+ }
3292
+ | kwrest_mark
3293
+ {
3294
+ id = :"**"
3295
+ self.env[id] = :lvar # TODO: needed?!?
3296
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
3297
+ }
3298
+
3299
+ f_opt: f_arg_asgn tEQL arg_value
3300
+ {
3301
+ lhs, _, rhs = val
3302
+ result = self.assignable lhs, rhs
3303
+ # TODO: detect duplicate names
3304
+ }
3305
+
3306
+ f_block_opt: f_arg_asgn tEQL primary_value
3307
+ {
3308
+ lhs, _, rhs = val
3309
+ result = self.assignable lhs, rhs
3310
+ }
3311
+
3312
+ f_block_optarg: f_block_opt
3313
+ {
3314
+ optblk, = val
3315
+ result = s(:block, optblk).line optblk.line
3316
+ }
3317
+ | f_block_optarg tCOMMA f_block_opt
3318
+ {
3319
+ optarg, _, optblk = val
3320
+ result = optarg
3321
+ result << optblk
3322
+ }
3323
+
3324
+ f_optarg: f_opt
3325
+ {
3326
+ opt, = val
3327
+ result = s(:block, opt).line opt.line
3328
+ }
3329
+ | f_optarg tCOMMA f_opt
3330
+ {
3331
+ result = self.block_append val[0], val[2]
3332
+ }
3333
+
3334
+ restarg_mark: tSTAR2 | tSTAR
3335
+
3336
+ f_rest_arg: restarg_mark tIDENTIFIER
3337
+ {
3338
+ # TODO: differs from parse.y - needs tests
3339
+ _, (id, line) = val
3340
+ name = id.to_sym
3341
+ self.assignable [name, line]
3342
+ result = [:"*#{name}", line]
3343
+ }
3344
+ | restarg_mark
3345
+ {
3346
+ name = :"*"
3347
+ self.env[name] = :lvar
3348
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
3349
+ }
3350
+
3351
+ blkarg_mark: tAMPER2 | tAMPER
3352
+
3353
+ f_block_arg: blkarg_mark tIDENTIFIER
3354
+ {
3355
+ _, (id, line) = val
3356
+ identifier = id.to_sym
3357
+
3358
+ self.env[identifier] = :lvar
3359
+ result = ["&#{identifier}".to_sym, line]
3360
+ }
3361
+
3362
+ opt_f_block_arg: tCOMMA f_block_arg
3363
+ {
3364
+ _, arg = val
3365
+ result = arg
3366
+ }
3367
+ |
3368
+ {
3369
+ result = nil
3370
+ }
3371
+
3372
+ singleton: var_ref
3373
+ | tLPAREN2
3374
+ {
3375
+ lexer.lex_state = EXPR_BEG
3376
+ }
3377
+ expr rparen
3378
+ {
3379
+ result = val[2]
3380
+ yyerror "Can't define single method for literals." if
3381
+ result.sexp_type == :lit
3382
+ }
3383
+
3384
+ assoc_list: none
3385
+ {
3386
+ result = s(:array).line lexer.lineno
3387
+ }
3388
+ | assocs trailer
3389
+
3390
+ assocs: assoc
3391
+ | assocs tCOMMA assoc
3392
+ {
3393
+ list = val[0].dup
3394
+ more = val[2].sexp_body
3395
+ list.push(*more) unless more.empty?
3396
+ result = list
3397
+ result.sexp_type = :hash
3398
+ }
3399
+
3400
+ assoc: arg_value tASSOC arg_value
3401
+ {
3402
+ v1, _, v2 = val
3403
+ result = s(:array, v1, v2).line v1.line
3404
+ }
3405
+ | tLABEL arg_value
3406
+ {
3407
+ (label, line), arg = val
3408
+
3409
+ lit = s(:lit, label.to_sym).line line
3410
+ result = s(:array, lit, arg).line line
3411
+ }
3412
+ | tSTRING_BEG string_contents tLABEL_END arg_value
3413
+ {
3414
+ (_, line), sym, _, value = val
3415
+
3416
+ sym.sexp_type = :dsym
3417
+
3418
+ result = s(:array, sym, value).line line
3419
+ }
3420
+ | tDSTAR arg_value
3421
+ {
3422
+ _, arg = val
3423
+ line = arg.line
3424
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
3425
+ }
3426
+
3427
+ operation: tIDENTIFIER | tCONSTANT | tFID
3428
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
3429
+ operation3: tIDENTIFIER | tFID | op
3430
+ dot_or_colon: tDOT | tCOLON2
3431
+ call_op: tDOT
3432
+ | tLONELY # TODO: rename tANDDOT?
3433
+
3434
+ call_op2: call_op
3435
+ | tCOLON2
3436
+
3437
+ opt_terms: | terms
3438
+ opt_nl: | tNL
3439
+ rparen: opt_nl tRPAREN
3440
+ # TODO:
3441
+ # {
3442
+ # _, close = val
3443
+ # result = [close, lexer.lineno]
3444
+ # }
3445
+ rbracket: opt_nl tRBRACK
3446
+ {
3447
+ _, close = val
3448
+ result = [close, lexer.lineno]
3449
+ }
3450
+ rbrace: opt_nl tRCURLY
3451
+ {
3452
+ _, close = val
3453
+ result = [close, lexer.lineno]
3454
+ }
3455
+ trailer: | tNL | tCOMMA
3456
+
3457
+ term: tSEMI { yyerrok }
3458
+ | tNL
3459
+
3460
+ terms: term
3461
+ | terms tSEMI { yyerrok }
3462
+
3463
+ none: { result = nil; }
3464
+ end
3465
+
3466
+ ---- inner
3467
+
3468
+ require "ruby_lexer"
3469
+ require "ruby_parser_extras"
3470
+ include RubyLexer::State::Values
3471
+
3472
+ # :stopdoc:
3473
+
3474
+ # Local Variables: **
3475
+ # racc-token-length-max:14 **
3476
+ # End: **