parser 0.9.alpha1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/AST_FORMAT.md +1338 -0
  4. data/README.md +58 -3
  5. data/Rakefile +32 -12
  6. data/bin/benchmark +47 -0
  7. data/bin/explain-parse +14 -0
  8. data/bin/parse +6 -0
  9. data/lib/parser.rb +84 -0
  10. data/lib/parser/all.rb +2 -0
  11. data/lib/parser/ast/node.rb +11 -0
  12. data/lib/parser/ast/processor.rb +8 -0
  13. data/lib/parser/base.rb +116 -0
  14. data/lib/parser/builders/default.rb +654 -0
  15. data/lib/parser/compatibility/ruby1_8.rb +13 -0
  16. data/lib/parser/diagnostic.rb +44 -0
  17. data/lib/parser/diagnostic/engine.rb +44 -0
  18. data/lib/parser/lexer.rl +335 -245
  19. data/lib/parser/lexer/explanation.rb +37 -0
  20. data/lib/parser/{lexer_literal.rb → lexer/literal.rb} +22 -12
  21. data/lib/parser/lexer/stack_state.rb +38 -0
  22. data/lib/parser/ruby18.y +1957 -0
  23. data/lib/parser/ruby19.y +2154 -0
  24. data/lib/parser/source/buffer.rb +78 -0
  25. data/lib/parser/source/map.rb +20 -0
  26. data/lib/parser/source/map/operator.rb +15 -0
  27. data/lib/parser/source/map/variable_assignment.rb +15 -0
  28. data/lib/parser/source/range.rb +66 -0
  29. data/lib/parser/static_environment.rb +12 -6
  30. data/parser.gemspec +23 -13
  31. data/test/helper.rb +45 -0
  32. data/test/parse_helper.rb +204 -0
  33. data/test/racc_coverage_helper.rb +130 -0
  34. data/test/test_diagnostic.rb +47 -0
  35. data/test/test_diagnostic_engine.rb +58 -0
  36. data/test/test_lexer.rb +601 -357
  37. data/test/test_lexer_stack_state.rb +69 -0
  38. data/test/test_parse_helper.rb +74 -0
  39. data/test/test_parser.rb +3654 -0
  40. data/test/test_source_buffer.rb +80 -0
  41. data/test/test_source_range.rb +51 -0
  42. data/test/test_static_environment.rb +1 -4
  43. metadata +137 -12
@@ -0,0 +1,2154 @@
1
+ class Parser::Ruby19
2
+
3
+ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
4
+ kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
5
+ kREDO kRETRY kIN kDO kDO_COND kDO_BLOCK kDO_LAMBDA kRETURN kYIELD kSUPER
6
+ kSELF kNIL kTRUE kFALSE kAND kOR kNOT kIF_MOD kUNLESS_MOD kWHILE_MOD
7
+ kUNTIL_MOD kRESCUE_MOD kALIAS kDEFINED klBEGIN klEND k__LINE__
8
+ k__FILE__ k__ENCODING__ tIDENTIFIER tFID tGVAR tIVAR tCONSTANT
9
+ tLABEL tCVAR tNTH_REF tBACK_REF tSTRING_CONTENT tINTEGER tFLOAT
10
+ tREGEXP_END tUPLUS tUMINUS tUMINUS_NUM tPOW tCMP tEQ tEQQ tNEQ
11
+ tGEQ tLEQ tANDOP tOROP tMATCH tNMATCH tDOT tDOT2 tDOT3 tAREF
12
+ tASET tLSHFT tRSHFT tCOLON2 tCOLON3 tOP_ASGN tASSOC tLPAREN
13
+ tLPAREN2 tRPAREN tLPAREN_ARG tLBRACK tLBRACK2 tRBRACK tLBRACE
14
+ tLBRACE_ARG tSTAR tSTAR2 tAMPER tAMPER2 tTILDE tPERCENT tDIVIDE
15
+ tPLUS tMINUS tLT tGT tPIPE tBANG tCARET tLCURLY tRCURLY
16
+ tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tREGEXP_OPT
17
+ tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
18
+ tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA tLAMBEG
19
+
20
+ prechigh
21
+ right tBANG tTILDE tUPLUS
22
+ right tPOW
23
+ right tUMINUS_NUM tUMINUS
24
+ left tSTAR2 tDIVIDE tPERCENT
25
+ left tPLUS tMINUS
26
+ left tLSHFT tRSHFT
27
+ left tAMPER2
28
+ left tPIPE tCARET
29
+ left tGT tGEQ tLT tLEQ
30
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
31
+ left tANDOP
32
+ left tOROP
33
+ nonassoc tDOT2 tDOT3
34
+ right tEH tCOLON
35
+ left kRESCUE_MOD
36
+ right tEQL tOP_ASGN
37
+ nonassoc kDEFINED
38
+ right kNOT
39
+ left kOR kAND
40
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
41
+ nonassoc tLBRACE_ARG
42
+ nonassoc tLOWEST
43
+ preclow
44
+
45
+ rule
46
+
47
+ program: top_compstmt
48
+
49
+ top_compstmt: top_stmts opt_terms
50
+ {
51
+ result = @builder.compstmt(val[0])
52
+ }
53
+
54
+ top_stmts: none
55
+ {
56
+ result = []
57
+ }
58
+ | top_stmt
59
+ {
60
+ result = [ val[0] ]
61
+ }
62
+ | top_stmts terms top_stmt
63
+ {
64
+ result = val[0] << val[2]
65
+ }
66
+ | error top_stmt
67
+ {
68
+ result = [ val[1] ]
69
+ }
70
+
71
+ top_stmt: stmt
72
+ | klBEGIN
73
+ {
74
+ @static_env.extend_static
75
+ }
76
+ tLCURLY top_compstmt tRCURLY
77
+ {
78
+ @static_env.unextend
79
+
80
+ result = @builder.preexe(val[0], val[2], val[3], val[4])
81
+ }
82
+
83
+ bodystmt: compstmt opt_rescue opt_else opt_ensure
84
+ {
85
+ rescue_bodies = val[1]
86
+ else_, t_else = val[2]
87
+ ensure_, t_ensure = val[3]
88
+
89
+ if rescue_bodies.empty? && !else_.nil?
90
+ diagnostic :warning, :useless_else, t_else
91
+ end
92
+
93
+ result = @builder.begin_body(val[0],
94
+ rescue_bodies,
95
+ else_, t_else,
96
+ ensure_, t_ensure)
97
+ }
98
+
99
+ compstmt: stmts opt_terms
100
+ {
101
+ result = @builder.compstmt(val[0])
102
+ }
103
+
104
+ stmts: none
105
+ {
106
+ result = []
107
+ }
108
+ | stmt
109
+ {
110
+ result = [ val[0] ]
111
+ }
112
+ | stmts terms stmt
113
+ {
114
+ result = val[0] << val[2]
115
+ }
116
+ | error stmt
117
+ {
118
+ result = [ val[1] ]
119
+ }
120
+
121
+ stmt: kALIAS fitem
122
+ {
123
+ @lexer.state = :expr_fname
124
+ }
125
+ fitem
126
+ {
127
+ result = @builder.alias(val[0], val[1], val[3])
128
+ }
129
+ | kALIAS tGVAR tGVAR
130
+ {
131
+ result = @builder.alias(val[0],
132
+ @builder.gvar(val[1]),
133
+ @builder.gvar(val[2]))
134
+ }
135
+ | kALIAS tGVAR tBACK_REF
136
+ {
137
+ result = @builder.alias(val[0],
138
+ @builder.gvar(val[1]),
139
+ @builder.back_ref(val[2]))
140
+ }
141
+ | kALIAS tGVAR tNTH_REF
142
+ {
143
+ diagnostic(:error, :nth_ref_alias, val[2])
144
+ }
145
+ | kUNDEF undef_list
146
+ {
147
+ result = @builder.undef_method(val[0], val[1])
148
+ }
149
+ | stmt kIF_MOD expr_value
150
+ {
151
+ result = @builder.condition_mod(val[0], nil,
152
+ val[1], val[2])
153
+ }
154
+ | stmt kUNLESS_MOD expr_value
155
+ {
156
+ result = @builder.condition_mod(nil, val[0],
157
+ val[1], val[2])
158
+ }
159
+ | stmt kWHILE_MOD expr_value
160
+ {
161
+ result = @builder.loop_mod(val[0], val[1], val[2])
162
+ }
163
+ | stmt kUNTIL_MOD expr_value
164
+ {
165
+ result = @builder.loop_mod(val[0], val[1], val[2])
166
+ }
167
+ | stmt kRESCUE_MOD stmt
168
+ {
169
+ rescue_body = @builder.rescue_body(val[1],
170
+ nil, nil, nil,
171
+ nil, val[2])
172
+
173
+ result = @builder.begin_body(val[0], [ rescue_body ])
174
+ }
175
+ | klEND tLCURLY compstmt tRCURLY
176
+ {
177
+ if in_def?
178
+ diagnostic(:warning, :end_in_method, val[0])
179
+ end
180
+
181
+ result = @builder.postexe(val[0], val[1], val[2], val[3])
182
+ }
183
+ | command_asgn
184
+ | mlhs tEQL command_call
185
+ {
186
+ result = @builder.multi_assign(val[0], val[1], val[2])
187
+ }
188
+ | var_lhs tOP_ASGN command_call
189
+ {
190
+ result = @builder.op_assign(val[0], val[1], val[2])
191
+ }
192
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
193
+ {
194
+ result = @builder.op_assign(
195
+ @builder.index(
196
+ val[0], val[1], val[2], val[3]),
197
+ val[4], val[5])
198
+ }
199
+ | primary_value tDOT tIDENTIFIER tOP_ASGN command_call
200
+ {
201
+ result = @builder.op_assign(
202
+ @builder.call_method(
203
+ val[0], val[1], val[2]),
204
+ val[3], val[4])
205
+ }
206
+ | primary_value tDOT tCONSTANT tOP_ASGN command_call
207
+ {
208
+ result = @builder.op_assign(
209
+ @builder.call_method(
210
+ val[0], val[1], val[2]),
211
+ val[3], val[4])
212
+ }
213
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
214
+ {
215
+ result = @builder.op_assign(
216
+ @builder.call_method(
217
+ val[0], val[1], val[2]),
218
+ val[3], val[4])
219
+ }
220
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
221
+ {
222
+ result = @builder.op_assign(
223
+ @builder.call_method(
224
+ val[0], val[1], val[2]),
225
+ val[3], val[4])
226
+ }
227
+ | backref tOP_ASGN command_call
228
+ {
229
+ @builder.op_assign(val[0], val[1], val[2])
230
+ }
231
+ | lhs tEQL mrhs
232
+ {
233
+ result = @builder.assign(val[0], val[1],
234
+ @builder.array(nil, val[2], nil))
235
+ }
236
+ | mlhs tEQL arg_value
237
+ {
238
+ result = @builder.multi_assign(val[0], val[1], val[2])
239
+ }
240
+ | mlhs tEQL mrhs
241
+ {
242
+ result = @builder.multi_assign(val[0], val[1],
243
+ @builder.array(nil, val[2], nil))
244
+ }
245
+ | expr
246
+
247
+ command_asgn: lhs tEQL command_call
248
+ {
249
+ result = @builder.assign(val[0], val[1], val[2])
250
+ }
251
+ | lhs tEQL command_asgn
252
+ {
253
+ result = @builder.assign(val[0], val[1], val[2])
254
+ }
255
+
256
+ expr: command_call
257
+ | expr kAND expr
258
+ {
259
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
260
+ }
261
+ | expr kOR expr
262
+ {
263
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
264
+ }
265
+ | kNOT opt_nl expr
266
+ {
267
+ result = @builder.not_op(val[0], val[2])
268
+ }
269
+ | tBANG command_call
270
+ {
271
+ result = @builder.not_op(val[0], val[1])
272
+ }
273
+ | arg
274
+
275
+ expr_value: expr
276
+ {
277
+ result = value_expr(val[0])
278
+ }
279
+
280
+ command_call: command
281
+ | block_command
282
+
283
+ block_command: block_call
284
+ | block_call tDOT operation2 command_args
285
+ {
286
+ result = @builder.call_method(val[0], val[1], val[2],
287
+ nil, val[3], nil)
288
+ }
289
+ | block_call tCOLON2 operation2 command_args
290
+ {
291
+ result = @builder.call_method(val[0], val[1], val[2],
292
+ nil, val[3], nil)
293
+ }
294
+
295
+ cmd_brace_block: tLBRACE_ARG
296
+ {
297
+ @static_env.extend_dynamic
298
+ }
299
+ opt_block_param compstmt tRCURLY
300
+ {
301
+ result = [ val[0], val[2], val[3], val[4] ]
302
+
303
+ @static_env.unextend
304
+ }
305
+
306
+ command: operation command_args =tLOWEST
307
+ {
308
+ result = @builder.call_method(nil, nil, val[0],
309
+ nil, val[1], nil)
310
+ }
311
+ | operation command_args cmd_brace_block
312
+ {
313
+ method_call = @builder.call_method(nil, nil, val[0],
314
+ nil, val[1], nil)
315
+
316
+ begin_t, args, body, end_t = val[2]
317
+ result = @builder.block(method_call,
318
+ begin_t, args, body, end_t)
319
+ }
320
+ | primary_value tDOT operation2 command_args =tLOWEST
321
+ {
322
+ result = @builder.call_method(val[0], val[1], val[2],
323
+ nil, val[3], nil)
324
+ }
325
+ | primary_value tDOT operation2 command_args cmd_brace_block
326
+ {
327
+ method_call = @builder.call_method(val[0], val[1], val[2],
328
+ nil, val[3], nil)
329
+
330
+ begin_t, args, body, end_t = val[4]
331
+ result = @builder.block(method_call,
332
+ begin_t, args, body, end_t)
333
+ }
334
+ | primary_value tCOLON2 operation2 command_args =tLOWEST
335
+ {
336
+ result = @builder.call_method(val[0], val[1], val[2],
337
+ nil, val[3], nil)
338
+ }
339
+ | primary_value tCOLON2 operation2 command_args cmd_brace_block
340
+ {
341
+ method_call = @builder.call_method(val[0], val[1], val[2],
342
+ nil, val[3], nil)
343
+
344
+ begin_t, args, body, end_t = val[4]
345
+ result = @builder.block(method_call,
346
+ begin_t, args, body, end_t)
347
+ }
348
+ | kSUPER command_args
349
+ {
350
+ result = @builder.keyword_cmd(:super, val[0],
351
+ nil, val[1], nil)
352
+ }
353
+ | kYIELD command_args
354
+ {
355
+ result = @builder.keyword_cmd(:yield, val[0],
356
+ nil, val[1], nil)
357
+ }
358
+ | kRETURN call_args
359
+ {
360
+ result = @builder.keyword_cmd(:return, val[0],
361
+ nil, val[1], nil)
362
+ }
363
+ | kBREAK call_args
364
+ {
365
+ result = @builder.keyword_cmd(:break, val[0],
366
+ nil, val[1], nil)
367
+ }
368
+ | kNEXT call_args
369
+ {
370
+ result = @builder.keyword_cmd(:next, val[0],
371
+ nil, val[1], nil)
372
+ }
373
+
374
+ mlhs: mlhs_basic
375
+ {
376
+ result = @builder.multi_lhs(nil, val[0], nil)
377
+ }
378
+ | tLPAREN mlhs_inner rparen
379
+ {
380
+ result = @builder.parenthesize(val[0], val[1], val[2])
381
+ }
382
+
383
+ mlhs_inner: mlhs_basic
384
+ {
385
+ result = @builder.multi_lhs(nil, val[0], nil)
386
+ }
387
+ | tLPAREN mlhs_inner rparen
388
+ {
389
+ result = @builder.multi_lhs(val[0], val[1], val[2])
390
+ }
391
+
392
+ mlhs_basic: mlhs_head
393
+ | mlhs_head mlhs_item
394
+ {
395
+ result = val[0].
396
+ push(val[1])
397
+ }
398
+ | mlhs_head tSTAR mlhs_node
399
+ {
400
+ result = val[0].
401
+ push(@builder.splat(val[1], val[2]))
402
+ }
403
+ | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
404
+ {
405
+ result = val[0].
406
+ push(@builder.splat(val[1], val[2])).
407
+ concat(val[4])
408
+ }
409
+ | mlhs_head tSTAR
410
+ {
411
+ result = val[0].
412
+ push(@builder.splat(val[1]))
413
+ }
414
+ | mlhs_head tSTAR tCOMMA mlhs_post
415
+ {
416
+ result = val[0].
417
+ push(@builder.splat(val[1])).
418
+ concat(val[3])
419
+ }
420
+ | tSTAR mlhs_node
421
+ {
422
+ result = [ @builder.splat(val[0], val[1]) ]
423
+ }
424
+ | tSTAR mlhs_node tCOMMA mlhs_post
425
+ {
426
+ result = [ @builder.splat(val[0], val[1]),
427
+ *val[3] ]
428
+ }
429
+ | tSTAR
430
+ {
431
+ result = [ @builder.splat(val[0]) ]
432
+ }
433
+ | tSTAR tCOMMA mlhs_post
434
+ {
435
+ result = [ @builder.splat(val[0]),
436
+ *val[2] ]
437
+ }
438
+
439
+ mlhs_item: mlhs_node
440
+ | tLPAREN mlhs_inner rparen
441
+ {
442
+ result = @builder.parenthesize(val[0], val[1], val[2])
443
+ }
444
+
445
+ mlhs_head: mlhs_item tCOMMA
446
+ {
447
+ result = [ val[0] ]
448
+ }
449
+ | mlhs_head mlhs_item tCOMMA
450
+ {
451
+ result = val[0] << val[1]
452
+ }
453
+
454
+ mlhs_post: mlhs_item
455
+ {
456
+ result = [ val[0] ]
457
+ }
458
+ | mlhs_post tCOMMA mlhs_item
459
+ {
460
+ result = val[0] << val[2]
461
+ }
462
+
463
+ mlhs_node: user_variable
464
+ {
465
+ result = @builder.assignable(val[0])
466
+ }
467
+ | keyword_variable
468
+ {
469
+ result = @builder.assignable(val[0])
470
+ }
471
+ | primary_value tLBRACK2 opt_call_args rbracket
472
+ {
473
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
474
+ }
475
+ | primary_value tDOT tIDENTIFIER
476
+ {
477
+ result = @builder.attr_asgn(val[0], val[1], val[2])
478
+ }
479
+ | primary_value tCOLON2 tIDENTIFIER
480
+ {
481
+ result = @builder.attr_asgn(val[0], val[1], val[2])
482
+ }
483
+ | primary_value tDOT tCONSTANT
484
+ {
485
+ result = @builder.attr_asgn(val[0], val[1], val[2])
486
+ }
487
+ | primary_value tCOLON2 tCONSTANT
488
+ {
489
+ if in_def?
490
+ diagnostic(:error, :dynamic_const, val[2])
491
+ end
492
+
493
+ result = @builder.assignable(
494
+ @builder.const_fetch(val[0], val[1], val[2]))
495
+ }
496
+ | tCOLON3 tCONSTANT
497
+ {
498
+ if in_def?
499
+ diagnostic(:error, :dynamic_const, val[1])
500
+ end
501
+
502
+ result = @builder.assignable(
503
+ @builder.const_global(val[0], val[1]))
504
+ }
505
+ | backref
506
+ {
507
+ result = @builder.assignable(val[0])
508
+ }
509
+
510
+ lhs: user_variable
511
+ {
512
+ result = @builder.assignable(val[0])
513
+ }
514
+ | keyword_variable
515
+ {
516
+ result = @builder.assignable(val[0])
517
+ }
518
+ | primary_value tLBRACK2 opt_call_args rbracket
519
+ {
520
+ result = @builder.index_asgn(val[0], val[1], val[2], val[3])
521
+ }
522
+ | primary_value tDOT tIDENTIFIER
523
+ {
524
+ result = @builder.attr_asgn(val[0], val[1], val[2])
525
+ }
526
+ | primary_value tCOLON2 tIDENTIFIER
527
+ {
528
+ result = @builder.attr_asgn(val[0], val[1], val[2])
529
+ }
530
+ | primary_value tDOT tCONSTANT
531
+ {
532
+ result = @builder.attr_asgn(val[0], val[1], val[2])
533
+ }
534
+ | primary_value tCOLON2 tCONSTANT
535
+ {
536
+ if in_def?
537
+ diagnostic(:error, :dynamic_const, val[2])
538
+ end
539
+
540
+ result = @builder.assignable(
541
+ @builder.const_fetch(val[0], val[1], val[2]))
542
+ }
543
+ | tCOLON3 tCONSTANT
544
+ {
545
+ if in_def?
546
+ diagnostic(:error, :dynamic_const, val[1])
547
+ end
548
+
549
+ result = @builder.assignable(
550
+ @builder.const_global(val[0], val[1]))
551
+ }
552
+ | backref
553
+ {
554
+ result = @builder.assignable(val[0])
555
+ }
556
+
557
+ cname: tIDENTIFIER
558
+ {
559
+ diagnostic(:error, :module_name_const, val[0])
560
+ }
561
+ | tCONSTANT
562
+
563
+ cpath: tCOLON3 cname
564
+ {
565
+ result = @builder.const_global(val[0], val[1])
566
+ }
567
+ | cname
568
+ {
569
+ result = @builder.const(val[0])
570
+ }
571
+ | primary_value tCOLON2 cname
572
+ {
573
+ result = @builder.const_fetch(val[0], val[1], val[2])
574
+ }
575
+
576
+ fname: tIDENTIFIER | tCONSTANT | tFID
577
+ | op
578
+ | reswords
579
+
580
+ fsym: fname
581
+ {
582
+ result = @builder.symbol(val[0])
583
+ }
584
+ | symbol
585
+
586
+ fitem: fsym
587
+ | dsym
588
+
589
+ undef_list: fitem
590
+ {
591
+ result = [ val[0] ]
592
+ }
593
+ | undef_list tCOMMA
594
+ {
595
+ @lexer.state = :expr_fname
596
+ }
597
+ fitem
598
+ {
599
+ result = val[0] << val[3]
600
+ }
601
+
602
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
603
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
604
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
605
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tBANG | tTILDE
606
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
607
+
608
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
609
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
610
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
611
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
612
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
613
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
614
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
615
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
616
+ | kUNTIL
617
+
618
+ arg: lhs tEQL arg
619
+ {
620
+ result = @builder.assign(val[0], val[1], val[2])
621
+ }
622
+ | lhs tEQL arg kRESCUE_MOD arg
623
+ {
624
+ rescue_body = @builder.rescue_body(val[3],
625
+ nil, nil, nil,
626
+ nil, val[4])
627
+
628
+ rescue_ = @builder.begin_body(val[2], [ rescue_body ])
629
+
630
+ result = @builder.assign(val[0], val[1], rescue_)
631
+ }
632
+ | var_lhs tOP_ASGN arg
633
+ {
634
+ result = @builder.op_assign(val[0], val[1], val[2])
635
+ }
636
+ | var_lhs tOP_ASGN arg kRESCUE_MOD arg
637
+ {
638
+ rescue_body = @builder.rescue_body(val[3],
639
+ nil, nil, nil,
640
+ nil, val[4])
641
+
642
+ rescue_ = @builder.begin_body(val[2], [ rescue_body ])
643
+
644
+ result = @builder.op_assign(val[0], val[1], rescue_)
645
+ }
646
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
647
+ {
648
+ result = @builder.op_assign(
649
+ @builder.index(
650
+ val[0], val[1], val[2], val[3]),
651
+ val[4], val[5])
652
+ }
653
+ | primary_value tDOT tIDENTIFIER tOP_ASGN arg
654
+ {
655
+ result = @builder.op_assign(
656
+ @builder.call_method(
657
+ val[0], val[1], val[2]),
658
+ val[3], val[4])
659
+ }
660
+ | primary_value tDOT tCONSTANT tOP_ASGN arg
661
+ {
662
+ result = @builder.op_assign(
663
+ @builder.call_method(
664
+ val[0], val[1], val[2]),
665
+ val[3], val[4])
666
+ }
667
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
668
+ {
669
+ result = @builder.op_assign(
670
+ @builder.call_method(
671
+ val[0], val[1], val[2]),
672
+ val[3], val[4])
673
+ }
674
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
675
+ {
676
+ diagnostic(:error, :dynamic_const, val[2], [ val[3] ])
677
+ }
678
+ | tCOLON3 tCONSTANT tOP_ASGN arg
679
+ {
680
+ diagnostic(:error, :dynamic_const, val[1], [ val[2] ])
681
+ }
682
+ | backref tOP_ASGN arg
683
+ {
684
+ result = @builder.op_assign(val[0], val[1], val[2])
685
+ }
686
+ | arg tDOT2 arg
687
+ {
688
+ result = @builder.range_inclusive(val[0], val[1], val[2])
689
+ }
690
+ | arg tDOT3 arg
691
+ {
692
+ result = @builder.range_exclusive(val[0], val[1], val[2])
693
+ }
694
+ | arg tPLUS arg
695
+ {
696
+ result = @builder.binary_op(val[0], val[1], val[2])
697
+ }
698
+ | arg tMINUS arg
699
+ {
700
+ result = @builder.binary_op(val[0], val[1], val[2])
701
+ }
702
+ | arg tSTAR2 arg
703
+ {
704
+ result = @builder.binary_op(val[0], val[1], val[2])
705
+ }
706
+ | arg tDIVIDE arg
707
+ {
708
+ result = @builder.binary_op(val[0], val[1], val[2])
709
+ }
710
+ | arg tPERCENT arg
711
+ {
712
+ result = @builder.binary_op(val[0], val[1], val[2])
713
+ }
714
+ | arg tPOW arg
715
+ {
716
+ result = @builder.binary_op(val[0], val[1], val[2])
717
+ }
718
+ | tUMINUS_NUM tINTEGER tPOW arg
719
+ {
720
+ result = @builder.unary_op(val[0],
721
+ @builder.binary_op(
722
+ @builder.integer(val[1]),
723
+ val[2], val[3]))
724
+ }
725
+ | tUMINUS_NUM tFLOAT tPOW arg
726
+ {
727
+ result = @builder.unary_op(val[0],
728
+ @builder.binary_op(
729
+ @builder.float(val[1]),
730
+ val[2], val[3]))
731
+ }
732
+ | tUPLUS arg
733
+ {
734
+ result = @builder.unary_op(val[0], val[1])
735
+ }
736
+ | tUMINUS arg
737
+ {
738
+ result = @builder.unary_op(val[0], val[1])
739
+ }
740
+ | arg tPIPE arg
741
+ {
742
+ result = @builder.binary_op(val[0], val[1], val[2])
743
+ }
744
+ | arg tCARET arg
745
+ {
746
+ result = @builder.binary_op(val[0], val[1], val[2])
747
+ }
748
+ | arg tAMPER2 arg
749
+ {
750
+ result = @builder.binary_op(val[0], val[1], val[2])
751
+ }
752
+ | arg tCMP arg
753
+ {
754
+ result = @builder.binary_op(val[0], val[1], val[2])
755
+ }
756
+ | arg tGT arg
757
+ {
758
+ result = @builder.binary_op(val[0], val[1], val[2])
759
+ }
760
+ | arg tGEQ arg
761
+ {
762
+ result = @builder.binary_op(val[0], val[1], val[2])
763
+ }
764
+ | arg tLT arg
765
+ {
766
+ result = @builder.binary_op(val[0], val[1], val[2])
767
+ }
768
+ | arg tLEQ arg
769
+ {
770
+ result = @builder.binary_op(val[0], val[1], val[2])
771
+ }
772
+ | arg tEQ arg
773
+ {
774
+ result = @builder.binary_op(val[0], val[1], val[2])
775
+ }
776
+ | arg tEQQ arg
777
+ {
778
+ result = @builder.binary_op(val[0], val[1], val[2])
779
+ }
780
+ | arg tNEQ arg
781
+ {
782
+ result = @builder.binary_op(val[0], val[1], val[2])
783
+ }
784
+ | arg tMATCH arg
785
+ {
786
+ result = @builder.binary_op(val[0], val[1], val[2])
787
+ }
788
+ | arg tNMATCH arg
789
+ {
790
+ result = @builder.binary_op(val[0], val[1], val[2])
791
+ }
792
+ | tBANG arg
793
+ {
794
+ result = @builder.not_op(val[0], val[1])
795
+ }
796
+ | tTILDE arg
797
+ {
798
+ result = @builder.unary_op(val[0], val[1])
799
+ }
800
+ | arg tLSHFT arg
801
+ {
802
+ result = @builder.binary_op(val[0], val[1], val[2])
803
+ }
804
+ | arg tRSHFT arg
805
+ {
806
+ result = @builder.binary_op(val[0], val[1], val[2])
807
+ }
808
+ | arg tANDOP arg
809
+ {
810
+ result = @builder.logical_op(:and, val[0], val[1], val[2])
811
+ }
812
+ | arg tOROP arg
813
+ {
814
+ result = @builder.logical_op(:or, val[0], val[1], val[2])
815
+ }
816
+ | kDEFINED opt_nl arg
817
+ {
818
+ result = @builder.keyword_cmd(:defined?, val[0], nil, [ val[2] ], nil)
819
+ }
820
+
821
+ | arg tEH arg opt_nl tCOLON arg
822
+ {
823
+ result = @builder.ternary(val[0], val[1],
824
+ val[2], val[4], val[5])
825
+ }
826
+ | primary
827
+
828
+ arg_value: arg
829
+ {
830
+ result = value_expr(val[0])
831
+ }
832
+
833
+ aref_args: none
834
+ | args trailer
835
+ | args tCOMMA assocs trailer
836
+ {
837
+ result = val[0] << @builder.associate(nil, val[2], nil)
838
+ }
839
+ | assocs trailer
840
+ {
841
+ result = [ @builder.associate(nil, val[0], nil) ]
842
+ }
843
+
844
+ paren_args: tLPAREN2 opt_call_args rparen
845
+ {
846
+ result = val
847
+ }
848
+
849
+ opt_paren_args: none
850
+ {
851
+ result = [ nil, [], nil ]
852
+ }
853
+ | paren_args
854
+
855
+ opt_call_args: none
856
+ {
857
+ result = []
858
+ }
859
+ | call_args
860
+ | args tCOMMA
861
+ | args tCOMMA assocs tCOMMA
862
+ {
863
+ result = val[0] << @builder.associate(nil, val[2], nil)
864
+ }
865
+ | assocs tCOMMA
866
+ {
867
+ result = [ @builder.associate(nil, val[0], nil) ]
868
+ }
869
+
870
+ call_args: command
871
+ {
872
+ result = [ val[0] ]
873
+ }
874
+ | args opt_block_arg
875
+ {
876
+ result = val[0].concat(val[1])
877
+ }
878
+ | assocs opt_block_arg
879
+ {
880
+ result = [ @builder.associate(nil, val[0], nil) ]
881
+ result.concat(val[1])
882
+ }
883
+ | args tCOMMA assocs opt_block_arg
884
+ {
885
+ assocs = @builder.associate(nil, val[2], nil)
886
+ result = val[0] << assocs
887
+ result.concat(val[3])
888
+ }
889
+ | block_arg
890
+ {
891
+ result = [ val[0] ]
892
+ }
893
+
894
+ command_args: {
895
+ result = @lexer.cmdarg.dup
896
+ @lexer.cmdarg.push(true)
897
+ }
898
+ call_args
899
+ {
900
+ @lexer.cmdarg = val[0]
901
+
902
+ result = val[1]
903
+ }
904
+
905
+ block_arg: tAMPER arg_value
906
+ {
907
+ result = @builder.block_pass(val[0], val[1])
908
+ }
909
+
910
+ opt_block_arg: tCOMMA block_arg
911
+ {
912
+ result = [ val[1] ]
913
+ }
914
+ | none
915
+ {
916
+ result = []
917
+ }
918
+
919
+ args: arg_value
920
+ {
921
+ result = [ val[0] ]
922
+ }
923
+ | tSTAR arg_value
924
+ {
925
+ result = [ @builder.splat(val[0], val[1]) ]
926
+ }
927
+ | args tCOMMA arg_value
928
+ {
929
+ result = val[0] << val[2]
930
+ }
931
+ | args tCOMMA tSTAR arg_value
932
+ {
933
+ result = val[0] << @builder.splat(val[2], val[3])
934
+ }
935
+
936
+ mrhs: args tCOMMA arg_value
937
+ {
938
+ result = val[0] << val[2]
939
+ }
940
+ | args tCOMMA tSTAR arg_value
941
+ {
942
+ result = val[0] << @builder.splat(val[2], val[3])
943
+ }
944
+ | tSTAR arg_value
945
+ {
946
+ result = [ @builder.splat(val[0], val[1]) ]
947
+ }
948
+
949
+ primary: literal
950
+ | strings
951
+ | xstring
952
+ | regexp
953
+ | words
954
+ | qwords
955
+ | var_ref
956
+ | backref
957
+ | tFID
958
+ {
959
+ result = @builder.call_method(nil, nil, val[0])
960
+ }
961
+ | kBEGIN bodystmt kEND
962
+ {
963
+ result = @builder.begin(val[0], val[1], val[2])
964
+ }
965
+ | tLPAREN_ARG expr
966
+ {
967
+ @lexer.state = :expr_endarg
968
+ }
969
+ opt_nl tRPAREN
970
+ {
971
+ # TODO better location info here
972
+ diagnostic :warning, :grouped_expression, val[0]
973
+
974
+ result = @builder.parenthesize(val[0], val[1], val[3])
975
+ }
976
+ | tLPAREN compstmt tRPAREN
977
+ {
978
+ result = @builder.parenthesize(val[0], val[1], val[2])
979
+ }
980
+ | primary_value tCOLON2 tCONSTANT
981
+ {
982
+ result = @builder.const_fetch(val[0], val[1], val[2])
983
+ }
984
+ | tCOLON3 tCONSTANT
985
+ {
986
+ result = @builder.const_global(val[0], val[1])
987
+ }
988
+ | tLBRACK aref_args tRBRACK
989
+ {
990
+ result = @builder.array(val[0], val[1], val[2])
991
+ }
992
+ | tLBRACE assoc_list tRCURLY
993
+ {
994
+ result = @builder.associate(val[0], val[1], val[2])
995
+ }
996
+ | kRETURN
997
+ {
998
+ result = @builder.keyword_cmd(:return, val[0])
999
+ }
1000
+ | kYIELD tLPAREN2 call_args rparen
1001
+ {
1002
+ result = @builder.keyword_cmd(:yield, val[0], val[1], val[2], val[3])
1003
+ }
1004
+ | kYIELD tLPAREN2 rparen
1005
+ {
1006
+ result = @builder.keyword_cmd(:yield, val[0], val[1], [], val[2])
1007
+ }
1008
+ | kYIELD
1009
+ {
1010
+ result = @builder.keyword_cmd(:yield, val[0])
1011
+ }
1012
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1013
+ {
1014
+ result = @builder.keyword_cmd(:defined?, val[0],
1015
+ val[2], [ val[3] ], val[4])
1016
+ }
1017
+ | kNOT tLPAREN2 expr rparen
1018
+ {
1019
+ result = @builder.not_op(val[0], val[2])
1020
+ }
1021
+ | kNOT tLPAREN2 rparen
1022
+ {
1023
+ result = @builder.not_op(val[0])
1024
+ }
1025
+ | operation brace_block
1026
+ {
1027
+ method_call = @builder.call_method(nil, nil, val[0])
1028
+
1029
+ begin_t, args, body, end_t = val[1]
1030
+ result = @builder.block(method_call,
1031
+ begin_t, args, body, end_t)
1032
+ }
1033
+ | method_call
1034
+ | method_call brace_block
1035
+ {
1036
+ begin_t, args, body, end_t = val[1]
1037
+ result = @builder.block(val[0],
1038
+ begin_t, args, body, end_t)
1039
+ }
1040
+ | tLAMBDA lambda
1041
+ {
1042
+ lambda_call = @builder.call_lambda(val[0])
1043
+
1044
+ args, (begin_t, body, end_t) = val[1]
1045
+ result = @builder.block(lambda_call,
1046
+ begin_t, args, body, end_t)
1047
+ }
1048
+ | kIF expr_value then compstmt if_tail kEND
1049
+ {
1050
+ else_t, else_ = val[4]
1051
+ result = @builder.condition(val[0], val[1], val[2],
1052
+ val[3], else_t,
1053
+ else_, val[5])
1054
+ }
1055
+ | kUNLESS expr_value then compstmt opt_else kEND
1056
+ {
1057
+ else_t, else_ = val[4]
1058
+ result = @builder.condition(val[0], val[1], val[2],
1059
+ else_, else_t,
1060
+ val[3], val[5])
1061
+ }
1062
+ | kWHILE
1063
+ {
1064
+ @lexer.cond.push(true)
1065
+ }
1066
+ expr_value do
1067
+ {
1068
+ @lexer.cond.pop
1069
+ }
1070
+ compstmt kEND
1071
+ {
1072
+ result = @builder.loop(val[0], val[2], val[3],
1073
+ val[5], val[6])
1074
+ }
1075
+ | kUNTIL
1076
+ {
1077
+ @lexer.cond.push(true)
1078
+ }
1079
+ expr_value do
1080
+ {
1081
+ @lexer.cond.pop
1082
+ }
1083
+ compstmt kEND
1084
+ {
1085
+ result = @builder.loop(val[0], val[2], val[3],
1086
+ val[5], val[6])
1087
+ }
1088
+ | kCASE expr_value opt_terms case_body kEND
1089
+ {
1090
+ result = @builder.case(val[0], val[1], val[3], val[4])
1091
+ }
1092
+ | kCASE opt_terms case_body kEND
1093
+ {
1094
+ result = @builder.case(val[0], nil, val[2], val[3])
1095
+ }
1096
+ | kFOR for_var kIN
1097
+ {
1098
+ @lexer.cond.push(true)
1099
+ }
1100
+ expr_value do
1101
+ {
1102
+ @lexer.cond.pop
1103
+ }
1104
+ compstmt kEND
1105
+ {
1106
+ result = @builder.for(val[0], val[1],
1107
+ val[2], val[4],
1108
+ val[5], val[7], val[8])
1109
+ }
1110
+ | kCLASS cpath superclass
1111
+ {
1112
+ if in_def?
1113
+ diagnostic(:error, :class_in_def, val[0])
1114
+ end
1115
+
1116
+ @comments.push @lexer.clear_comments
1117
+ @static_env.extend_static
1118
+ }
1119
+ bodystmt kEND
1120
+ {
1121
+ lt_t, superclass = val[2]
1122
+ result = @builder.def_class(val[0], val[1],
1123
+ lt_t, superclass,
1124
+ val[4], val[5])
1125
+
1126
+ @static_env.unextend
1127
+ @lexer.clear_comments
1128
+ }
1129
+ | kCLASS tLSHFT expr term
1130
+ {
1131
+ result = @def_level
1132
+ @def_level = 0
1133
+
1134
+ @static_env.extend_static
1135
+ }
1136
+ bodystmt kEND
1137
+ {
1138
+ result = @builder.def_sclass(val[0], val[1], val[2],
1139
+ val[5], val[6])
1140
+
1141
+ @static_env.unextend
1142
+ @lexer.clear_comments
1143
+
1144
+ @def_level = val[4]
1145
+ }
1146
+ | kMODULE cpath
1147
+ {
1148
+ if in_def?
1149
+ diagnostic(:error, :module_in_def, val[0])
1150
+ end
1151
+
1152
+ @comments.push @lexer.clear_comments
1153
+ @static_env.extend_static
1154
+ }
1155
+ bodystmt kEND
1156
+ {
1157
+ result = @builder.def_module(val[0], val[1],
1158
+ val[3], val[4])
1159
+
1160
+ @static_env.unextend
1161
+ @lexer.clear_comments
1162
+ }
1163
+ | kDEF fname
1164
+ {
1165
+ @comments.push @lexer.clear_comments
1166
+ @def_level += 1
1167
+ @static_env.extend_static
1168
+ }
1169
+ f_arglist bodystmt kEND
1170
+ {
1171
+ result = @builder.def_method(val[0], val[1],
1172
+ val[3], val[4], val[5], @comments.pop)
1173
+
1174
+ @static_env.unextend
1175
+ @def_level -= 1
1176
+ @lexer.clear_comments
1177
+ }
1178
+ | kDEF singleton dot_or_colon
1179
+ {
1180
+ @comments.push @lexer.clear_comments
1181
+ @lexer.state = :expr_fname
1182
+ }
1183
+ fname
1184
+ {
1185
+ @def_level += 1
1186
+ @static_env.extend_static
1187
+ }
1188
+ f_arglist bodystmt kEND
1189
+ {
1190
+ result = @builder.def_singleton(val[0], val[1], val[2],
1191
+ val[4], val[6], val[7], val[8], @comments.pop)
1192
+
1193
+ @static_env.unextend
1194
+ @def_level -= 1
1195
+ @lexer.clear_comments
1196
+ }
1197
+ | kBREAK
1198
+ {
1199
+ result = @builder.keyword_cmd(:break, val[0])
1200
+ }
1201
+ | kNEXT
1202
+ {
1203
+ result = @builder.keyword_cmd(:next, val[0])
1204
+ }
1205
+ | kREDO
1206
+ {
1207
+ result = @builder.keyword_cmd(:redo, val[0])
1208
+ }
1209
+ | kRETRY
1210
+ {
1211
+ result = @builder.keyword_cmd(:retry, val[0])
1212
+ }
1213
+
1214
+ primary_value: primary
1215
+ {
1216
+ result = value_expr(val[0])
1217
+ }
1218
+
1219
+ then: term
1220
+ | kTHEN
1221
+ | term kTHEN
1222
+
1223
+ do: term
1224
+ | kDO_COND
1225
+
1226
+ if_tail: opt_else
1227
+ | kELSIF expr_value then compstmt if_tail
1228
+ {
1229
+ else_t, else_ = val[4]
1230
+ result = [ val[0],
1231
+ @builder.condition(val[0], val[1], val[2],
1232
+ val[3], else_t,
1233
+ else_, nil),
1234
+ ]
1235
+ }
1236
+
1237
+ opt_else: none
1238
+ | kELSE compstmt
1239
+ {
1240
+ result = val
1241
+ }
1242
+
1243
+ for_var: lhs
1244
+ | mlhs
1245
+
1246
+ f_marg: f_norm_arg
1247
+ {
1248
+ @static_env.declare val[0][0]
1249
+
1250
+ result = @builder.arg(val[0])
1251
+ }
1252
+ | tLPAREN f_margs rparen
1253
+ {
1254
+ result = @builder.multi_lhs(val[0], val[1], val[2])
1255
+ }
1256
+
1257
+ f_marg_list: f_marg
1258
+ {
1259
+ result = [ val[0] ]
1260
+ }
1261
+ | f_marg_list tCOMMA f_marg
1262
+ {
1263
+ result = val[0] << val[2]
1264
+ }
1265
+
1266
+ f_margs: f_marg_list
1267
+ | f_marg_list tCOMMA tSTAR f_norm_arg
1268
+ {
1269
+ @static_env.declare val[3][0]
1270
+
1271
+ result = val[0].
1272
+ push(@builder.splatarg(val[2], val[3]))
1273
+ }
1274
+ | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1275
+ {
1276
+ @static_env.declare val[3][0]
1277
+
1278
+ result = val[0].
1279
+ push(@builder.splatarg(val[2], val[3])).
1280
+ concat(val[5])
1281
+ }
1282
+ | f_marg_list tCOMMA tSTAR
1283
+ {
1284
+ result = val[0].
1285
+ push(@builder.splatarg(val[2]))
1286
+ }
1287
+ | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1288
+ {
1289
+ result = val[0].
1290
+ push(@builder.splatarg(val[2])).
1291
+ concat(val[4])
1292
+ }
1293
+ | tSTAR f_norm_arg
1294
+ {
1295
+ @static_env.declare val[1][0]
1296
+
1297
+ result = [ @builder.splatarg(val[0], val[1]) ]
1298
+ }
1299
+ | tSTAR f_norm_arg tCOMMA f_marg_list
1300
+ {
1301
+ @static_env.declare val[1][0]
1302
+
1303
+ result = [ @builder.splatarg(val[0], val[1]),
1304
+ *val[3] ]
1305
+ }
1306
+ | tSTAR
1307
+ {
1308
+ result = [ @builder.splatarg(val[0]) ]
1309
+ }
1310
+ | tSTAR tCOMMA f_marg_list
1311
+ {
1312
+ result = [ @builder.splatarg(val[0]),
1313
+ *val[2] ]
1314
+ }
1315
+
1316
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
1317
+ {
1318
+ result = val[0].
1319
+ concat(val[2]).
1320
+ concat(val[4]).
1321
+ concat(val[5])
1322
+ }
1323
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1324
+ {
1325
+ result = val[0].
1326
+ concat(val[2]).
1327
+ concat(val[4]).
1328
+ concat(val[6]).
1329
+ concat(val[7])
1330
+ }
1331
+ | f_arg tCOMMA f_block_optarg opt_f_block_arg
1332
+ {
1333
+ result = val[0].
1334
+ concat(val[2]).
1335
+ concat(val[3])
1336
+ }
1337
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_f_block_arg
1338
+ {
1339
+ result = val[0].
1340
+ concat(val[2]).
1341
+ concat(val[4]).
1342
+ concat(val[5])
1343
+ }
1344
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
1345
+ {
1346
+ result = val[0].
1347
+ concat(val[2]).
1348
+ concat(val[3])
1349
+ }
1350
+ | f_arg tCOMMA
1351
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1352
+ {
1353
+ result = val[0].
1354
+ concat(val[2]).
1355
+ concat(val[4]).
1356
+ concat(val[5])
1357
+ }
1358
+ | f_arg opt_f_block_arg
1359
+ {
1360
+ result = val[0].concat(val[1])
1361
+ }
1362
+ | f_block_optarg tCOMMA f_rest_arg opt_f_block_arg
1363
+ {
1364
+ result = val[0].
1365
+ concat(val[2]).
1366
+ concat(val[3])
1367
+ }
1368
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1369
+ {
1370
+ result = val[0].
1371
+ concat(val[2]).
1372
+ concat(val[4]).
1373
+ concat(val[5])
1374
+ }
1375
+ | f_block_optarg opt_f_block_arg
1376
+ {
1377
+ result = val[0].
1378
+ concat(val[1])
1379
+ }
1380
+ | f_block_optarg tCOMMA f_arg opt_f_block_arg
1381
+ {
1382
+ result = val[0].
1383
+ concat(val[2]).
1384
+ concat(val[3])
1385
+ }
1386
+ | f_rest_arg opt_f_block_arg
1387
+ {
1388
+ result = val[0].
1389
+ concat(val[1])
1390
+ }
1391
+ | f_rest_arg tCOMMA f_arg opt_f_block_arg
1392
+ {
1393
+ result = val[0].
1394
+ concat(val[2]).
1395
+ concat(val[3])
1396
+ }
1397
+ | f_block_arg
1398
+ {
1399
+ result = [ val[0] ]
1400
+ }
1401
+
1402
+ opt_block_param: none
1403
+ {
1404
+ result = @builder.args(nil, [], nil)
1405
+ }
1406
+ | block_param_def
1407
+
1408
+ block_param_def: tPIPE opt_bv_decl tPIPE
1409
+ {
1410
+ result = @builder.args(val[0], val[1], val[2])
1411
+ }
1412
+ | tOROP
1413
+ {
1414
+ result = @builder.args(val[0], [], val[0])
1415
+ }
1416
+ | tPIPE block_param opt_bv_decl tPIPE
1417
+ {
1418
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
1419
+ }
1420
+
1421
+ opt_bv_decl: none
1422
+ {
1423
+ result = []
1424
+ }
1425
+ | tSEMI bv_decls
1426
+ {
1427
+ result = val[1]
1428
+ }
1429
+
1430
+ bv_decls: bvar
1431
+ {
1432
+ result = [ val[0] ]
1433
+ }
1434
+ | bv_decls tCOMMA bvar
1435
+ {
1436
+ result = val[0] << val[2]
1437
+ }
1438
+
1439
+ bvar: tIDENTIFIER
1440
+ {
1441
+ result = @builder.shadowarg(val[0])
1442
+ }
1443
+ | f_bad_arg
1444
+
1445
+ lambda: f_larglist lambda_body
1446
+ {
1447
+ result = [ val[0], val[1] ]
1448
+ }
1449
+
1450
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1451
+ {
1452
+ result = @builder.args(val[0], val[1].concat(val[2]), val[3])
1453
+ }
1454
+ | f_args
1455
+ {
1456
+ result = @builder.args(nil, val[0], nil)
1457
+ }
1458
+
1459
+ lambda_body: tLAMBEG compstmt tRCURLY
1460
+ {
1461
+ result = [ val[0], val[1], val[2] ]
1462
+ }
1463
+ | kDO_LAMBDA compstmt kEND
1464
+ {
1465
+ result = [ val[0], val[1], val[2] ]
1466
+ }
1467
+
1468
+ do_block: kDO_BLOCK
1469
+ {
1470
+ @static_env.extend_dynamic
1471
+ }
1472
+ opt_block_param compstmt kEND
1473
+ {
1474
+ result = [ val[0], val[2], val[3], val[4] ]
1475
+
1476
+ @static_env.unextend
1477
+ }
1478
+
1479
+ block_call: command do_block
1480
+ {
1481
+ begin_t, block_args, body, end_t = val[1]
1482
+ result = @builder.block(val[0],
1483
+ begin_t, block_args, body, end_t)
1484
+ }
1485
+ | block_call tDOT operation2 opt_paren_args
1486
+ {
1487
+ lparen_t, args, rparen_t = val[3]
1488
+ result = @builder.call_method(val[0], val[1], val[2],
1489
+ lparen_t, args, rparen_t)
1490
+ }
1491
+ | block_call tCOLON2 operation2 opt_paren_args
1492
+ {
1493
+ lparen_t, args, rparen_t = val[3]
1494
+ result = @builder.call_method(val[0], val[1], val[2],
1495
+ lparen_t, args, rparen_t)
1496
+ }
1497
+
1498
+ method_call: operation paren_args
1499
+ {
1500
+ lparen_t, args, rparen_t = val[1]
1501
+ result = @builder.call_method(nil, nil, val[0],
1502
+ lparen_t, args, rparen_t)
1503
+ }
1504
+ | primary_value tDOT operation2 opt_paren_args
1505
+ {
1506
+ lparen_t, args, rparen_t = val[3]
1507
+ result = @builder.call_method(val[0], val[1], val[2],
1508
+ lparen_t, args, rparen_t)
1509
+ }
1510
+ | primary_value tCOLON2 operation2 paren_args
1511
+ {
1512
+ lparen_t, args, rparen_t = val[3]
1513
+ result = @builder.call_method(val[0], val[1], val[2],
1514
+ lparen_t, args, rparen_t)
1515
+ }
1516
+ | primary_value tCOLON2 operation3
1517
+ {
1518
+ result = @builder.call_method(val[0], val[1], val[2])
1519
+ }
1520
+ | primary_value tDOT paren_args
1521
+ {
1522
+ lparen_t, args, rparen_t = val[2]
1523
+ result = @builder.call_method(val[0], val[1], nil,
1524
+ lparen_t, args, rparen_t)
1525
+ }
1526
+ | primary_value tCOLON2 paren_args
1527
+ {
1528
+ lparen_t, args, rparen_t = val[2]
1529
+ result = @builder.call_method(val[0], val[1], nil,
1530
+ lparen_t, args, rparen_t)
1531
+ }
1532
+ | kSUPER paren_args
1533
+ {
1534
+ lparen_t, args, rparen_t = val[1]
1535
+ result = @builder.keyword_cmd(:super, val[0],
1536
+ lparen_t, args, rparen_t)
1537
+ }
1538
+ | kSUPER
1539
+ {
1540
+ result = @builder.keyword_cmd(:zsuper, val[0])
1541
+ }
1542
+ | primary_value tLBRACK2 opt_call_args rbracket
1543
+ {
1544
+ result = @builder.index(val[0], val[1], val[2], val[3])
1545
+ }
1546
+
1547
+ brace_block: tLCURLY
1548
+ {
1549
+ @static_env.extend_dynamic
1550
+ }
1551
+ opt_block_param compstmt tRCURLY
1552
+ {
1553
+ result = [ val[0], val[2], val[3], val[4] ]
1554
+
1555
+ @static_env.unextend
1556
+ }
1557
+ | kDO
1558
+ {
1559
+ @static_env.extend_dynamic
1560
+ }
1561
+ opt_block_param compstmt kEND
1562
+ {
1563
+ result = [ val[0], val[2], val[3], val[4] ]
1564
+
1565
+ @static_env.unextend
1566
+ }
1567
+
1568
+ case_body: kWHEN args then compstmt cases
1569
+ {
1570
+ result = [ @builder.when(val[0], val[1], val[2], val[3]),
1571
+ *val[4] ]
1572
+ }
1573
+
1574
+ cases: opt_else
1575
+ {
1576
+ else_t, else_ = val[0]
1577
+ result = [ else_ ]
1578
+ }
1579
+ | case_body
1580
+
1581
+ opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1582
+ {
1583
+ assoc_t, exc_var = val[2]
1584
+
1585
+ if val[1]
1586
+ exc_list = @builder.array(nil, val[1], nil)
1587
+ end
1588
+
1589
+ result = [ @builder.rescue_body(val[0],
1590
+ exc_list, assoc_t, exc_var,
1591
+ val[3], val[4]),
1592
+ *val[5] ]
1593
+ }
1594
+ |
1595
+ {
1596
+ result = []
1597
+ }
1598
+
1599
+ exc_list: arg_value
1600
+ {
1601
+ result = [ val[0] ]
1602
+ }
1603
+ | mrhs
1604
+ | none
1605
+
1606
+ exc_var: tASSOC lhs
1607
+ {
1608
+ result = val
1609
+ }
1610
+ | none
1611
+
1612
+ opt_ensure: kENSURE compstmt
1613
+ {
1614
+ result = val
1615
+ }
1616
+ | none
1617
+
1618
+ literal: numeric
1619
+ | symbol
1620
+ | dsym
1621
+
1622
+ strings: string
1623
+ {
1624
+ result = @builder.string_compose(nil, val[0], nil)
1625
+ }
1626
+
1627
+ string: string1
1628
+ {
1629
+ result = [ val[0] ]
1630
+ }
1631
+ | string string1
1632
+ {
1633
+ result = val[0] << val[1]
1634
+ }
1635
+
1636
+ string1: tSTRING_BEG string_contents tSTRING_END
1637
+ {
1638
+ result = @builder.string_compose(val[0], val[1], val[2])
1639
+ }
1640
+ | tSTRING
1641
+ {
1642
+ result = @builder.string(val[0])
1643
+ }
1644
+
1645
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
1646
+ {
1647
+ result = @builder.xstring_compose(val[0], val[1], val[2])
1648
+ }
1649
+
1650
+ regexp: tREGEXP_BEG regexp_contents tSTRING_END tREGEXP_OPT
1651
+ {
1652
+ opts = @builder.regexp_options(val[3])
1653
+ result = @builder.regexp_compose(val[0], val[1], val[2], opts)
1654
+ }
1655
+
1656
+ words: tWORDS_BEG tSPACE tSTRING_END
1657
+ { # :nocov: TODO: unused with Ragel lexer; remove?
1658
+ result = @builder.words_compose(val[0], [], val[2])
1659
+ }
1660
+ | tWORDS_BEG word_list tSTRING_END
1661
+ {
1662
+ result = @builder.words_compose(val[0], val[1], val[2])
1663
+ }
1664
+
1665
+ word_list: none
1666
+ {
1667
+ result = []
1668
+ }
1669
+ | word_list word tSPACE
1670
+ {
1671
+ result = val[0] << val[1]
1672
+ }
1673
+
1674
+ word: string_content
1675
+ | word string_content
1676
+ { # :nocov: TODO: test this rule, remove if unused
1677
+ raise "unused 'word string_content'"
1678
+ }
1679
+
1680
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
1681
+ { # :nocov: TODO: unused with Ragel lexer; remove?
1682
+ result = @builder.words_compose(val[0], [], val[2])
1683
+ }
1684
+ | tQWORDS_BEG qword_list tSTRING_END
1685
+ {
1686
+ result = @builder.words_compose(val[0], val[1], val[2])
1687
+ }
1688
+
1689
+ qword_list: none
1690
+ {
1691
+ result = []
1692
+ }
1693
+ | qword_list tSTRING_CONTENT tSPACE
1694
+ {
1695
+ result = val[0] << @builder.string(val[1])
1696
+ }
1697
+
1698
+ string_contents: none
1699
+ {
1700
+ result = []
1701
+ }
1702
+ | string_contents string_content
1703
+ {
1704
+ result = val[0] << val[1]
1705
+ }
1706
+
1707
+ xstring_contents: none # TODO: replace with string_contents?
1708
+ {
1709
+ result = []
1710
+ }
1711
+ | xstring_contents string_content
1712
+ {
1713
+ result = val[0] << val[1]
1714
+ }
1715
+
1716
+ regexp_contents: none
1717
+ {
1718
+ result = []
1719
+ }
1720
+ | regexp_contents string_content
1721
+ {
1722
+ result = val[0] << val[1]
1723
+ }
1724
+
1725
+ string_content: tSTRING_CONTENT
1726
+ {
1727
+ result = @builder.string(val[0])
1728
+ }
1729
+ | tSTRING_DVAR string_dvar
1730
+ {
1731
+ result = val[1]
1732
+ }
1733
+ | tSTRING_DBEG
1734
+ {
1735
+ @lexer.cond.push(false)
1736
+ @lexer.cmdarg.push(false)
1737
+ }
1738
+ compstmt tRCURLY
1739
+ {
1740
+ @lexer.cond.lexpop
1741
+ @lexer.cmdarg.lexpop
1742
+
1743
+ result = val[2]
1744
+ }
1745
+
1746
+ string_dvar: tGVAR
1747
+ {
1748
+ result = @builder.gvar(val[0])
1749
+ }
1750
+ | tIVAR
1751
+ {
1752
+ result = @builder.ivar(val[0])
1753
+ }
1754
+ | tCVAR
1755
+ {
1756
+ result = @builder.cvar(val[0])
1757
+ }
1758
+ | backref
1759
+
1760
+
1761
+ symbol: tSYMBEG sym
1762
+ { # :nocov: TODO: not used, delete.
1763
+ result = nil
1764
+ }
1765
+ | tSYMBOL
1766
+ {
1767
+ result = @builder.symbol(val[0])
1768
+ }
1769
+
1770
+ sym: fname | tIVAR | tGVAR | tCVAR
1771
+
1772
+ dsym: tSYMBEG xstring_contents tSTRING_END
1773
+ {
1774
+ result = @builder.symbol_compose(val[0], val[1], val[2])
1775
+ }
1776
+
1777
+ numeric: tINTEGER
1778
+ {
1779
+ result = @builder.integer(val[0])
1780
+ }
1781
+ | tFLOAT
1782
+ {
1783
+ result = @builder.float(val[0])
1784
+ }
1785
+ | tUMINUS_NUM tINTEGER =tLOWEST
1786
+ {
1787
+ result = @builder.integer(val[1], true)
1788
+ }
1789
+ | tUMINUS_NUM tFLOAT =tLOWEST
1790
+ {
1791
+ result = @builder.float(val[1], true)
1792
+ }
1793
+
1794
+ user_variable: tIDENTIFIER
1795
+ {
1796
+ result = @builder.ident(val[0])
1797
+ }
1798
+ | tIVAR
1799
+ {
1800
+ result = @builder.ivar(val[0])
1801
+ }
1802
+ | tGVAR
1803
+ {
1804
+ result = @builder.gvar(val[0])
1805
+ }
1806
+ | tCONSTANT
1807
+ {
1808
+ result = @builder.const(val[0])
1809
+ }
1810
+ | tCVAR
1811
+ {
1812
+ result = @builder.cvar(val[0])
1813
+ }
1814
+
1815
+ keyword_variable: kNIL
1816
+ {
1817
+ result = @builder.nil(val[0])
1818
+ }
1819
+ | kSELF
1820
+ {
1821
+ result = @builder.self(val[0])
1822
+ }
1823
+ | kTRUE
1824
+ {
1825
+ result = @builder.true(val[0])
1826
+ }
1827
+ | kFALSE
1828
+ {
1829
+ result = @builder.false(val[0])
1830
+ }
1831
+ | k__FILE__
1832
+ {
1833
+ result = @builder.__FILE__(val[0])
1834
+ }
1835
+ | k__LINE__
1836
+ {
1837
+ result = @builder.__LINE__(val[0])
1838
+ }
1839
+ | k__ENCODING__
1840
+ {
1841
+ result = @builder.__ENCODING__(val[0])
1842
+ }
1843
+
1844
+ var_ref: user_variable
1845
+ {
1846
+ result = @builder.accessible(val[0])
1847
+ }
1848
+ | keyword_variable
1849
+ {
1850
+ result = @builder.accessible(val[0])
1851
+ }
1852
+
1853
+ var_lhs: user_variable
1854
+ {
1855
+ result = @builder.assignable(val[0])
1856
+ }
1857
+ | keyword_variable
1858
+ {
1859
+ result = @builder.assignable(val[0])
1860
+ }
1861
+
1862
+ backref: tNTH_REF
1863
+ {
1864
+ result = @builder.nth_ref(val[0])
1865
+ }
1866
+ | tBACK_REF
1867
+ {
1868
+ result = @builder.back_ref(val[0])
1869
+ }
1870
+
1871
+ superclass: term
1872
+ {
1873
+ result = nil
1874
+ }
1875
+ | tLT expr_value term
1876
+ {
1877
+ result = [ val[0], val[1] ]
1878
+ }
1879
+ | error term
1880
+ {
1881
+ yyerrok
1882
+ result = nil
1883
+ }
1884
+
1885
+ f_arglist: tLPAREN2 f_args rparen
1886
+ {
1887
+ result = @builder.args(val[0], val[1], val[2])
1888
+
1889
+ @lexer.state = :expr_beg
1890
+ }
1891
+ | f_args term
1892
+ {
1893
+ result = @builder.args(nil, val[0], nil)
1894
+ }
1895
+
1896
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_f_block_arg
1897
+ {
1898
+ result = val[0].
1899
+ concat(val[2]).
1900
+ concat(val[4]).
1901
+ concat(val[5])
1902
+ }
1903
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1904
+ {
1905
+ result = val[0].
1906
+ concat(val[2]).
1907
+ concat(val[4]).
1908
+ concat(val[6]).
1909
+ concat(val[7])
1910
+ }
1911
+ | f_arg tCOMMA f_optarg opt_f_block_arg
1912
+ {
1913
+ result = val[0].
1914
+ concat(val[2]).
1915
+ concat(val[3])
1916
+ }
1917
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_f_block_arg
1918
+ {
1919
+ result = val[0].
1920
+ concat(val[2]).
1921
+ concat(val[4]).
1922
+ concat(val[5])
1923
+ }
1924
+ | f_arg tCOMMA f_rest_arg opt_f_block_arg
1925
+ {
1926
+ result = val[0].
1927
+ concat(val[2]).
1928
+ concat(val[3])
1929
+ }
1930
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1931
+ {
1932
+ result = val[0].
1933
+ concat(val[2]).
1934
+ concat(val[4]).
1935
+ concat(val[5])
1936
+ }
1937
+ | f_arg opt_f_block_arg
1938
+ {
1939
+ result = val[0].
1940
+ concat(val[1])
1941
+ }
1942
+ | f_optarg tCOMMA f_rest_arg opt_f_block_arg
1943
+ {
1944
+ result = val[0].
1945
+ concat(val[2]).
1946
+ concat(val[3])
1947
+ }
1948
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_f_block_arg
1949
+ {
1950
+ result = val[0].
1951
+ concat(val[2]).
1952
+ concat(val[4]).
1953
+ concat(val[5])
1954
+ }
1955
+ | f_optarg opt_f_block_arg
1956
+ {
1957
+ result = val[0].
1958
+ concat(val[1])
1959
+ }
1960
+ | f_optarg tCOMMA f_arg opt_f_block_arg
1961
+ {
1962
+ result = val[0].
1963
+ concat(val[2]).
1964
+ concat(val[3])
1965
+ }
1966
+ | f_rest_arg opt_f_block_arg
1967
+ {
1968
+ result = val[0].
1969
+ concat(val[1])
1970
+ }
1971
+ | f_rest_arg tCOMMA f_arg opt_f_block_arg
1972
+ {
1973
+ result = val[0].
1974
+ concat(val[2]).
1975
+ concat(val[3])
1976
+ }
1977
+ | f_block_arg
1978
+ {
1979
+ result = [ val[0] ]
1980
+ }
1981
+ | # nothing
1982
+ {
1983
+ result = []
1984
+ }
1985
+
1986
+ f_bad_arg: tCONSTANT
1987
+ {
1988
+ diagnostic(:error, :argument_const, val[0])
1989
+ }
1990
+ | tIVAR
1991
+ {
1992
+ diagnostic(:error, :argument_ivar, val[0])
1993
+ }
1994
+ | tGVAR
1995
+ {
1996
+ diagnostic(:error, :argument_gvar, val[0])
1997
+ }
1998
+ | tCVAR
1999
+ {
2000
+ diagnostic(:error, :argument_cvar, val[0])
2001
+ }
2002
+
2003
+ f_norm_arg: f_bad_arg
2004
+ | tIDENTIFIER
2005
+
2006
+ f_arg_item: f_norm_arg
2007
+ {
2008
+ @static_env.declare val[0][0]
2009
+
2010
+ result = @builder.arg(val[0])
2011
+ }
2012
+ | tLPAREN f_margs rparen
2013
+ {
2014
+ result = @builder.multi_lhs(val[0], val[1], val[2])
2015
+ }
2016
+
2017
+ f_arg: f_arg_item
2018
+ {
2019
+ result = [ val[0] ]
2020
+ }
2021
+ | f_arg tCOMMA f_arg_item
2022
+ {
2023
+ result = val[0] << val[2]
2024
+ }
2025
+
2026
+ f_opt: tIDENTIFIER tEQL arg_value
2027
+ {
2028
+ @static_env.declare val[0][0]
2029
+
2030
+ result = @builder.optarg(val[0], val[1], val[2])
2031
+ }
2032
+
2033
+ f_block_opt: tIDENTIFIER tEQL primary_value
2034
+ {
2035
+ @static_env.declare val[0][0]
2036
+
2037
+ result = @builder.optarg(val[0], val[1], val[2])
2038
+ }
2039
+
2040
+ f_block_optarg: f_block_opt
2041
+ {
2042
+ result = [ val[0] ]
2043
+ }
2044
+ | f_block_optarg tCOMMA f_block_opt
2045
+ {
2046
+ result = val[0] << val[2]
2047
+ }
2048
+
2049
+ f_optarg: f_opt
2050
+ {
2051
+ result = [ val[0] ]
2052
+ }
2053
+ | f_optarg tCOMMA f_opt
2054
+ {
2055
+ result = val[0] << val[2]
2056
+ }
2057
+
2058
+ restarg_mark: tSTAR2 | tSTAR
2059
+
2060
+ f_rest_arg: restarg_mark tIDENTIFIER
2061
+ {
2062
+ @static_env.declare val[1][0]
2063
+
2064
+ result = [ @builder.splatarg(val[0], val[1]) ]
2065
+ }
2066
+ | restarg_mark
2067
+ {
2068
+ result = [ @builder.splatarg(val[0]) ]
2069
+ }
2070
+
2071
+ blkarg_mark: tAMPER2 | tAMPER
2072
+
2073
+ f_block_arg: blkarg_mark tIDENTIFIER
2074
+ {
2075
+ @static_env.declare val[1][0]
2076
+
2077
+ result = @builder.blockarg(val[0], val[1])
2078
+ }
2079
+
2080
+ opt_f_block_arg: tCOMMA f_block_arg
2081
+ {
2082
+ result = [ val[1] ]
2083
+ }
2084
+ |
2085
+ {
2086
+ result = []
2087
+ }
2088
+
2089
+ singleton: var_ref
2090
+ | tLPAREN2 expr rparen
2091
+ {
2092
+ result = val[1]
2093
+ }
2094
+
2095
+ assoc_list: none
2096
+ {
2097
+ result = []
2098
+ }
2099
+ | assocs trailer
2100
+
2101
+ assocs: assoc
2102
+ {
2103
+ result = [ val[0] ]
2104
+ }
2105
+ | assocs tCOMMA assoc
2106
+ {
2107
+ result = val[0] << val[2]
2108
+ }
2109
+
2110
+ assoc: arg_value tASSOC arg_value
2111
+ {
2112
+ result = @builder.pair(val[0], val[1], val[2])
2113
+ }
2114
+ | tLABEL arg_value
2115
+ {
2116
+ # TODO: Extract colon
2117
+ key = @builder.symbol(val[0])
2118
+ result = @builder.pair(key, nil, val[1])
2119
+ }
2120
+
2121
+ operation: tIDENTIFIER | tCONSTANT | tFID
2122
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2123
+ operation3: tIDENTIFIER | tFID | op
2124
+ dot_or_colon: tDOT | tCOLON2
2125
+ opt_terms: | terms
2126
+ opt_nl: | tNL
2127
+ rparen: opt_nl tRPAREN
2128
+ rbracket: opt_nl tRBRACK
2129
+ trailer: | tNL | tCOMMA
2130
+
2131
+ term: tSEMI
2132
+ {
2133
+ yyerrok
2134
+ }
2135
+ | tNL
2136
+
2137
+ terms: term
2138
+ | terms tSEMI
2139
+
2140
+ none: # nothing
2141
+ {
2142
+ result = nil
2143
+ }
2144
+ end
2145
+
2146
+ ---- header
2147
+
2148
+ require 'parser'
2149
+
2150
+ ---- inner
2151
+
2152
+ def version
2153
+ 19
2154
+ end