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