ruby_parser 3.12.0 → 3.18.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 (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: **