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