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