ruby_parser 3.12.0 → 3.18.1

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