ruby_parser 3.19.2 → 3.20.1

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