ruby_parser 3.15.0 → 3.18.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,3467 @@
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
+ result = new_yield val[2]
1400
+ }
1401
+ | kYIELD tLPAREN2 rparen
1402
+ {
1403
+ result = new_yield
1404
+ }
1405
+ | kYIELD
1406
+ {
1407
+ result = new_yield
1408
+ }
1409
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1410
+ {
1411
+ (_, line), _, _, arg, _ = val
1412
+
1413
+ result = s(:defined, arg).line line
1414
+ }
1415
+ | kNOT tLPAREN2 expr rparen
1416
+ {
1417
+ _, _, lhs, _ = val
1418
+ result = new_call lhs, :"!"
1419
+ }
1420
+ | kNOT tLPAREN2 rparen
1421
+ {
1422
+ debug 19
1423
+ }
1424
+ | fcall brace_block
1425
+ {
1426
+ call, iter = val
1427
+
1428
+ iter.insert 1, call
1429
+ result = iter
1430
+ # FIX: probably not: call.line = iter.line
1431
+ }
1432
+ | method_call
1433
+ | method_call brace_block
1434
+ {
1435
+ call, iter = val[0], val[1]
1436
+ block_dup_check call, iter
1437
+ iter.insert 1, call # FIX
1438
+ result = iter
1439
+ }
1440
+ | lambda
1441
+ {
1442
+ expr, = val
1443
+ result = expr
1444
+ }
1445
+ | k_if expr_value then compstmt if_tail k_end
1446
+ {
1447
+ _, c, _, t, f, _ = val
1448
+ result = new_if c, t, f
1449
+ }
1450
+ | k_unless expr_value then compstmt opt_else k_end
1451
+ {
1452
+ _, c, _, t, f, _ = val
1453
+ result = new_if c, f, t
1454
+ }
1455
+ | k_while expr_value_do compstmt k_end
1456
+ {
1457
+ _, cond, body, _ = val
1458
+ result = new_while body, cond, true
1459
+ }
1460
+ | k_until expr_value_do compstmt k_end
1461
+ {
1462
+ _, cond, body, _ = val
1463
+ result = new_until body, cond, true
1464
+ }
1465
+ | k_case expr_value opt_terms case_body k_end
1466
+ {
1467
+ (_, line), expr, _, body, _ = val
1468
+ result = new_case expr, body, line
1469
+ }
1470
+ | k_case opt_terms case_body k_end
1471
+ {
1472
+ (_, line), _, body, _ = val
1473
+ result = new_case nil, body, line
1474
+ }
1475
+ | k_case expr_value opt_terms p_case_body k_end
1476
+ {
1477
+ (_, line), expr, _, body, _ = val
1478
+
1479
+ result = new_case expr, body, line
1480
+ }
1481
+ | k_for for_var kIN expr_value_do compstmt k_end
1482
+ {
1483
+ _, var, _, iter, body, _ = val
1484
+ result = new_for iter, var, body
1485
+ }
1486
+ | k_class
1487
+ {
1488
+ result = self.lexer.lineno
1489
+ }
1490
+ cpath superclass
1491
+ {
1492
+ if (self.in_def || self.in_single > 0) then
1493
+ yyerror "class definition in method body"
1494
+ end
1495
+ self.env.extend
1496
+ }
1497
+ bodystmt k_end
1498
+ {
1499
+ result = new_class val
1500
+ self.env.unextend
1501
+ self.lexer.ignore_body_comments
1502
+ }
1503
+ | k_class tLSHFT
1504
+ {
1505
+ result = self.lexer.lineno
1506
+ }
1507
+ expr
1508
+ {
1509
+ result = self.in_def
1510
+ self.in_def = false
1511
+ }
1512
+ term
1513
+ {
1514
+ result = self.in_single
1515
+ self.in_single = 0
1516
+ self.env.extend
1517
+ }
1518
+ bodystmt k_end
1519
+ {
1520
+ result = new_sclass val
1521
+ self.env.unextend
1522
+ self.lexer.ignore_body_comments
1523
+ }
1524
+ | k_module
1525
+ {
1526
+ result = self.lexer.lineno
1527
+ }
1528
+ cpath
1529
+ {
1530
+ yyerror "module definition in method body" if
1531
+ self.in_def or self.in_single > 0
1532
+
1533
+ self.env.extend
1534
+ }
1535
+ bodystmt k_end
1536
+ {
1537
+ result = new_module val
1538
+ self.env.unextend
1539
+ self.lexer.ignore_body_comments
1540
+ }
1541
+ | defn_head f_arglist bodystmt k_end
1542
+ {
1543
+ # [ [:f, 1, false], s(:args)...]
1544
+ # =>
1545
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1546
+ val.insert 1, val.first.pop
1547
+ val.insert 0, [:k_def, 666]
1548
+
1549
+ result, in_def = new_defn val
1550
+
1551
+ lexer.cond.pop # group = local_pop
1552
+ lexer.cmdarg.pop
1553
+ self.env.unextend
1554
+ self.in_def = in_def
1555
+
1556
+ self.lexer.ignore_body_comments
1557
+ }
1558
+ | defs_head f_arglist bodystmt k_end
1559
+ {
1560
+ # [ [recv, [:name, 1, false]], s(:args...]
1561
+ # =>
1562
+ # [ recv, [:name, 1, false], s(:args...]
1563
+ # =>
1564
+ # [ recv, [:name, 1], false, s(:args...]
1565
+ # =>
1566
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1567
+
1568
+ val.prepend(*val.shift)
1569
+ val.insert 2, val[1].pop
1570
+ val.insert 0, [:k_def, 666]
1571
+
1572
+ result, in_def = new_defs val
1573
+
1574
+ lexer.cond.pop # group = local_pop
1575
+ lexer.cmdarg.pop
1576
+ self.env.unextend
1577
+ self.in_def = in_def
1578
+
1579
+ self.in_single -= 1
1580
+
1581
+ # TODO: restore cur_arg ? what's cur_arg?
1582
+
1583
+ self.lexer.ignore_body_comments
1584
+ }
1585
+ | kBREAK
1586
+ {
1587
+ (_, line), = val
1588
+ result = s(:break).line line
1589
+ }
1590
+ | kNEXT
1591
+ {
1592
+ (_, line), = val
1593
+ result = s(:next).line line
1594
+ }
1595
+ | kREDO
1596
+ {
1597
+ (_, line), = val
1598
+ result = s(:redo).line line
1599
+ }
1600
+ | kRETRY
1601
+ {
1602
+ (_, line), = val
1603
+ result = s(:retry).line line
1604
+ }
1605
+
1606
+ primary_value: primary
1607
+ {
1608
+ result = value_expr(val[0])
1609
+ }
1610
+
1611
+ # These are really stupid
1612
+ k_begin: kBEGIN
1613
+ k_if: kIF
1614
+ k_unless: kUNLESS
1615
+ k_while: kWHILE
1616
+ k_until: kUNTIL
1617
+ k_case: kCASE
1618
+ k_for: kFOR
1619
+ k_class: kCLASS
1620
+ {
1621
+ self.comments.push self.lexer.comments
1622
+ }
1623
+ k_module: kMODULE
1624
+ {
1625
+ self.comments.push self.lexer.comments
1626
+ }
1627
+ k_def: kDEF
1628
+ {
1629
+ self.comments.push self.lexer.comments
1630
+ }
1631
+ k_do: kDO
1632
+ k_do_block: kDO_BLOCK
1633
+ k_rescue: kRESCUE
1634
+ k_ensure: kENSURE
1635
+ k_when: kWHEN
1636
+ k_else: kELSE
1637
+ k_elsif: kELSIF
1638
+ k_end: kEND
1639
+ k_return: kRETURN
1640
+
1641
+ then: term
1642
+ | kTHEN
1643
+ | term kTHEN
1644
+
1645
+ do: term
1646
+ | kDO_COND
1647
+
1648
+ if_tail: opt_else
1649
+ | k_elsif expr_value then compstmt if_tail
1650
+ {
1651
+ (_, line), c, _, t, rest = val
1652
+
1653
+ result = s(:if, c, t, rest).line line
1654
+ }
1655
+
1656
+ opt_else: none
1657
+ | kELSE compstmt
1658
+ {
1659
+ result = val[1]
1660
+ }
1661
+
1662
+ for_var: lhs
1663
+ | mlhs
1664
+ {
1665
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1666
+ }
1667
+
1668
+ f_marg: f_norm_arg
1669
+ | tLPAREN f_margs rparen
1670
+ {
1671
+ result = val[1]
1672
+ }
1673
+
1674
+ f_marg_list: f_marg
1675
+ {
1676
+ sym, = val
1677
+
1678
+ result = s(:array, sym).line lexer.lineno
1679
+ }
1680
+ | f_marg_list tCOMMA f_marg
1681
+ {
1682
+ result = list_append val[0], val[2]
1683
+ }
1684
+
1685
+ f_margs: f_marg_list
1686
+ {
1687
+ args, = val
1688
+
1689
+ result = block_var args
1690
+ }
1691
+ | f_marg_list tCOMMA f_rest_marg
1692
+ {
1693
+ args, _, rest = val
1694
+
1695
+ result = block_var args, rest
1696
+ }
1697
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1698
+ {
1699
+ lhs, _, splat, _, rhs = val
1700
+
1701
+ result = block_var lhs, splat, rhs
1702
+ }
1703
+ | f_rest_marg
1704
+ {
1705
+ rest, = val
1706
+
1707
+ result = block_var rest
1708
+ }
1709
+ | f_rest_marg tCOMMA f_marg_list
1710
+ {
1711
+ splat, _, rest = val
1712
+
1713
+ result = block_var splat, rest
1714
+ }
1715
+
1716
+ f_rest_marg: tSTAR f_norm_arg
1717
+ {
1718
+ _, (id, line) = val
1719
+
1720
+ result = args ["*#{id}".to_sym]
1721
+ result.line line
1722
+ }
1723
+ | tSTAR
1724
+ {
1725
+ result = args [:*]
1726
+ result.line lexer.lineno # FIX: tSTAR -> line
1727
+ }
1728
+
1729
+ f_any_kwrest: f_kwrest
1730
+ | f_no_kwarg
1731
+
1732
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1733
+ {
1734
+ result = call_args val
1735
+ }
1736
+ | f_block_kwarg opt_f_block_arg
1737
+ {
1738
+ result = call_args val
1739
+ }
1740
+ | f_any_kwrest opt_f_block_arg
1741
+ {
1742
+ result = call_args val
1743
+ }
1744
+ | f_block_arg
1745
+ {
1746
+ (id, line), = val
1747
+ result = call_args [id]
1748
+ result.line line
1749
+ }
1750
+
1751
+ opt_block_args_tail: tCOMMA block_args_tail
1752
+ {
1753
+ result = args val
1754
+ }
1755
+ | none
1756
+
1757
+ excessed_comma: tCOMMA
1758
+ {
1759
+ result = s(:WTF_COMMA!)
1760
+ }
1761
+
1762
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1763
+ {
1764
+ result = args val
1765
+ }
1766
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1767
+ {
1768
+ result = args val
1769
+ }
1770
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1771
+ {
1772
+ result = args val
1773
+ }
1774
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1775
+ {
1776
+ result = args val
1777
+ }
1778
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1779
+ {
1780
+ result = args val
1781
+ }
1782
+ | f_arg excessed_comma
1783
+ {
1784
+ arg, _ = val
1785
+ result = arg << nil
1786
+ }
1787
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1788
+ {
1789
+ result = args val
1790
+ }
1791
+ | f_arg opt_block_args_tail
1792
+ {
1793
+ result = args val
1794
+ }
1795
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1796
+ {
1797
+ result = args val
1798
+ }
1799
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1800
+ {
1801
+ result = args val
1802
+ }
1803
+ | f_block_optarg opt_block_args_tail
1804
+ {
1805
+ result = args val
1806
+ }
1807
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1808
+ {
1809
+ result = args val
1810
+ }
1811
+ | f_rest_arg opt_block_args_tail
1812
+ {
1813
+ result = args val
1814
+ }
1815
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1816
+ {
1817
+ result = args val
1818
+ }
1819
+ | block_args_tail
1820
+ {
1821
+ result = args val
1822
+ }
1823
+
1824
+ opt_block_param: none { result = 0 }
1825
+ | block_param_def
1826
+ {
1827
+ self.lexer.command_start = true
1828
+ }
1829
+
1830
+ block_param_def: tPIPE opt_bv_decl tPIPE
1831
+ {
1832
+ # TODO: current_arg = 0
1833
+ result = args val
1834
+ }
1835
+ | tOROP
1836
+ {
1837
+ result = s(:args).line lexer.lineno
1838
+ }
1839
+ | tPIPE block_param opt_bv_decl tPIPE
1840
+ {
1841
+ # TODO: current_arg = 0
1842
+ result = args val
1843
+ }
1844
+
1845
+ opt_bv_decl: opt_nl
1846
+ | opt_nl tSEMI bv_decls opt_nl
1847
+ {
1848
+ result = args val
1849
+ }
1850
+
1851
+ bv_decls: bvar
1852
+ {
1853
+ result = args val
1854
+ }
1855
+ | bv_decls tCOMMA bvar
1856
+ {
1857
+ result = args val
1858
+ }
1859
+
1860
+ bvar: tIDENTIFIER
1861
+ {
1862
+ (id, line), = val
1863
+ result = s(:shadow, id.to_sym).line line
1864
+ }
1865
+ | f_bad_arg
1866
+
1867
+ lambda: tLAMBDA
1868
+ {
1869
+ self.env.extend :dynamic
1870
+ result = [lexer.lineno, lexer.lpar_beg]
1871
+ lexer.paren_nest += 1
1872
+ lexer.lpar_beg = lexer.paren_nest
1873
+ }
1874
+ f_larglist
1875
+ {
1876
+ lexer.cmdarg.push false
1877
+ }
1878
+ lambda_body
1879
+ {
1880
+ _, (line, lpar), args, _cmdarg, body = val
1881
+ lexer.lpar_beg = lpar
1882
+
1883
+ lexer.cmdarg.pop
1884
+
1885
+ call = s(:lambda).line line
1886
+ result = new_iter call, args, body
1887
+ result.line line
1888
+ self.env.unextend # TODO: dynapush & dynapop
1889
+ }
1890
+
1891
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1892
+ {
1893
+ result = args val
1894
+ }
1895
+ | f_args
1896
+ {
1897
+ result = val[0]
1898
+ result = 0 if result == s(:args)
1899
+ }
1900
+
1901
+ lambda_body: tLAMBEG compstmt tRCURLY
1902
+ {
1903
+ result = val[1]
1904
+ }
1905
+ | kDO_LAMBDA bodystmt kEND
1906
+ {
1907
+ result = val[1]
1908
+ }
1909
+
1910
+ do_block: k_do_block do_body kEND
1911
+ {
1912
+ (_, line), iter, _ = val
1913
+ result = iter.line line
1914
+ }
1915
+
1916
+ block_call: command do_block
1917
+ {
1918
+ # TODO:
1919
+ ## if (nd_type($1) == NODE_YIELD) {
1920
+ ## compile_error(PARSER_ARG "block given to yield");
1921
+
1922
+ cmd, blk = val
1923
+
1924
+ syntax_error "Both block arg and actual block given." if
1925
+ cmd.block_pass?
1926
+
1927
+ if inverted? val then
1928
+ val = invert_block_call val
1929
+ cmd, blk = val
1930
+ end
1931
+
1932
+ result = blk
1933
+ result.insert 1, cmd
1934
+ }
1935
+ | block_call call_op2 operation2 opt_paren_args
1936
+ {
1937
+ lhs, _, (id, _line), args = val
1938
+
1939
+ result = new_call lhs, id.to_sym, args
1940
+ }
1941
+ | block_call call_op2 operation2 opt_paren_args brace_block
1942
+ {
1943
+ iter1, _, (name, _line), args, iter2 = val
1944
+
1945
+ call = new_call iter1, name.to_sym, args
1946
+ iter2.insert 1, call
1947
+
1948
+ result = iter2
1949
+ }
1950
+ | block_call call_op2 operation2 command_args do_block
1951
+ {
1952
+ iter1, _, (name, _line), args, iter2 = val
1953
+
1954
+ call = new_call iter1, name.to_sym, args
1955
+ iter2.insert 1, call
1956
+
1957
+ result = iter2
1958
+ }
1959
+
1960
+ method_call: fcall paren_args
1961
+ {
1962
+ call, args = val
1963
+
1964
+ result = call.concat args.sexp_body if args
1965
+ }
1966
+ | primary_value call_op operation2 opt_paren_args
1967
+ {
1968
+ recv, call_op, (op, _line), args = val
1969
+
1970
+ result = new_call recv, op.to_sym, args, call_op
1971
+ }
1972
+ | primary_value tCOLON2 operation2 paren_args
1973
+ {
1974
+ recv, _, (op, _line), args = val
1975
+
1976
+ result = new_call recv, op.to_sym, args
1977
+ }
1978
+ | primary_value tCOLON2 operation3
1979
+ {
1980
+ lhs, _, (id, _line) = val
1981
+
1982
+ result = new_call lhs, id.to_sym
1983
+ }
1984
+ | primary_value call_op paren_args
1985
+ {
1986
+ result = new_call val[0], :call, val[2], val[1]
1987
+ }
1988
+ | primary_value tCOLON2 paren_args
1989
+ {
1990
+ result = new_call val[0], :call, val[2]
1991
+ }
1992
+ | kSUPER paren_args
1993
+ {
1994
+ result = new_super val[1]
1995
+ }
1996
+ | kSUPER
1997
+ {
1998
+ result = s(:zsuper).line lexer.lineno
1999
+ }
2000
+ | primary_value tLBRACK2 opt_call_args rbracket
2001
+ {
2002
+ result = new_aref val
2003
+ }
2004
+
2005
+ brace_block: tLCURLY
2006
+ {
2007
+ self.env.extend :dynamic
2008
+ result = self.lexer.lineno
2009
+ }
2010
+ brace_body tRCURLY
2011
+ {
2012
+ _, line, body, _ = val
2013
+
2014
+ result = body
2015
+ result.line line
2016
+
2017
+ self.env.unextend
2018
+ }
2019
+ | k_do
2020
+ {
2021
+ self.env.extend :dynamic
2022
+ result = self.lexer.lineno
2023
+ }
2024
+ do_body kEND
2025
+ {
2026
+ _, line, body, _ = val
2027
+
2028
+ result = body
2029
+ result.line line
2030
+
2031
+ self.env.unextend
2032
+ }
2033
+
2034
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2035
+ { result = lexer.cmdarg.store(false) }
2036
+ opt_block_param compstmt
2037
+ {
2038
+ line, cmdarg, param, cmpstmt = val
2039
+
2040
+ result = new_brace_body param, cmpstmt, line
2041
+ self.env.unextend
2042
+ lexer.cmdarg.restore cmdarg
2043
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
2044
+ }
2045
+
2046
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
2047
+ { lexer.cmdarg.push false }
2048
+ opt_block_param
2049
+ bodystmt
2050
+ {
2051
+ line, _cmdarg, param, cmpstmt = val
2052
+
2053
+ result = new_do_body param, cmpstmt, line
2054
+ lexer.cmdarg.pop
2055
+ self.env.unextend
2056
+ }
2057
+
2058
+ case_args: arg_value
2059
+ {
2060
+ arg, = val
2061
+
2062
+ result = s(:array, arg).line arg.line
2063
+ }
2064
+ | tSTAR arg_value
2065
+ {
2066
+ _, arg = val
2067
+
2068
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2069
+ }
2070
+ | case_args tCOMMA arg_value
2071
+ {
2072
+ args, _, id = val
2073
+
2074
+ result = self.list_append args, id
2075
+ }
2076
+ | case_args tCOMMA tSTAR arg_value
2077
+ {
2078
+ args, _, _, id = val
2079
+
2080
+ result = self.list_append args, s(:splat, id).line(id.line)
2081
+ }
2082
+
2083
+ case_body: k_when
2084
+ {
2085
+ result = self.lexer.lineno
2086
+ }
2087
+ case_args then compstmt cases
2088
+ {
2089
+ result = new_when(val[2], val[4])
2090
+ result.line val[1]
2091
+ result << val[5] if val[5]
2092
+ }
2093
+
2094
+ cases: opt_else | case_body
2095
+ ######################################################################
2096
+
2097
+ p_case_body: kIN
2098
+ {
2099
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2100
+ self.lexer.command_start = false
2101
+ result = self.in_kwarg
2102
+ self.in_kwarg = true
2103
+ push_pvtbl
2104
+ push_pktbl
2105
+ }
2106
+ p_top_expr then
2107
+ {
2108
+ pop_pktbl
2109
+ pop_pvtbl
2110
+ old_kwargs = _values[-3]
2111
+ self.in_kwarg = old_kwargs
2112
+ }
2113
+ compstmt
2114
+ p_cases
2115
+ {
2116
+ (_, line), _, pat, _, _, body, cases = val
2117
+
2118
+ result = new_in pat, body, cases, line
2119
+ }
2120
+
2121
+ p_cases: opt_else
2122
+ | p_case_body
2123
+
2124
+ p_top_expr: p_top_expr_body
2125
+ | p_top_expr_body kIF_MOD expr_value
2126
+ {
2127
+ body, _, cond = val
2128
+ body = remove_begin body
2129
+
2130
+ result = s(:if, cond, body, nil).line body.line
2131
+ }
2132
+ | p_top_expr_body kUNLESS_MOD expr_value
2133
+ {
2134
+ body, _, cond = val
2135
+ body = remove_begin body
2136
+
2137
+ result = s(:if, cond, nil, body).line body.line
2138
+ }
2139
+
2140
+ p_top_expr_body: p_expr
2141
+ | p_expr tCOMMA
2142
+ {
2143
+ expr, _ = val
2144
+
2145
+ tail = new_array_pattern_tail nil, true, nil, nil
2146
+ result = new_array_pattern nil, expr, tail, expr.line
2147
+ }
2148
+ | p_expr tCOMMA p_args
2149
+ {
2150
+ expr, _, args = val
2151
+
2152
+ result = new_array_pattern nil, expr, args, expr.line
2153
+ }
2154
+ | p_find
2155
+ {
2156
+ find, = val
2157
+
2158
+ result = new_find_pattern nil, find
2159
+ }
2160
+ | p_args_tail
2161
+ {
2162
+ args, = val
2163
+ result = new_array_pattern nil, nil, args, args.line
2164
+ }
2165
+ | p_kwargs
2166
+ {
2167
+ kwargs, = val
2168
+ result = new_hash_pattern nil, kwargs, kwargs.line
2169
+ }
2170
+
2171
+ p_expr: p_as
2172
+
2173
+ p_as: p_expr tASSOC p_variable
2174
+ {
2175
+ # NODE *n = NEW_LIST($1, &@$);
2176
+ # n = list_append(p, n, $3);
2177
+ # $$ = new_hash(p, n, &@$);
2178
+
2179
+ expr, _, var = val
2180
+
2181
+ id = var.last
2182
+
2183
+ self.env[id] = :lvar # HACK: need to extend env
2184
+ lhs = s(:lasgn, id).line var.line
2185
+
2186
+ result = new_assign lhs, expr
2187
+ }
2188
+ | p_alt
2189
+
2190
+ p_alt: p_alt tPIPE p_expr_basic
2191
+ {
2192
+ lhs, _, rhs = val
2193
+
2194
+ result = s(:or, lhs, rhs).line lhs.line
2195
+ }
2196
+ | p_expr_basic
2197
+
2198
+ p_lparen: tLPAREN2 { push_pktbl }
2199
+ p_lbracket: tLBRACK2 { push_pktbl }
2200
+
2201
+ p_expr_basic: p_value
2202
+ | p_const p_lparen p_args tRPAREN
2203
+ {
2204
+ lhs, _, args, _ = val
2205
+
2206
+ pop_pktbl
2207
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2208
+ }
2209
+ | p_const p_lparen p_find tRPAREN
2210
+ {
2211
+ const, _, find, _ = val
2212
+
2213
+ pop_pktbl
2214
+ result = new_find_pattern(const, find).line const.line
2215
+ }
2216
+ | p_const p_lparen p_kwargs tRPAREN
2217
+ {
2218
+ lhs, _, kwargs, _ = val
2219
+
2220
+ pop_pktbl
2221
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2222
+ }
2223
+ | p_const tLPAREN2 tRPAREN
2224
+ {
2225
+ const, _, _ = val
2226
+
2227
+ tail = new_array_pattern_tail nil, nil, nil, nil
2228
+ result = new_array_pattern const, nil, tail, const.line
2229
+ }
2230
+ | p_const p_lbracket p_args rbracket
2231
+ {
2232
+ const, _, pre_arg, _ = val
2233
+
2234
+ pop_pktbl
2235
+ result = new_array_pattern const, nil, pre_arg, const.line
2236
+ }
2237
+ | p_const p_lbracket p_find rbracket
2238
+ {
2239
+ const, _, find, _ = val
2240
+
2241
+ pop_pktbl
2242
+ result = new_find_pattern(const, find).line const.line
2243
+ }
2244
+ | p_const p_lbracket p_kwargs rbracket
2245
+ {
2246
+ const, _, kwargs, _ = val
2247
+
2248
+ result = new_hash_pattern const, kwargs, const.line
2249
+ }
2250
+ | p_const tLBRACK2 rbracket
2251
+ {
2252
+ const, _, _ = val
2253
+
2254
+ tail = new_array_pattern_tail nil, nil, nil, nil
2255
+ result = new_array_pattern const, nil, tail, const.line
2256
+ }
2257
+ | tLBRACK p_args rbracket
2258
+ {
2259
+ _, pat, _ = val
2260
+
2261
+ result = new_array_pattern nil, nil, pat, pat.line
2262
+ }
2263
+ | tLBRACK p_find rbracket
2264
+ {
2265
+ _, find, _ = val
2266
+
2267
+ result = new_find_pattern nil, find
2268
+ }
2269
+ | tLBRACK rbracket
2270
+ {
2271
+ (_, line), _ = val
2272
+
2273
+ result = s(:array_pat).line line
2274
+ }
2275
+ | tLBRACE
2276
+ {
2277
+ push_pktbl
2278
+ result = self.in_kwarg
2279
+ self.in_kwarg = false
2280
+ }
2281
+ p_kwargs rbrace
2282
+ {
2283
+ _, in_kwarg, kwargs, _ = val
2284
+
2285
+ pop_pktbl
2286
+ self.in_kwarg = in_kwarg
2287
+
2288
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2289
+ }
2290
+ | tLBRACE rbrace
2291
+ {
2292
+ (_, line), _ = val
2293
+
2294
+ tail = new_hash_pattern_tail nil, nil, line
2295
+ result = new_hash_pattern nil, tail, line
2296
+ }
2297
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2298
+ {
2299
+ _, _, expr, _ = val
2300
+
2301
+ pop_pktbl
2302
+ result = expr
2303
+ }
2304
+
2305
+ p_args: p_expr
2306
+ {
2307
+ expr, = val
2308
+
2309
+ ary = s(:array_TAIL, expr).line expr.line
2310
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2311
+ }
2312
+ | p_args_head
2313
+ {
2314
+ head, = val
2315
+
2316
+ result = new_array_pattern_tail head, true, nil, nil
2317
+ }
2318
+ | p_args_head p_arg
2319
+ {
2320
+ head, tail = val
2321
+
2322
+ both = array_pat_concat head, tail
2323
+
2324
+ result = new_array_pattern_tail both, nil, nil, nil
2325
+ result.line head.line
2326
+ }
2327
+ | p_args_head tSTAR tIDENTIFIER
2328
+ {
2329
+ head, _, (id, _line) = val
2330
+
2331
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2332
+ result.line head.line
2333
+ }
2334
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2335
+ {
2336
+ head, _, (id, _line), _, post = val
2337
+
2338
+ result = new_array_pattern_tail head, true, id.to_sym, post
2339
+ result.line head.line
2340
+ }
2341
+ | p_args_head tSTAR
2342
+ {
2343
+ expr, _ = val
2344
+
2345
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2346
+ }
2347
+ | p_args_head tSTAR tCOMMA p_args_post
2348
+ {
2349
+ head, _, _, post = val
2350
+
2351
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2352
+ }
2353
+ | p_args_tail
2354
+
2355
+ p_args_head: p_arg tCOMMA
2356
+ {
2357
+ arg, _ = val
2358
+ result = arg
2359
+ }
2360
+ | p_args_head p_arg tCOMMA
2361
+ {
2362
+ head, tail, _ = val
2363
+
2364
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2365
+ result.line head.line
2366
+ }
2367
+
2368
+ p_args_tail: p_rest
2369
+ {
2370
+ (id, line), = val
2371
+
2372
+ result = new_array_pattern_tail nil, true, id, nil
2373
+ result.line line
2374
+ }
2375
+ | p_rest tCOMMA p_args_post
2376
+ {
2377
+ (id, line), _, rhs = val
2378
+
2379
+ result = new_array_pattern_tail nil, true, id, rhs
2380
+ result.line line
2381
+ }
2382
+
2383
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2384
+ {
2385
+ lhs, _, mid, _, rhs = val
2386
+
2387
+ result = new_find_pattern_tail lhs, mid, rhs
2388
+ }
2389
+
2390
+ p_rest: tSTAR tIDENTIFIER
2391
+ {
2392
+ _, (id, line) = val
2393
+
2394
+ result = [id.to_sym, line]
2395
+ }
2396
+ | tSTAR
2397
+ {
2398
+ (_id, line), = val
2399
+
2400
+ result = [nil, line]
2401
+ }
2402
+
2403
+ p_args_post: p_arg
2404
+ | p_args_post tCOMMA p_arg
2405
+ {
2406
+ lhs, _, rhs = val
2407
+
2408
+ result = array_pat_concat lhs, rhs
2409
+ }
2410
+
2411
+ p_arg: p_expr
2412
+ {
2413
+ expr, = val
2414
+ expr = s(:array_TAIL, expr).line expr.line unless
2415
+ expr.sexp_type == :array_TAIL
2416
+ result = expr
2417
+ }
2418
+
2419
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2420
+ {
2421
+ kw_arg, _, rest = val
2422
+ # TODO? new_unique_key_hash(p, $1, &@$)
2423
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2424
+ }
2425
+ | p_kwarg
2426
+ {
2427
+ kwarg, = val
2428
+ # TODO? new_unique_key_hash(p, $1, &@$)
2429
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2430
+ }
2431
+ | p_kwarg tCOMMA
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_any_kwrest
2438
+ {
2439
+ rest, = val
2440
+
2441
+ result = new_hash_pattern_tail nil, rest, rest.line
2442
+ }
2443
+
2444
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2445
+ | p_kwarg tCOMMA p_kw
2446
+ {
2447
+ kwarg, _, kw = val
2448
+ kwarg.concat kw.sexp_body
2449
+ result = kwarg
2450
+ }
2451
+
2452
+ p_kw: p_kw_label p_expr
2453
+ {
2454
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2455
+ lhs, rhs = val
2456
+
2457
+ result = s(:PAIR, lhs, rhs).line lhs.line
2458
+ }
2459
+ | p_kw_label
2460
+ {
2461
+ lhs, = val
2462
+
2463
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2464
+
2465
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2466
+ # yyerror1(&@1, "key must be valid as local variables");
2467
+ # }
2468
+
2469
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2470
+ # assignable(p, $1, 0, &@$));
2471
+
2472
+ case lhs.sexp_type
2473
+ when :lit then
2474
+ assignable [lhs.value, lhs.line]
2475
+ else
2476
+ # TODO or done?
2477
+ debug 666
2478
+ end
2479
+
2480
+ # TODO PAIR -> LIST ?
2481
+ result = s(:PAIR, lhs, nil).line lhs.line
2482
+ }
2483
+
2484
+ p_kw_label: tLABEL
2485
+ {
2486
+ (id, line), = val
2487
+
2488
+ result = s(:lit, id.to_sym).line line
2489
+ }
2490
+
2491
+ p_kwrest: kwrest_mark tIDENTIFIER
2492
+ {
2493
+ _, (id, line) = val
2494
+
2495
+ name = id.to_sym
2496
+ self.assignable [name, line]
2497
+ result = s(:kwrest, :"**#{name}").line line
2498
+ }
2499
+ | kwrest_mark
2500
+ {
2501
+ (_, line), = val
2502
+
2503
+ result = s(:kwrest, :"**").line line
2504
+ }
2505
+
2506
+ p_kwnorest: kwrest_mark kNIL
2507
+ {
2508
+ (_, line), _ = val
2509
+
2510
+ # TODO: or s(:norest)? s(:**nil)?
2511
+ result = s(:kwrest, :"**nil").line line
2512
+ }
2513
+
2514
+ p_any_kwrest: p_kwrest
2515
+ | p_kwnorest
2516
+
2517
+ p_value: p_primitive
2518
+ | p_primitive tDOT2 p_primitive
2519
+ {
2520
+ lhs, _, rhs = val
2521
+
2522
+ lhs = value_expr lhs
2523
+ rhs = value_expr rhs
2524
+
2525
+ result = s(:dot2, lhs, rhs).line lhs.line
2526
+ }
2527
+ | p_primitive tDOT3 p_primitive
2528
+ {
2529
+ lhs, _, rhs = val
2530
+
2531
+ lhs = value_expr lhs
2532
+ rhs = value_expr rhs
2533
+
2534
+ result = s(:dot3, lhs, rhs).line lhs.line
2535
+ }
2536
+ | p_primitive tDOT2
2537
+ {
2538
+ v1, _ = val
2539
+
2540
+ result = s(:dot2, v1, nil).line v1.line
2541
+ }
2542
+ | p_primitive tDOT3
2543
+ {
2544
+ v1, _ = val
2545
+
2546
+ result = s(:dot3, v1, nil).line v1.line
2547
+ }
2548
+ | p_variable
2549
+ | p_var_ref
2550
+ | p_const
2551
+ | tBDOT2 p_primitive
2552
+ {
2553
+ _, v1 = val
2554
+
2555
+ result = s(:dot2, nil, v1).line v1.line
2556
+ }
2557
+ | tBDOT3 p_primitive
2558
+ {
2559
+ _, v1 = val
2560
+
2561
+ result = s(:dot3, nil, v1).line v1.line
2562
+ }
2563
+
2564
+ p_primitive: literal
2565
+ | strings
2566
+ | xstring
2567
+ | regexp
2568
+ | words
2569
+ | qwords
2570
+ | symbols
2571
+ | qsymbols
2572
+ | keyword_variable
2573
+ {
2574
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2575
+ var, = val
2576
+
2577
+ result = var
2578
+ }
2579
+ | lambda
2580
+
2581
+ p_variable: tIDENTIFIER
2582
+ {
2583
+ (id, line), = val
2584
+
2585
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2586
+ # TODO: assignable(p, $1, 0, &@$);
2587
+ result = s(:lvar, id.to_sym).line line
2588
+ }
2589
+
2590
+ p_var_ref: tCARET tIDENTIFIER
2591
+ {
2592
+ _, (id, line) = val
2593
+
2594
+ # TODO: check id against env for lvar or dvar
2595
+
2596
+ result = s(:lvar, id.to_sym).line line
2597
+ }
2598
+
2599
+ p_const: tCOLON3 cname
2600
+ {
2601
+ _, (id, line) = val
2602
+ result = s(:colon3, id.to_sym).line line
2603
+ }
2604
+ | p_const tCOLON2 cname
2605
+ {
2606
+ lhs, _, (id, _line) = val
2607
+
2608
+ l = lhs.line
2609
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2610
+ }
2611
+ | tCONSTANT
2612
+ {
2613
+ # TODO $$ = gettable(p, $1, &@$);
2614
+ (id, line), = val
2615
+ result = s(:const, id.to_sym).line line
2616
+ }
2617
+ ######################################################################
2618
+
2619
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2620
+ {
2621
+ (_, line), klasses, var, _, body, rest = val
2622
+
2623
+ klasses ||= s(:array)
2624
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2625
+ klasses.line line
2626
+
2627
+ result = new_resbody(klasses, body)
2628
+ result << rest if rest # UGH, rewritten above
2629
+ }
2630
+ |
2631
+ {
2632
+ result = nil
2633
+ }
2634
+
2635
+ exc_list: arg_value
2636
+ {
2637
+ arg, = val
2638
+ result = s(:array, arg).line arg.line
2639
+ }
2640
+ | mrhs
2641
+ | none
2642
+
2643
+ exc_var: tASSOC lhs
2644
+ {
2645
+ result = val[1]
2646
+ }
2647
+ | none
2648
+
2649
+ opt_ensure: k_ensure compstmt
2650
+ {
2651
+ (_, line), body = val
2652
+
2653
+ result = body || s(:nil).line(line)
2654
+ }
2655
+ | none
2656
+
2657
+ literal: numeric
2658
+ {
2659
+ (lit, line), = val
2660
+ result = s(:lit, lit).line line
2661
+ }
2662
+ | symbol
2663
+
2664
+ strings: string
2665
+ {
2666
+ str, = val
2667
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2668
+ result = str
2669
+ }
2670
+
2671
+ string: tCHAR
2672
+ {
2673
+ debug 36
2674
+ }
2675
+ | string1
2676
+ | string string1
2677
+ {
2678
+ result = self.literal_concat val[0], val[1]
2679
+ }
2680
+
2681
+ string1: tSTRING_BEG string_contents tSTRING_END
2682
+ {
2683
+ (_, line), str, (_, func) = val
2684
+
2685
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2686
+
2687
+ result = str.line line
2688
+ }
2689
+ | tSTRING
2690
+ {
2691
+ result = new_string val
2692
+ }
2693
+
2694
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2695
+ {
2696
+ result = new_xstring val
2697
+ # TODO: dedent?!?! SERIOUSLY?!?
2698
+ }
2699
+
2700
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2701
+ {
2702
+ result = new_regexp val
2703
+ }
2704
+
2705
+ words: tWORDS_BEG tSPACE tSTRING_END
2706
+ {
2707
+ (_, line), _, _ = val
2708
+
2709
+ result = s(:array).line line
2710
+ }
2711
+ | tWORDS_BEG word_list tSTRING_END
2712
+ {
2713
+ (_, line), list, _ = val
2714
+
2715
+ result = list.line line
2716
+ }
2717
+
2718
+ word_list: none
2719
+ {
2720
+ result = new_word_list
2721
+ }
2722
+ | word_list word tSPACE
2723
+ {
2724
+ result = val[0].dup << new_word_list_entry(val)
2725
+ }
2726
+
2727
+ word: string_content
2728
+ | word string_content
2729
+ {
2730
+ result = self.literal_concat val[0], val[1]
2731
+ }
2732
+
2733
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2734
+ {
2735
+ (_, line), _, _ = val
2736
+
2737
+ result = s(:array).line line
2738
+ }
2739
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2740
+ {
2741
+ (_, line), list, _, = val
2742
+ list.line line
2743
+ result = list
2744
+ }
2745
+
2746
+ symbol_list: none
2747
+ {
2748
+ result = new_symbol_list
2749
+ }
2750
+ | symbol_list word tSPACE
2751
+ {
2752
+ list, * = val
2753
+ result = list.dup << new_symbol_list_entry(val)
2754
+ }
2755
+
2756
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2757
+ {
2758
+ (_, line), _, _ = val
2759
+
2760
+ result = s(:array).line line
2761
+ }
2762
+ | tQWORDS_BEG qword_list tSTRING_END
2763
+ {
2764
+ (_, line), list, _ = val
2765
+
2766
+ result = list.line line
2767
+ }
2768
+
2769
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2770
+ {
2771
+ (_, line), _, _ = val
2772
+
2773
+ result = s(:array).line line
2774
+ }
2775
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2776
+ {
2777
+ (_, line), list, _ = val
2778
+
2779
+ result = list.line line
2780
+ }
2781
+
2782
+ qword_list: none
2783
+ {
2784
+ result = new_qword_list
2785
+ }
2786
+ | qword_list tSTRING_CONTENT tSPACE
2787
+ {
2788
+ result = val[0].dup << new_qword_list_entry(val)
2789
+ }
2790
+
2791
+ qsym_list: none
2792
+ {
2793
+ result = new_qsym_list
2794
+ }
2795
+ | qsym_list tSTRING_CONTENT tSPACE
2796
+ {
2797
+ result = val[0].dup << new_qsym_list_entry(val)
2798
+ }
2799
+
2800
+ string_contents: none
2801
+ {
2802
+ line = prev_value_to_lineno _values.last
2803
+ result = s(:str, +"").line line
2804
+ }
2805
+ | string_contents string_content
2806
+ {
2807
+ v1, v2 = val
2808
+ result = literal_concat v1, v2
2809
+ }
2810
+
2811
+ xstring_contents: none
2812
+ {
2813
+ result = nil
2814
+ }
2815
+ | xstring_contents string_content
2816
+ {
2817
+ v1, v2 = val
2818
+ result = literal_concat v1, v2
2819
+ }
2820
+
2821
+ regexp_contents: none
2822
+ {
2823
+ result = nil
2824
+ }
2825
+ | regexp_contents string_content
2826
+ {
2827
+ v1, v2 = val
2828
+ result = literal_concat v1, v2
2829
+ }
2830
+
2831
+ string_content: tSTRING_CONTENT
2832
+ {
2833
+ result = new_string val
2834
+ }
2835
+ | tSTRING_DVAR
2836
+ {
2837
+ result = lexer.lex_strterm
2838
+
2839
+ lexer.lex_strterm = nil
2840
+ lexer.lex_state = EXPR_BEG
2841
+ }
2842
+ string_dvar
2843
+ {
2844
+ _, strterm, str = val
2845
+ lexer.lex_strterm = strterm
2846
+ result = s(:evstr, str).line str.line
2847
+ }
2848
+ | tSTRING_DBEG
2849
+ {
2850
+ result = [lexer.lex_strterm,
2851
+ lexer.brace_nest,
2852
+ lexer.string_nest, # TODO: remove
2853
+ lexer.lex_state,
2854
+ lexer.lineno,
2855
+ ]
2856
+
2857
+ lexer.cmdarg.push false
2858
+ lexer.cond.push false
2859
+
2860
+ lexer.lex_strterm = nil
2861
+ lexer.brace_nest = 0
2862
+ lexer.string_nest = 0
2863
+
2864
+ lexer.lex_state = EXPR_BEG
2865
+ }
2866
+ compstmt
2867
+ tSTRING_DEND
2868
+ {
2869
+ _, memo, stmt, _ = val
2870
+
2871
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2872
+ # TODO: heredoc_indent
2873
+
2874
+ lexer.lex_strterm = lex_strterm
2875
+ lexer.brace_nest = brace_nest
2876
+ lexer.string_nest = string_nest
2877
+
2878
+ lexer.cond.pop
2879
+ lexer.cmdarg.pop
2880
+
2881
+ lexer.lex_state = oldlex_state
2882
+
2883
+ case stmt
2884
+ when Sexp then
2885
+ case stmt.sexp_type
2886
+ when :str, :dstr, :evstr then
2887
+ result = stmt
2888
+ else
2889
+ result = s(:evstr, stmt).line line
2890
+ end
2891
+ when nil then
2892
+ result = s(:evstr).line line
2893
+ else
2894
+ debug 37
2895
+ raise "unknown string body: #{stmt.inspect}"
2896
+ end
2897
+ }
2898
+
2899
+ string_dvar: tGVAR
2900
+ {
2901
+ (id, line), = val
2902
+ result = s(:gvar, id.to_sym).line line
2903
+ }
2904
+ | tIVAR
2905
+ {
2906
+ (id, line), = val
2907
+ result = s(:ivar, id.to_sym).line line
2908
+ }
2909
+ | tCVAR
2910
+ {
2911
+ (id, line), = val
2912
+ result = s(:cvar, id.to_sym).line line
2913
+ }
2914
+ | backref
2915
+
2916
+ symbol: ssym
2917
+ | dsym
2918
+
2919
+ ssym: tSYMBEG sym
2920
+ {
2921
+ _, (id, line) = val
2922
+
2923
+ lexer.lex_state = EXPR_END
2924
+ result = s(:lit, id.to_sym).line line
2925
+ }
2926
+ | tSYMBOL
2927
+ {
2928
+ (id, line), = val
2929
+
2930
+ lexer.lex_state = EXPR_END
2931
+ result = s(:lit, id.to_sym).line line
2932
+ }
2933
+
2934
+ sym: fname | tIVAR | tGVAR | tCVAR
2935
+
2936
+ dsym: tSYMBEG string_contents tSTRING_END
2937
+ {
2938
+ _, result, _ = val
2939
+
2940
+ lexer.lex_state = EXPR_END
2941
+
2942
+ result ||= s(:str, "").line lexer.lineno
2943
+
2944
+ case result.sexp_type
2945
+ when :dstr then
2946
+ result.sexp_type = :dsym
2947
+ when :str then
2948
+ result = s(:lit, result.last.to_sym).line result.line
2949
+ when :evstr then
2950
+ result = s(:dsym, "", result).line result.line
2951
+ else
2952
+ debug 38
2953
+ end
2954
+ }
2955
+
2956
+ numeric: simple_numeric
2957
+ | tUMINUS_NUM simple_numeric =tLOWEST
2958
+ {
2959
+ _, (num, line) = val
2960
+ result = [-num, line]
2961
+ }
2962
+
2963
+ simple_numeric: tINTEGER
2964
+ | tFLOAT
2965
+ | tRATIONAL
2966
+ | tIMAGINARY
2967
+
2968
+ user_variable: tIDENTIFIER
2969
+ | tIVAR
2970
+ | tGVAR
2971
+ | tCONSTANT
2972
+ | tCVAR
2973
+
2974
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2975
+ | kSELF { result = s(:self).line lexer.lineno }
2976
+ | kTRUE { result = s(:true).line lexer.lineno }
2977
+ | kFALSE { result = s(:false).line lexer.lineno }
2978
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2979
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2980
+ | k__ENCODING__
2981
+ {
2982
+ l = lexer.lineno
2983
+ result =
2984
+ if defined? Encoding then
2985
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2986
+ else
2987
+ s(:str, "Unsupported!").line l
2988
+ end
2989
+ }
2990
+
2991
+ var_ref: user_variable
2992
+ {
2993
+ raise "NO: #{val.inspect}" if Sexp === val.first
2994
+ (var, line), = val
2995
+ result = Sexp === var ? var : self.gettable(var)
2996
+
2997
+ result.line line
2998
+ }
2999
+ | keyword_variable
3000
+ {
3001
+ var = val[0]
3002
+ result = Sexp === var ? var : self.gettable(var)
3003
+ }
3004
+
3005
+ var_lhs: user_variable
3006
+ {
3007
+ result = self.assignable val[0]
3008
+ }
3009
+ | keyword_variable
3010
+ {
3011
+ result = self.assignable val[0]
3012
+ debug 39
3013
+ }
3014
+
3015
+ backref: tNTH_REF
3016
+ {
3017
+ (ref, line), = val
3018
+ result = s(:nth_ref, ref).line line
3019
+ }
3020
+ | tBACK_REF
3021
+ {
3022
+ (ref, line), = val
3023
+ result = s(:back_ref, ref).line line
3024
+ }
3025
+
3026
+ superclass: tLT
3027
+ {
3028
+ lexer.lex_state = EXPR_BEG
3029
+ lexer.command_start = true
3030
+ }
3031
+ expr_value term
3032
+ {
3033
+ result = val[2]
3034
+ }
3035
+ | none
3036
+ {
3037
+ result = nil
3038
+ }
3039
+
3040
+ f_opt_paren_args: f_paren_args
3041
+ | none
3042
+
3043
+ f_paren_args: tLPAREN2 f_args rparen
3044
+ {
3045
+ result = end_args val
3046
+ }
3047
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3048
+ {
3049
+ result = end_args val
3050
+ }
3051
+ | tLPAREN2 args_forward rparen
3052
+ {
3053
+ result = end_args val
3054
+ }
3055
+
3056
+ f_arglist: f_paren_args
3057
+ | {
3058
+ result = self.in_kwarg
3059
+ self.in_kwarg = true
3060
+ self.lexer.lex_state |= EXPR_LABEL
3061
+ }
3062
+ f_args term
3063
+ {
3064
+ result = end_args val
3065
+ }
3066
+
3067
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
3068
+ {
3069
+ result = args val
3070
+ }
3071
+ | f_kwarg opt_f_block_arg
3072
+ {
3073
+ result = args val
3074
+ }
3075
+ | f_any_kwrest opt_f_block_arg
3076
+ {
3077
+ result = args val
3078
+ }
3079
+ | f_block_arg
3080
+
3081
+ opt_args_tail: tCOMMA args_tail
3082
+ {
3083
+ result = val[1]
3084
+ }
3085
+ |
3086
+ {
3087
+ result = nil
3088
+ }
3089
+
3090
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
3091
+ {
3092
+ result = args val
3093
+ }
3094
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3095
+ {
3096
+ result = args val
3097
+ }
3098
+ | f_arg tCOMMA f_optarg opt_args_tail
3099
+ {
3100
+ result = args val
3101
+ }
3102
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
3103
+ {
3104
+ result = args val
3105
+ }
3106
+ | f_arg tCOMMA f_rest_arg opt_args_tail
3107
+ {
3108
+ result = args val
3109
+ }
3110
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3111
+ {
3112
+ result = args val
3113
+ }
3114
+ | f_arg opt_args_tail
3115
+ {
3116
+ result = args val
3117
+ }
3118
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
3119
+ {
3120
+ result = args val
3121
+ }
3122
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
3123
+ {
3124
+ result = args val
3125
+ }
3126
+ | f_optarg opt_args_tail
3127
+ {
3128
+ result = args val
3129
+ }
3130
+ | f_optarg tCOMMA f_arg opt_args_tail
3131
+ {
3132
+ result = args val
3133
+ }
3134
+ | f_rest_arg opt_args_tail
3135
+ {
3136
+ result = args val
3137
+ }
3138
+ | f_rest_arg tCOMMA f_arg opt_args_tail
3139
+ {
3140
+ result = args val
3141
+ }
3142
+ | args_tail
3143
+ {
3144
+ result = args val
3145
+ }
3146
+ |
3147
+ {
3148
+ result = args val
3149
+ # result.line lexer.lineno
3150
+ }
3151
+
3152
+ args_forward: tBDOT3
3153
+ {
3154
+ result = s(:forward_args).line lexer.lineno
3155
+ }
3156
+
3157
+ f_bad_arg: tCONSTANT
3158
+ {
3159
+ yyerror "formal argument cannot be a constant"
3160
+ }
3161
+ | tIVAR
3162
+ {
3163
+ yyerror "formal argument cannot be an instance variable"
3164
+ }
3165
+ | tGVAR
3166
+ {
3167
+ yyerror "formal argument cannot be a global variable"
3168
+ }
3169
+ | tCVAR
3170
+ {
3171
+ yyerror "formal argument cannot be a class variable"
3172
+ }
3173
+
3174
+ f_norm_arg: f_bad_arg
3175
+ | tIDENTIFIER
3176
+ {
3177
+ (id, line), = val
3178
+ identifier = id.to_sym
3179
+ self.env[identifier] = :lvar
3180
+
3181
+ result = [identifier, line]
3182
+ }
3183
+
3184
+ f_arg_asgn: f_norm_arg
3185
+
3186
+ f_arg_item: f_arg_asgn
3187
+ | tLPAREN f_margs rparen
3188
+ {
3189
+ _, margs, _ = val
3190
+
3191
+ result = margs
3192
+ }
3193
+
3194
+ f_arg: f_arg_item
3195
+ {
3196
+ result = new_arg val
3197
+ }
3198
+ | f_arg tCOMMA f_arg_item
3199
+ {
3200
+ list, _, item = val
3201
+
3202
+ if list.sexp_type == :args then
3203
+ result = list
3204
+ else
3205
+ result = s(:args, list).line list.line
3206
+ end
3207
+
3208
+ result << (Sexp === item ? item : item.first)
3209
+ }
3210
+
3211
+ f_label: tLABEL
3212
+
3213
+ f_kw: f_label arg_value
3214
+ {
3215
+ # TODO: new_kw_arg
3216
+ (label, line), arg = val
3217
+
3218
+ identifier = label.to_sym
3219
+ self.env[identifier] = :lvar
3220
+
3221
+ kwarg = s(:kwarg, identifier, arg).line line
3222
+ result = s(:array, kwarg).line line
3223
+ }
3224
+ | f_label
3225
+ {
3226
+ (label, line), = val
3227
+
3228
+ id = label.to_sym
3229
+ self.env[id] = :lvar
3230
+
3231
+ result = s(:array, s(:kwarg, id).line(line)).line line
3232
+ }
3233
+
3234
+ f_block_kw: f_label primary_value
3235
+ {
3236
+ # TODO: new_kw_arg
3237
+ (label, line), expr = val
3238
+ id = label.to_sym
3239
+ self.env[id] = :lvar
3240
+
3241
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
3242
+ }
3243
+ | f_label
3244
+ {
3245
+ # TODO: new_kw_arg
3246
+ (label, line), = val
3247
+ id = label.to_sym
3248
+ self.env[id] = :lvar
3249
+
3250
+ result = s(:array, s(:kwarg, id).line(line)).line line
3251
+ }
3252
+
3253
+ f_block_kwarg: f_block_kw
3254
+ | f_block_kwarg tCOMMA f_block_kw
3255
+ {
3256
+ list, _, item = val
3257
+ result = list << item.last
3258
+ }
3259
+
3260
+ f_kwarg: f_kw
3261
+ | f_kwarg tCOMMA f_kw
3262
+ {
3263
+ result = args val
3264
+ }
3265
+
3266
+ kwrest_mark: tPOW
3267
+ | tDSTAR
3268
+
3269
+ f_no_kwarg: kwrest_mark kNIL
3270
+ {
3271
+ (_, line), _ = val
3272
+ result = [:"**nil", line]
3273
+ }
3274
+
3275
+ f_kwrest: kwrest_mark tIDENTIFIER
3276
+ {
3277
+ _, (id, line) = val
3278
+
3279
+ name = id.to_sym
3280
+ self.assignable [name, line]
3281
+ result = [:"**#{name}", line]
3282
+ }
3283
+ | kwrest_mark
3284
+ {
3285
+ id = :"**"
3286
+ self.env[id] = :lvar # TODO: needed?!?
3287
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
3288
+ }
3289
+
3290
+ f_opt: f_arg_asgn tEQL arg_value
3291
+ {
3292
+ lhs, _, rhs = val
3293
+ result = self.assignable lhs, rhs
3294
+ # TODO: detect duplicate names
3295
+ }
3296
+
3297
+ f_block_opt: f_arg_asgn tEQL primary_value
3298
+ {
3299
+ lhs, _, rhs = val
3300
+ result = self.assignable lhs, rhs
3301
+ }
3302
+
3303
+ f_block_optarg: f_block_opt
3304
+ {
3305
+ optblk, = val
3306
+ result = s(:block, optblk).line optblk.line
3307
+ }
3308
+ | f_block_optarg tCOMMA f_block_opt
3309
+ {
3310
+ optarg, _, optblk = val
3311
+ result = optarg
3312
+ result << optblk
3313
+ }
3314
+
3315
+ f_optarg: f_opt
3316
+ {
3317
+ opt, = val
3318
+ result = s(:block, opt).line opt.line
3319
+ }
3320
+ | f_optarg tCOMMA f_opt
3321
+ {
3322
+ result = self.block_append val[0], val[2]
3323
+ }
3324
+
3325
+ restarg_mark: tSTAR2 | tSTAR
3326
+
3327
+ f_rest_arg: restarg_mark tIDENTIFIER
3328
+ {
3329
+ # TODO: differs from parse.y - needs tests
3330
+ _, (id, line) = val
3331
+ name = id.to_sym
3332
+ self.assignable [name, line]
3333
+ result = [:"*#{name}", line]
3334
+ }
3335
+ | restarg_mark
3336
+ {
3337
+ name = :"*"
3338
+ self.env[name] = :lvar
3339
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
3340
+ }
3341
+
3342
+ blkarg_mark: tAMPER2 | tAMPER
3343
+
3344
+ f_block_arg: blkarg_mark tIDENTIFIER
3345
+ {
3346
+ _, (id, line) = val
3347
+ identifier = id.to_sym
3348
+
3349
+ self.env[identifier] = :lvar
3350
+ result = ["&#{identifier}".to_sym, line]
3351
+ }
3352
+
3353
+ opt_f_block_arg: tCOMMA f_block_arg
3354
+ {
3355
+ _, arg = val
3356
+ result = arg
3357
+ }
3358
+ |
3359
+ {
3360
+ result = nil
3361
+ }
3362
+
3363
+ singleton: var_ref
3364
+ | tLPAREN2
3365
+ {
3366
+ lexer.lex_state = EXPR_BEG
3367
+ }
3368
+ expr rparen
3369
+ {
3370
+ result = val[2]
3371
+ yyerror "Can't define single method for literals." if
3372
+ result.sexp_type == :lit
3373
+ }
3374
+
3375
+ assoc_list: none
3376
+ {
3377
+ result = s(:array).line lexer.lineno
3378
+ }
3379
+ | assocs trailer
3380
+
3381
+ assocs: assoc
3382
+ | assocs tCOMMA assoc
3383
+ {
3384
+ list = val[0].dup
3385
+ more = val[2].sexp_body
3386
+ list.push(*more) unless more.empty?
3387
+ result = list
3388
+ result.sexp_type = :hash
3389
+ }
3390
+
3391
+ assoc: arg_value tASSOC arg_value
3392
+ {
3393
+ v1, _, v2 = val
3394
+ result = s(:array, v1, v2).line v1.line
3395
+ }
3396
+ | tLABEL arg_value
3397
+ {
3398
+ (label, line), arg = val
3399
+
3400
+ lit = s(:lit, label.to_sym).line line
3401
+ result = s(:array, lit, arg).line line
3402
+ }
3403
+ | tSTRING_BEG string_contents tLABEL_END arg_value
3404
+ {
3405
+ (_, line), sym, _, value = val
3406
+
3407
+ sym.sexp_type = :dsym
3408
+
3409
+ result = s(:array, sym, value).line line
3410
+ }
3411
+ | tDSTAR arg_value
3412
+ {
3413
+ _, arg = val
3414
+ line = arg.line
3415
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
3416
+ }
3417
+
3418
+ operation: tIDENTIFIER | tCONSTANT | tFID
3419
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
3420
+ operation3: tIDENTIFIER | tFID | op
3421
+ dot_or_colon: tDOT | tCOLON2
3422
+ call_op: tDOT
3423
+ | tLONELY # TODO: rename tANDDOT?
3424
+
3425
+ call_op2: call_op
3426
+ | tCOLON2
3427
+
3428
+ opt_terms: | terms
3429
+ opt_nl: | tNL
3430
+ rparen: opt_nl tRPAREN
3431
+ # TODO:
3432
+ # {
3433
+ # _, close = val
3434
+ # result = [close, lexer.lineno]
3435
+ # }
3436
+ rbracket: opt_nl tRBRACK
3437
+ {
3438
+ _, close = val
3439
+ result = [close, lexer.lineno]
3440
+ }
3441
+ rbrace: opt_nl tRCURLY
3442
+ {
3443
+ _, close = val
3444
+ result = [close, lexer.lineno]
3445
+ }
3446
+ trailer: | tNL | tCOMMA
3447
+
3448
+ term: tSEMI { yyerrok }
3449
+ | tNL
3450
+
3451
+ terms: term
3452
+ | terms tSEMI { yyerrok }
3453
+
3454
+ none: { result = nil; }
3455
+ end
3456
+
3457
+ ---- inner
3458
+
3459
+ require "ruby_lexer"
3460
+ require "ruby_parser_extras"
3461
+ include RubyLexer::State::Values
3462
+
3463
+ # :stopdoc:
3464
+
3465
+ # Local Variables: **
3466
+ # racc-token-length-max:14 **
3467
+ # End: **