ruby_parser 3.0.0 → 3.19.1

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