parser 0.9.alpha1 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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