ruby_parser 3.0.0 → 3.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +36 -19
  4. data/History.rdoc +1297 -0
  5. data/Manifest.txt +35 -7
  6. data/{README.txt → README.rdoc} +44 -14
  7. data/Rakefile +308 -110
  8. data/bin/ruby_parse +3 -1
  9. data/bin/ruby_parse_extract_error +36 -16
  10. data/compare/normalize.rb +218 -0
  11. data/debugging.md +190 -0
  12. data/gauntlet.md +107 -0
  13. data/lib/.document +1 -0
  14. data/lib/rp_extensions.rb +53 -0
  15. data/lib/rp_stringscanner.rb +33 -0
  16. data/lib/ruby20_parser.rb +10973 -0
  17. data/lib/ruby20_parser.y +2683 -0
  18. data/lib/ruby21_parser.rb +10980 -0
  19. data/lib/ruby21_parser.y +2700 -0
  20. data/lib/ruby22_parser.rb +11123 -0
  21. data/lib/ruby22_parser.y +2711 -0
  22. data/lib/ruby23_parser.rb +11132 -0
  23. data/lib/ruby23_parser.y +2713 -0
  24. data/lib/ruby24_parser.rb +11231 -0
  25. data/lib/ruby24_parser.y +2721 -0
  26. data/lib/ruby25_parser.rb +11231 -0
  27. data/lib/ruby25_parser.y +2721 -0
  28. data/lib/ruby26_parser.rb +11253 -0
  29. data/lib/ruby26_parser.y +2736 -0
  30. data/lib/ruby27_parser.rb +12980 -0
  31. data/lib/ruby27_parser.y +3324 -0
  32. data/lib/ruby30_parser.rb +13242 -0
  33. data/lib/ruby30_parser.y +3447 -0
  34. data/lib/ruby31_parser.rb +13622 -0
  35. data/lib/ruby31_parser.y +3481 -0
  36. data/lib/ruby3_parser.yy +3536 -0
  37. data/lib/ruby_lexer.rb +933 -1232
  38. data/lib/ruby_lexer.rex +185 -0
  39. data/lib/ruby_lexer.rex.rb +399 -0
  40. data/lib/ruby_lexer_strings.rb +638 -0
  41. data/lib/ruby_parser.rb +97 -3
  42. data/lib/ruby_parser.yy +3465 -0
  43. data/lib/ruby_parser_extras.rb +1216 -687
  44. data/test/test_ruby_lexer.rb +2249 -1092
  45. data/test/test_ruby_parser.rb +5156 -975
  46. data/test/test_ruby_parser_extras.rb +47 -77
  47. data/tools/munge.rb +250 -0
  48. data/tools/ripper.rb +44 -0
  49. data.tar.gz.sig +1 -1
  50. metadata +200 -155
  51. metadata.gz.sig +0 -0
  52. data/.gemtest +0 -0
  53. data/History.txt +0 -482
  54. data/lib/gauntlet_rubyparser.rb +0 -120
  55. data/lib/ruby18_parser.rb +0 -5747
  56. data/lib/ruby18_parser.y +0 -1873
  57. data/lib/ruby19_parser.rb +0 -6110
  58. data/lib/ruby19_parser.y +0 -2078
@@ -0,0 +1,2736 @@
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
+ result = wrap :colon3, val[1]
694
+ }
695
+ | cname
696
+ {
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
699
+ }
700
+ | primary_value tCOLON2 cname
701
+ {
702
+ pval, _, (name, _line) = val
703
+
704
+ result = s(:colon2, pval, name.to_sym)
705
+ result.line pval.line
706
+ }
707
+
708
+ fname: tIDENTIFIER | tCONSTANT | tFID
709
+ | op
710
+ {
711
+ lexer.lex_state = EXPR_END
712
+ }
713
+
714
+ | reswords
715
+
716
+ fitem: fname
717
+ {
718
+ result = wrap :lit, val[0]
719
+ }
720
+ | symbol
721
+
722
+ undef_list: fitem
723
+ {
724
+ result = new_undef val[0]
725
+ }
726
+ |
727
+ undef_list tCOMMA
728
+ {
729
+ lexer.lex_state = EXPR_FNAME
730
+ }
731
+ fitem
732
+ {
733
+ result = new_undef val[0], val[3]
734
+ }
735
+
736
+ op: tPIPE | tCARET | tAMPER2 | tCMP | tEQ | tEQQ
737
+ | tMATCH | tNMATCH | tGT | tGEQ | tLT | tLEQ
738
+ | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
739
+ | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
740
+ | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
741
+
742
+ reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
743
+ | kALIAS | kAND | kBEGIN | kBREAK | kCASE
744
+ | kCLASS | kDEF | kDEFINED | kDO | kELSE
745
+ | kELSIF | kEND | kENSURE | kFALSE | kFOR
746
+ | kIN | kMODULE | kNEXT | kNIL | kNOT
747
+ | kOR | kREDO | kRESCUE | kRETRY | kRETURN
748
+ | kSELF | kSUPER | kTHEN | kTRUE | kUNDEF
749
+ | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
750
+ | kUNTIL
751
+
752
+ arg: lhs tEQL arg_rhs
753
+ {
754
+ result = new_assign val[0], val[2]
755
+ }
756
+ | var_lhs tOP_ASGN arg_rhs
757
+ {
758
+ result = new_op_asgn val
759
+ }
760
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
761
+ {
762
+ result = new_op_asgn1 val
763
+ }
764
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
765
+ {
766
+ result = new_op_asgn2 val
767
+ }
768
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
769
+ {
770
+ result = new_op_asgn2 val
771
+ }
772
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
773
+ {
774
+ lhs, _, (id, _line), (op, _), rhs = val
775
+
776
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
777
+ }
778
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
779
+ {
780
+ lhs1, _, (lhs2, _line), op, rhs = val
781
+
782
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
783
+ result = new_const_op_asgn [lhs, op, rhs]
784
+ }
785
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
786
+ {
787
+ _, lhs, op, rhs = val
788
+
789
+ lhs = wrap :colon3, lhs
790
+ result = new_const_op_asgn [lhs, op, rhs]
791
+ }
792
+ | backref tOP_ASGN arg_rhs
793
+ {
794
+ # TODO: lhs = var_field val[0]
795
+ asgn = new_op_asgn val
796
+ result = self.backref_assign_error asgn
797
+ }
798
+ | arg tDOT2 arg
799
+ {
800
+ v1, v2 = val[0], val[2]
801
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
803
+ else
804
+ result = s(:dot2, v1, v2).line v1.line
805
+ end
806
+ }
807
+ | arg tDOT3 arg
808
+ {
809
+ v1, v2 = val[0], val[2]
810
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
811
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
812
+ else
813
+ result = s(:dot3, v1, v2).line v1.line
814
+ end
815
+ }
816
+ | arg tDOT2
817
+ {
818
+ v1, _ = val
819
+ v2 = nil
820
+
821
+ result = s(:dot2, v1, v2).line v1.line
822
+ }
823
+ | arg tDOT3
824
+ {
825
+ v1, _ = val
826
+ v2 = nil
827
+
828
+ result = s(:dot3, v1, v2).line v1.line
829
+ }
830
+
831
+
832
+ | arg tPLUS arg
833
+ {
834
+ result = new_call val[0], :+, argl(val[2])
835
+ }
836
+ | arg tMINUS arg
837
+ {
838
+ result = new_call val[0], :-, argl(val[2])
839
+ }
840
+ | arg tSTAR2 arg # TODO: rename
841
+ {
842
+ result = new_call val[0], :*, argl(val[2])
843
+ }
844
+ | arg tDIVIDE arg
845
+ {
846
+ result = new_call val[0], :"/", argl(val[2])
847
+ }
848
+ | arg tPERCENT arg
849
+ {
850
+ result = new_call val[0], :"%", argl(val[2])
851
+ }
852
+ | arg tPOW arg
853
+ {
854
+ result = new_call val[0], :**, argl(val[2])
855
+ }
856
+ | tUMINUS_NUM simple_numeric tPOW arg
857
+ {
858
+ _, (num, line), _, arg = val
859
+ lit = s(:lit, num).line line
860
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
861
+
862
+ }
863
+ | tUPLUS arg
864
+ {
865
+ result = new_call val[1], :"+@"
866
+ }
867
+ | tUMINUS arg
868
+ {
869
+ result = new_call val[1], :"-@"
870
+ }
871
+ | arg tPIPE arg
872
+ {
873
+ result = new_call val[0], :"|", argl(val[2])
874
+ }
875
+ | arg tCARET arg
876
+ {
877
+ result = new_call val[0], :"^", argl(val[2])
878
+ }
879
+ | arg tAMPER2 arg
880
+ {
881
+ result = new_call val[0], :"&", argl(val[2])
882
+ }
883
+ | arg tCMP arg
884
+ {
885
+ result = new_call val[0], :"<=>", argl(val[2])
886
+ }
887
+ | rel_expr =tCMP
888
+ | arg tEQ arg
889
+ {
890
+ result = new_call val[0], :"==", argl(val[2])
891
+ }
892
+ | arg tEQQ arg
893
+ {
894
+ result = new_call val[0], :"===", argl(val[2])
895
+ }
896
+ | arg tNEQ arg
897
+ {
898
+ result = new_call val[0], :"!=", argl(val[2])
899
+ }
900
+ | arg tMATCH arg
901
+ {
902
+ lhs, _, rhs = val
903
+ result = new_match lhs, rhs
904
+ }
905
+ | arg tNMATCH arg
906
+ {
907
+ lhs, _, rhs = val
908
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
909
+ }
910
+ | tBANG arg
911
+ {
912
+ _, arg = val
913
+ result = new_call arg, :"!"
914
+ result.line arg.line
915
+ }
916
+ | tTILDE arg
917
+ {
918
+ result = new_call value_expr(val[1]), :"~"
919
+ }
920
+ | arg tLSHFT arg
921
+ {
922
+ val[0] = value_expr val[0]
923
+ val[2] = value_expr val[2]
924
+ result = new_call val[0], :"\<\<", argl(val[2])
925
+ }
926
+ | arg tRSHFT arg
927
+ {
928
+ val[0] = value_expr val[0]
929
+ val[2] = value_expr val[2]
930
+ result = new_call val[0], :">>", argl(val[2])
931
+ }
932
+ | arg tANDOP arg
933
+ {
934
+ result = logical_op :and, val[0], val[2]
935
+ }
936
+ | arg tOROP arg
937
+ {
938
+ result = logical_op :or, val[0], val[2]
939
+ }
940
+ | kDEFINED opt_nl arg
941
+ {
942
+ (_, line), _, arg = val
943
+ result = s(:defined, arg).line line
944
+ }
945
+ | arg tEH arg opt_nl tCOLON arg
946
+ {
947
+ c, _, t, _, _, f = val
948
+ result = s(:if, c, t, f).line c.line
949
+ }
950
+ | primary
951
+
952
+ relop: tGT
953
+ | tLT
954
+ | tGEQ
955
+ | tLEQ
956
+
957
+ rel_expr: arg relop arg =tGT
958
+ {
959
+ lhs, (op, _), rhs = val
960
+ result = new_call lhs, op.to_sym, argl(rhs)
961
+ }
962
+ | rel_expr relop arg =tGT
963
+ {
964
+ lhs, (op, _), rhs = val
965
+ warn "comparison '%s' after comparison", op
966
+ result = new_call lhs, op.to_sym, argl(rhs)
967
+ }
968
+
969
+ arg_value: arg
970
+ {
971
+ result = value_expr(val[0])
972
+ }
973
+
974
+ aref_args: none
975
+ | args trailer
976
+ {
977
+ result = args [val[0]]
978
+ }
979
+ | args tCOMMA assocs trailer
980
+ {
981
+ result = args [val[0], array_to_hash(val[2])]
982
+ }
983
+ | assocs trailer
984
+ {
985
+ result = args [array_to_hash(val[0])]
986
+ }
987
+
988
+ arg_rhs: arg =tOP_ASGN
989
+ | arg kRESCUE_MOD arg
990
+ {
991
+ body, (_, line), resbody = val
992
+ body = value_expr body
993
+ resbody = remove_begin resbody
994
+
995
+ ary = s(:array).line line
996
+ result = new_rescue(body, new_resbody(ary, resbody))
997
+ }
998
+
999
+ paren_args: tLPAREN2 opt_call_args rparen
1000
+ {
1001
+ _, args, _ = val
1002
+ result = args
1003
+ }
1004
+
1005
+ opt_paren_args: none
1006
+ | paren_args
1007
+
1008
+ opt_call_args: none
1009
+ | call_args
1010
+ | args tCOMMA
1011
+ {
1012
+ result = args val
1013
+ }
1014
+ | args tCOMMA assocs tCOMMA
1015
+ {
1016
+ result = args [val[0], array_to_hash(val[2])]
1017
+ }
1018
+ | assocs tCOMMA
1019
+ {
1020
+ result = args [array_to_hash(val[0])]
1021
+ }
1022
+
1023
+ call_args: command
1024
+ {
1025
+ warning "parenthesize argument(s) for future version"
1026
+ result = call_args val
1027
+ }
1028
+ | args opt_block_arg
1029
+ {
1030
+ result = call_args val
1031
+ }
1032
+ | assocs opt_block_arg
1033
+ {
1034
+ result = call_args [array_to_hash(val[0]), val[1]]
1035
+ }
1036
+ | args tCOMMA assocs opt_block_arg
1037
+ {
1038
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
1039
+ }
1040
+ | block_arg
1041
+ {
1042
+ result = call_args val
1043
+ }
1044
+
1045
+ command_args: {
1046
+ # parse26.y line 2200
1047
+
1048
+ # If call_args starts with a open paren '(' or
1049
+ # '[', look-ahead reading of the letters calls
1050
+ # CMDARG_PUSH(0), but the push must be done
1051
+ # after CMDARG_PUSH(1). So this code makes them
1052
+ # consistent by first cancelling the premature
1053
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1054
+ # finally redoing CMDARG_PUSH(0).
1055
+
1056
+ result = yychar = self.last_token_type.first
1057
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1058
+ lexer.cmdarg.pop if lookahead
1059
+ lexer.cmdarg.push true
1060
+ lexer.cmdarg.push false if lookahead
1061
+ }
1062
+ call_args
1063
+ {
1064
+ yychar, args = val
1065
+
1066
+ # call_args can be followed by tLBRACE_ARG (that
1067
+ # does CMDARG_PUSH(0) in the lexer) but the push
1068
+ # must be done after CMDARG_POP() in the parser.
1069
+ # So this code does CMDARG_POP() to pop 0 pushed
1070
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1071
+ # by command_args, and CMDARG_PUSH(0) to restore
1072
+ # back the flag set by tLBRACE_ARG.
1073
+
1074
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1075
+ lexer.cmdarg.pop if lookahead
1076
+ lexer.cmdarg.pop
1077
+ lexer.cmdarg.push false if lookahead
1078
+ result = args
1079
+ }
1080
+
1081
+ block_arg: tAMPER arg_value
1082
+ {
1083
+ _, arg = val
1084
+ result = s(:block_pass, arg).line arg.line
1085
+ }
1086
+
1087
+ opt_block_arg: tCOMMA block_arg
1088
+ {
1089
+ result = val[1]
1090
+ }
1091
+ | none
1092
+
1093
+ args: arg_value
1094
+ {
1095
+ arg, = val
1096
+ lineno = arg.line || lexer.lineno # HACK
1097
+
1098
+ result = s(:array, arg).line lineno
1099
+ }
1100
+ | tSTAR arg_value
1101
+ {
1102
+ _, arg = val
1103
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1104
+ }
1105
+ | args tCOMMA arg_value
1106
+ {
1107
+ args, _, id = val
1108
+ result = self.list_append args, id
1109
+ }
1110
+ | args tCOMMA tSTAR arg_value
1111
+ {
1112
+ # TODO: the line number from tSTAR has been dropped
1113
+ args, _, _, id = val
1114
+ line = lexer.lineno
1115
+ result = self.list_append args, s(:splat, id).line(line)
1116
+ }
1117
+
1118
+ mrhs_arg: mrhs
1119
+ {
1120
+ result = new_masgn_arg val[0]
1121
+ }
1122
+ | arg_value
1123
+ {
1124
+ result = new_masgn_arg val[0], :wrap
1125
+ }
1126
+
1127
+ mrhs: args tCOMMA arg_value
1128
+ {
1129
+ result = val[0] << val[2]
1130
+ }
1131
+ | args tCOMMA tSTAR arg_value
1132
+ {
1133
+ # TODO: make all tXXXX terminals include lexer.lineno
1134
+ arg, _, _, splat = val
1135
+ result = self.arg_concat arg, splat
1136
+ }
1137
+ | tSTAR arg_value
1138
+ {
1139
+ _, arg = val
1140
+ result = s(:splat, arg).line arg.line
1141
+ }
1142
+
1143
+ primary: literal
1144
+ | strings
1145
+ | xstring
1146
+ | regexp
1147
+ | words
1148
+ | qwords
1149
+ | symbols
1150
+ | qsymbols
1151
+ | var_ref
1152
+ | backref
1153
+ | tFID
1154
+ {
1155
+ (msg, line), = val
1156
+ result = new_call nil, msg.to_sym
1157
+ result.line line
1158
+ }
1159
+ | k_begin
1160
+ {
1161
+ lexer.cmdarg.push false
1162
+ result = self.lexer.lineno
1163
+ }
1164
+ bodystmt k_end
1165
+ {
1166
+ lexer.cmdarg.pop
1167
+ result = new_begin val
1168
+ }
1169
+ | tLPAREN_ARG
1170
+ {
1171
+ lexer.lex_state = EXPR_ENDARG
1172
+ result = lexer.lineno
1173
+ }
1174
+ rparen
1175
+ {
1176
+ _, line, _ = val
1177
+ result = s(:begin).line line
1178
+ }
1179
+ | tLPAREN_ARG
1180
+ stmt
1181
+ {
1182
+ lexer.lex_state = EXPR_ENDARG
1183
+ }
1184
+ rparen
1185
+ {
1186
+ _, stmt, _, _, = val
1187
+ # warning "(...) interpreted as grouped expression"
1188
+ result = stmt
1189
+ }
1190
+ | tLPAREN compstmt tRPAREN
1191
+ {
1192
+ _, stmt, _ = val
1193
+ result = stmt
1194
+ result ||= s(:nil).line lexer.lineno
1195
+ result.paren = true
1196
+ }
1197
+ | primary_value tCOLON2 tCONSTANT
1198
+ {
1199
+ expr, _, (id, _line) = val
1200
+
1201
+ result = s(:colon2, expr, id.to_sym).line expr.line
1202
+ }
1203
+ | tCOLON3 tCONSTANT
1204
+ {
1205
+ result = wrap :colon3, val[1]
1206
+ }
1207
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1208
+ {
1209
+ _, line, args, _ = val
1210
+ result = args || s(:array)
1211
+ result.sexp_type = :array # aref_args is :args
1212
+ result.line line
1213
+ }
1214
+ | tLBRACE
1215
+ {
1216
+ result = self.lexer.lineno
1217
+ }
1218
+ assoc_list tRCURLY
1219
+ {
1220
+ result = new_hash val
1221
+ }
1222
+ | k_return
1223
+ {
1224
+ (_, line), = val
1225
+ result = s(:return).line line
1226
+ }
1227
+ | kYIELD tLPAREN2 call_args rparen
1228
+ {
1229
+ (_, line), _, args, _ = val
1230
+
1231
+ result = new_yield(args).line line
1232
+ }
1233
+ | kYIELD tLPAREN2 rparen
1234
+ {
1235
+ (_, line), _, _ = val
1236
+
1237
+ result = new_yield.line line
1238
+ }
1239
+ | kYIELD
1240
+ {
1241
+ (_, line), = val
1242
+
1243
+ result = new_yield.line line
1244
+ }
1245
+ | kDEFINED opt_nl tLPAREN2 expr rparen
1246
+ {
1247
+ (_, line), _, _, arg, _ = val
1248
+
1249
+ result = s(:defined, arg).line line
1250
+ }
1251
+ | kNOT tLPAREN2 expr rparen
1252
+ {
1253
+ _, _, lhs, _ = val
1254
+ result = new_call lhs, :"!"
1255
+ }
1256
+ | kNOT tLPAREN2 rparen
1257
+ {
1258
+ debug 20
1259
+ }
1260
+ | fcall brace_block
1261
+ {
1262
+ call, iter = val
1263
+
1264
+ iter.insert 1, call
1265
+ result = iter
1266
+ # FIX: probably not: call.line = iter.line
1267
+ }
1268
+ | method_call
1269
+ | method_call brace_block
1270
+ {
1271
+ call, iter = val[0], val[1]
1272
+ block_dup_check call, iter
1273
+ iter.insert 1, call # FIX
1274
+ result = iter
1275
+ }
1276
+ | lambda
1277
+ {
1278
+ expr, = val
1279
+ result = expr
1280
+ }
1281
+ | k_if expr_value then compstmt if_tail k_end
1282
+ {
1283
+ _, c, _, t, f, _ = val
1284
+ result = new_if c, t, f
1285
+ }
1286
+ | k_unless expr_value then compstmt opt_else k_end
1287
+ {
1288
+ _, c, _, t, f, _ = val
1289
+ result = new_if c, f, t
1290
+ }
1291
+ | k_while expr_value_do compstmt k_end
1292
+ {
1293
+ _, cond, body, _ = val
1294
+ result = new_while body, cond, true
1295
+ }
1296
+ | k_until expr_value_do compstmt k_end
1297
+ {
1298
+ _, cond, body, _ = val
1299
+ result = new_until body, cond, true
1300
+ }
1301
+ | k_case expr_value opt_terms case_body k_end
1302
+ {
1303
+ (_, line), expr, _, body, _ = val
1304
+ result = new_case expr, body, line
1305
+ }
1306
+ | k_case opt_terms case_body k_end
1307
+ {
1308
+ (_, line), _, body, _ = val
1309
+ result = new_case nil, body, line
1310
+ }
1311
+ | k_for for_var kIN expr_value_do compstmt k_end
1312
+ {
1313
+ _, var, _, iter, body, _ = val
1314
+ result = new_for iter, var, body
1315
+ }
1316
+ | k_class
1317
+ {
1318
+ result = self.lexer.lineno
1319
+ }
1320
+ cpath superclass
1321
+ {
1322
+ if (self.in_def || self.in_single > 0) then
1323
+ yyerror "class definition in method body"
1324
+ end
1325
+ self.env.extend
1326
+ }
1327
+ bodystmt k_end
1328
+ {
1329
+ result = new_class val
1330
+ self.env.unextend
1331
+ self.lexer.ignore_body_comments
1332
+ }
1333
+ | k_class tLSHFT
1334
+ {
1335
+ result = self.lexer.lineno
1336
+ }
1337
+ expr
1338
+ {
1339
+ result = self.in_def
1340
+ self.in_def = false
1341
+ }
1342
+ term
1343
+ {
1344
+ result = self.in_single
1345
+ self.in_single = 0
1346
+ self.env.extend
1347
+ }
1348
+ bodystmt k_end
1349
+ {
1350
+ result = new_sclass val
1351
+ self.env.unextend
1352
+ self.lexer.ignore_body_comments
1353
+ }
1354
+ | k_module
1355
+ {
1356
+ result = self.lexer.lineno
1357
+ }
1358
+ cpath
1359
+ {
1360
+ yyerror "module definition in method body" if
1361
+ self.in_def or self.in_single > 0
1362
+
1363
+ self.env.extend
1364
+ }
1365
+ bodystmt k_end
1366
+ {
1367
+ result = new_module val
1368
+ self.env.unextend
1369
+ self.lexer.ignore_body_comments
1370
+ }
1371
+ | k_def fname
1372
+ {
1373
+ result = self.in_def
1374
+
1375
+ self.in_def = true # group = local_push
1376
+ self.env.extend
1377
+ lexer.cmdarg.push false
1378
+ lexer.cond.push false
1379
+ }
1380
+ f_arglist bodystmt k_end
1381
+ {
1382
+ result, in_def = new_defn val
1383
+
1384
+ lexer.cond.pop # group = local_pop
1385
+ lexer.cmdarg.pop
1386
+ self.env.unextend
1387
+ self.in_def = in_def
1388
+
1389
+ self.lexer.ignore_body_comments
1390
+ }
1391
+ | k_def singleton dot_or_colon
1392
+ {
1393
+ lexer.lex_state = EXPR_FNAME
1394
+ }
1395
+ fname
1396
+ {
1397
+ result = self.in_def
1398
+
1399
+ self.in_single += 1 # TODO: remove?
1400
+
1401
+ self.in_def = true # local_push
1402
+ self.env.extend
1403
+ lexer.cmdarg.push false
1404
+ lexer.cond.push false
1405
+
1406
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1407
+ }
1408
+ f_arglist bodystmt k_end
1409
+ {
1410
+
1411
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1412
+ # =>
1413
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1414
+
1415
+ val.delete_at 3
1416
+ val.delete_at 2
1417
+
1418
+ result, in_def = new_defs val
1419
+
1420
+ lexer.cond.pop # group = local_pop
1421
+ lexer.cmdarg.pop
1422
+ self.env.unextend
1423
+ self.in_def = in_def
1424
+
1425
+ self.in_single -= 1
1426
+
1427
+ # TODO: restore cur_arg ? what's cur_arg?
1428
+
1429
+ self.lexer.ignore_body_comments
1430
+ }
1431
+ | kBREAK
1432
+ {
1433
+ (_, line), = val
1434
+ result = s(:break).line line
1435
+ }
1436
+ | kNEXT
1437
+ {
1438
+ (_, line), = val
1439
+ result = s(:next).line line
1440
+ }
1441
+ | kREDO
1442
+ {
1443
+ (_, line), = val
1444
+ result = s(:redo).line line
1445
+ }
1446
+ | kRETRY
1447
+ {
1448
+ (_, line), = val
1449
+ result = s(:retry).line line
1450
+ }
1451
+
1452
+ primary_value: primary
1453
+ {
1454
+ result = value_expr(val[0])
1455
+ }
1456
+
1457
+ # These are really stupid
1458
+ k_begin: kBEGIN
1459
+ k_if: kIF
1460
+ k_unless: kUNLESS
1461
+ k_while: kWHILE
1462
+ k_until: kUNTIL
1463
+ k_case: kCASE
1464
+ k_for: kFOR
1465
+ k_class: kCLASS
1466
+ {
1467
+ self.comments.push self.lexer.comments
1468
+ }
1469
+ k_module: kMODULE
1470
+ {
1471
+ self.comments.push self.lexer.comments
1472
+ }
1473
+ k_def: kDEF
1474
+ {
1475
+ self.comments.push self.lexer.comments
1476
+ }
1477
+ k_do: kDO
1478
+ k_do_block: kDO_BLOCK
1479
+ k_rescue: kRESCUE
1480
+ k_ensure: kENSURE
1481
+ k_when: kWHEN
1482
+ k_else: kELSE
1483
+ k_elsif: kELSIF
1484
+ k_end: kEND
1485
+ k_return: kRETURN
1486
+
1487
+ then: term
1488
+ | kTHEN
1489
+ | term kTHEN
1490
+
1491
+ do: term
1492
+ | kDO_COND
1493
+
1494
+ if_tail: opt_else
1495
+ | k_elsif expr_value then compstmt if_tail
1496
+ {
1497
+ (_, line), c, _, t, rest = val
1498
+
1499
+ result = s(:if, c, t, rest).line line
1500
+ }
1501
+
1502
+ opt_else: none
1503
+ | kELSE compstmt
1504
+ {
1505
+ result = val[1]
1506
+ }
1507
+
1508
+ for_var: lhs
1509
+ | mlhs
1510
+ {
1511
+ val[0].delete_at 1 if val[0][1].nil? # HACK
1512
+ }
1513
+
1514
+ f_marg: f_norm_arg
1515
+ | tLPAREN f_margs rparen
1516
+ {
1517
+ result = val[1]
1518
+ }
1519
+
1520
+ f_marg_list: f_marg
1521
+ {
1522
+ sym, = val
1523
+
1524
+ result = s(:array, sym).line lexer.lineno
1525
+ }
1526
+ | f_marg_list tCOMMA f_marg
1527
+ {
1528
+ result = list_append val[0], val[2]
1529
+ }
1530
+
1531
+ f_margs: f_marg_list
1532
+ {
1533
+ args, = val
1534
+
1535
+ result = block_var args
1536
+ }
1537
+ | f_marg_list tCOMMA f_rest_marg
1538
+ {
1539
+ args, _, rest = val
1540
+
1541
+ result = block_var args, rest
1542
+ }
1543
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1544
+ {
1545
+ lhs, _, splat, _, rhs = val
1546
+
1547
+ result = block_var lhs, splat, rhs
1548
+ }
1549
+ | f_rest_marg
1550
+ {
1551
+ rest, = val
1552
+
1553
+ result = block_var rest
1554
+ }
1555
+ | f_rest_marg tCOMMA f_marg_list
1556
+ {
1557
+ splat, _, rest = val
1558
+
1559
+ result = block_var splat, rest
1560
+ }
1561
+
1562
+ f_rest_marg: tSTAR f_norm_arg
1563
+ {
1564
+ _, (id, line) = val
1565
+
1566
+ result = args ["*#{id}".to_sym]
1567
+ result.line line
1568
+ }
1569
+ | tSTAR
1570
+ {
1571
+ result = args [:*]
1572
+ result.line lexer.lineno # FIX: tSTAR -> line
1573
+ }
1574
+
1575
+ block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1576
+ {
1577
+ result = call_args val
1578
+ }
1579
+ | f_block_kwarg opt_f_block_arg
1580
+ {
1581
+ result = call_args val
1582
+ }
1583
+ | f_kwrest opt_f_block_arg
1584
+ {
1585
+ result = call_args val
1586
+ }
1587
+ | f_block_arg
1588
+ {
1589
+ (id, line), = val
1590
+ result = call_args [id]
1591
+ result.line line
1592
+ }
1593
+
1594
+ opt_block_args_tail: tCOMMA block_args_tail
1595
+ {
1596
+ result = args val
1597
+ }
1598
+ | none
1599
+
1600
+ block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1601
+ {
1602
+ result = args val
1603
+ }
1604
+ | f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1605
+ {
1606
+ result = args val
1607
+ }
1608
+ | f_arg tCOMMA f_block_optarg opt_block_args_tail
1609
+ {
1610
+ result = args val
1611
+ }
1612
+ | f_arg tCOMMA f_block_optarg tCOMMA f_arg opt_block_args_tail
1613
+ {
1614
+ result = args val
1615
+ }
1616
+ | f_arg tCOMMA f_rest_arg opt_block_args_tail
1617
+ {
1618
+ result = args val
1619
+ }
1620
+ | f_arg tCOMMA
1621
+ {
1622
+ result = args(val) << nil
1623
+ }
1624
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1625
+ {
1626
+ result = args val
1627
+ }
1628
+ | f_arg opt_block_args_tail
1629
+ {
1630
+ result = args val
1631
+ }
1632
+ | f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1633
+ {
1634
+ result = args val
1635
+ }
1636
+ | f_block_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1637
+ {
1638
+ result = args val
1639
+ }
1640
+ | f_block_optarg opt_block_args_tail
1641
+ {
1642
+ result = args val
1643
+ }
1644
+ | f_block_optarg tCOMMA f_arg opt_block_args_tail
1645
+ {
1646
+ result = args val
1647
+ }
1648
+ | f_rest_arg opt_block_args_tail
1649
+ {
1650
+ result = args val
1651
+ }
1652
+ | f_rest_arg tCOMMA f_arg opt_block_args_tail
1653
+ {
1654
+ result = args val
1655
+ }
1656
+ | block_args_tail
1657
+ {
1658
+ result = args val
1659
+ }
1660
+
1661
+ opt_block_param: none { result = 0 }
1662
+ | block_param_def
1663
+ {
1664
+ self.lexer.command_start = true
1665
+ }
1666
+
1667
+ block_param_def: tPIPE opt_bv_decl tPIPE
1668
+ {
1669
+ # TODO: current_arg = 0
1670
+ result = args val
1671
+ }
1672
+ | tOROP
1673
+ {
1674
+ result = s(:args).line lexer.lineno
1675
+ }
1676
+ | tPIPE block_param opt_bv_decl tPIPE
1677
+ {
1678
+ # TODO: current_arg = 0
1679
+ result = args val
1680
+ }
1681
+
1682
+ opt_bv_decl: opt_nl
1683
+ | opt_nl tSEMI bv_decls opt_nl
1684
+ {
1685
+ result = args val
1686
+ }
1687
+
1688
+ bv_decls: bvar
1689
+ {
1690
+ result = args val
1691
+ }
1692
+ | bv_decls tCOMMA bvar
1693
+ {
1694
+ result = args val
1695
+ }
1696
+
1697
+ bvar: tIDENTIFIER
1698
+ {
1699
+ result = wrap :shadow, val[0]
1700
+ }
1701
+ | f_bad_arg
1702
+
1703
+ lambda: tLAMBDA
1704
+ {
1705
+ self.env.extend :dynamic
1706
+ result = [lexer.lineno, lexer.lpar_beg]
1707
+ lexer.paren_nest += 1
1708
+ lexer.lpar_beg = lexer.paren_nest
1709
+ }
1710
+ f_larglist
1711
+ {
1712
+ lexer.cmdarg.push false
1713
+ }
1714
+ lambda_body
1715
+ {
1716
+ _, (line, lpar), args, _cmdarg, body = val
1717
+ lexer.lpar_beg = lpar
1718
+
1719
+ lexer.cmdarg.pop
1720
+
1721
+ call = s(:lambda).line line
1722
+ result = new_iter call, args, body
1723
+ result.line line
1724
+ self.env.unextend # TODO: dynapush & dynapop
1725
+ }
1726
+
1727
+ f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1728
+ {
1729
+ result = args val
1730
+ }
1731
+ | f_args
1732
+ {
1733
+ result = val[0]
1734
+ result = 0 if result == s(:args)
1735
+ }
1736
+
1737
+ lambda_body: tLAMBEG compstmt tRCURLY
1738
+ {
1739
+ result = val[1]
1740
+ }
1741
+ | kDO_LAMBDA bodystmt kEND
1742
+ {
1743
+ result = val[1]
1744
+ }
1745
+
1746
+ do_block: k_do_block do_body kEND
1747
+ {
1748
+ (_, line), iter, _ = val
1749
+ result = iter.line line
1750
+ }
1751
+
1752
+ block_call: command do_block
1753
+ {
1754
+ # TODO:
1755
+ ## if (nd_type($1) == NODE_YIELD) {
1756
+ ## compile_error(PARSER_ARG "block given to yield");
1757
+
1758
+ cmd, blk = val
1759
+
1760
+ syntax_error "Both block arg and actual block given." if
1761
+ cmd.block_pass?
1762
+
1763
+ if inverted? val then
1764
+ val = invert_block_call val
1765
+ cmd, blk = val
1766
+ end
1767
+
1768
+ result = blk
1769
+ result.insert 1, cmd
1770
+ }
1771
+ | block_call call_op2 operation2 opt_paren_args
1772
+ {
1773
+ lhs, _, (id, _line), args = val
1774
+
1775
+ result = new_call lhs, id.to_sym, args
1776
+ }
1777
+ | block_call call_op2 operation2 opt_paren_args brace_block
1778
+ {
1779
+ iter1, _, (name, _line), args, iter2 = val
1780
+
1781
+ call = new_call iter1, name.to_sym, args
1782
+ iter2.insert 1, call
1783
+
1784
+ result = iter2
1785
+ }
1786
+ | block_call call_op2 operation2 command_args do_block
1787
+ {
1788
+ iter1, _, (name, _line), args, iter2 = val
1789
+
1790
+ call = new_call iter1, name.to_sym, args
1791
+ iter2.insert 1, call
1792
+
1793
+ result = iter2
1794
+ }
1795
+
1796
+ method_call: fcall paren_args
1797
+ {
1798
+ call, args = val
1799
+
1800
+ result = call.concat args.sexp_body if args
1801
+ }
1802
+ | primary_value call_op operation2 opt_paren_args
1803
+ {
1804
+ recv, call_op, (op, _line), args = val
1805
+
1806
+ result = new_call recv, op.to_sym, args, call_op
1807
+ }
1808
+ | primary_value tCOLON2 operation2 paren_args
1809
+ {
1810
+ recv, _, (op, _line), args = val
1811
+
1812
+ result = new_call recv, op.to_sym, args
1813
+ }
1814
+ | primary_value tCOLON2 operation3
1815
+ {
1816
+ lhs, _, (id, _line) = val
1817
+
1818
+ result = new_call lhs, id.to_sym
1819
+ }
1820
+ | primary_value call_op paren_args
1821
+ {
1822
+ result = new_call val[0], :call, val[2], val[1]
1823
+ }
1824
+ | primary_value tCOLON2 paren_args
1825
+ {
1826
+ result = new_call val[0], :call, val[2]
1827
+ }
1828
+ | kSUPER paren_args
1829
+ {
1830
+ result = new_super val[1]
1831
+ }
1832
+ | kSUPER
1833
+ {
1834
+ result = s(:zsuper).line lexer.lineno
1835
+ }
1836
+ | primary_value tLBRACK2 opt_call_args rbracket
1837
+ {
1838
+ result = new_aref val
1839
+ }
1840
+
1841
+ brace_block: tLCURLY
1842
+ {
1843
+ self.env.extend :dynamic
1844
+ result = self.lexer.lineno
1845
+ }
1846
+ brace_body tRCURLY
1847
+ {
1848
+ _, line, body, _ = val
1849
+
1850
+ result = body
1851
+ result.line line
1852
+
1853
+ self.env.unextend
1854
+ }
1855
+ | k_do
1856
+ {
1857
+ self.env.extend :dynamic
1858
+ result = self.lexer.lineno
1859
+ }
1860
+ do_body kEND
1861
+ {
1862
+ _, line, body, _ = val
1863
+
1864
+ result = body
1865
+ result.line line
1866
+
1867
+ self.env.unextend
1868
+ }
1869
+
1870
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1871
+ { result = lexer.cmdarg.store(false) }
1872
+ opt_block_param compstmt
1873
+ {
1874
+ line, cmdarg, param, cmpstmt = val
1875
+
1876
+ result = new_brace_body param, cmpstmt, line
1877
+ self.env.unextend
1878
+ lexer.cmdarg.restore cmdarg
1879
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1880
+ }
1881
+
1882
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1883
+ { lexer.cmdarg.push false }
1884
+ opt_block_param
1885
+ bodystmt
1886
+ {
1887
+ line, _cmdarg, param, cmpstmt = val
1888
+
1889
+ result = new_do_body param, cmpstmt, line
1890
+ lexer.cmdarg.pop
1891
+ self.env.unextend
1892
+ }
1893
+
1894
+ case_args: arg_value
1895
+ {
1896
+ arg, = val
1897
+
1898
+ result = s(:array, arg).line arg.line
1899
+ }
1900
+ | tSTAR arg_value
1901
+ {
1902
+ _, arg = val
1903
+
1904
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1905
+ }
1906
+ | case_args tCOMMA arg_value
1907
+ {
1908
+ args, _, id = val
1909
+
1910
+ result = self.list_append args, id
1911
+ }
1912
+ | case_args tCOMMA tSTAR arg_value
1913
+ {
1914
+ args, _, _, id = val
1915
+
1916
+ result = self.list_append args, s(:splat, id).line(id.line)
1917
+ }
1918
+
1919
+ case_body: k_when
1920
+ {
1921
+ result = self.lexer.lineno
1922
+ }
1923
+ case_args then compstmt cases
1924
+ {
1925
+ result = new_when(val[2], val[4])
1926
+ result.line val[1]
1927
+ result << val[5] if val[5]
1928
+ }
1929
+
1930
+ cases: opt_else | case_body
1931
+
1932
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1933
+ {
1934
+ (_, line), klasses, var, _, body, rest = val
1935
+
1936
+ klasses ||= s(:array)
1937
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1938
+ klasses.line line
1939
+
1940
+ result = new_resbody(klasses, body)
1941
+ result << rest if rest # UGH, rewritten above
1942
+ }
1943
+ |
1944
+ {
1945
+ result = nil
1946
+ }
1947
+
1948
+ exc_list: arg_value
1949
+ {
1950
+ arg, = val
1951
+ result = s(:array, arg).line arg.line
1952
+ }
1953
+ | mrhs
1954
+ | none
1955
+
1956
+ exc_var: tASSOC lhs
1957
+ {
1958
+ result = val[1]
1959
+ }
1960
+ | none
1961
+
1962
+ opt_ensure: k_ensure compstmt
1963
+ {
1964
+ (_, line), body = val
1965
+
1966
+ result = body || s(:nil).line(line)
1967
+ }
1968
+ | none
1969
+
1970
+ literal: numeric
1971
+ {
1972
+ (lit, line), = val
1973
+ result = s(:lit, lit).line line
1974
+ }
1975
+ | symbol
1976
+
1977
+ strings: string
1978
+ {
1979
+ str, = val
1980
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1981
+ result = str
1982
+ }
1983
+
1984
+ string: tCHAR
1985
+ {
1986
+ debug 37
1987
+ }
1988
+ | string1
1989
+ | string string1
1990
+ {
1991
+ result = self.literal_concat val[0], val[1]
1992
+ }
1993
+
1994
+ string1: tSTRING_BEG string_contents tSTRING_END
1995
+ {
1996
+ (_, line), str, (_, func) = val
1997
+
1998
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1999
+
2000
+ result = str.line line
2001
+ }
2002
+ | tSTRING
2003
+ {
2004
+ result = new_string val
2005
+ }
2006
+
2007
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2008
+ {
2009
+ result = new_xstring val
2010
+ # TODO: dedent?!?! SERIOUSLY?!?
2011
+ }
2012
+
2013
+ regexp: tREGEXP_BEG regexp_contents tREGEXP_END
2014
+ {
2015
+ result = new_regexp val
2016
+ }
2017
+
2018
+ words: tWORDS_BEG tSPACE tSTRING_END
2019
+ {
2020
+ (_, line), _, _ = val
2021
+
2022
+ result = s(:array).line line
2023
+ }
2024
+ | tWORDS_BEG word_list tSTRING_END
2025
+ {
2026
+ (_, line), list, _ = val
2027
+
2028
+ result = list.line line
2029
+ }
2030
+
2031
+ word_list: none
2032
+ {
2033
+ result = new_word_list
2034
+ }
2035
+ | word_list word tSPACE
2036
+ {
2037
+ result = val[0].dup << new_word_list_entry(val)
2038
+ }
2039
+
2040
+ word: string_content
2041
+ | word string_content
2042
+ {
2043
+ result = self.literal_concat val[0], val[1]
2044
+ }
2045
+
2046
+ symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2047
+ {
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2051
+ }
2052
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2053
+ {
2054
+ (_, line), list, _, = val
2055
+ list.line line
2056
+ result = list
2057
+ }
2058
+
2059
+ symbol_list: none
2060
+ {
2061
+ result = new_symbol_list
2062
+ }
2063
+ | symbol_list word tSPACE
2064
+ {
2065
+ list, * = val
2066
+ result = list.dup << new_symbol_list_entry(val)
2067
+ }
2068
+
2069
+ qwords: tQWORDS_BEG tSPACE tSTRING_END
2070
+ {
2071
+ (_, line), _, _ = val
2072
+
2073
+ result = s(:array).line line
2074
+ }
2075
+ | tQWORDS_BEG qword_list tSTRING_END
2076
+ {
2077
+ (_, line), list, _ = val
2078
+
2079
+ result = list.line line
2080
+ }
2081
+
2082
+ qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2083
+ {
2084
+ (_, line), _, _ = val
2085
+
2086
+ result = s(:array).line line
2087
+ }
2088
+ | tQSYMBOLS_BEG qsym_list tSTRING_END
2089
+ {
2090
+ (_, line), list, _ = val
2091
+
2092
+ result = list.line line
2093
+ }
2094
+
2095
+ qword_list: none
2096
+ {
2097
+ result = new_qword_list
2098
+ }
2099
+ | qword_list tSTRING_CONTENT tSPACE
2100
+ {
2101
+ result = val[0].dup << new_qword_list_entry(val)
2102
+ }
2103
+
2104
+ qsym_list: none
2105
+ {
2106
+ result = new_qsym_list
2107
+ }
2108
+ | qsym_list tSTRING_CONTENT tSPACE
2109
+ {
2110
+ result = val[0].dup << new_qsym_list_entry(val)
2111
+ }
2112
+
2113
+ string_contents: none
2114
+ {
2115
+ line = prev_value_to_lineno _values.last
2116
+ result = s(:str, +"").line line
2117
+ }
2118
+ | string_contents string_content
2119
+ {
2120
+ v1, v2 = val
2121
+ result = literal_concat v1, v2
2122
+ }
2123
+
2124
+ xstring_contents: none
2125
+ {
2126
+ result = nil
2127
+ }
2128
+ | xstring_contents string_content
2129
+ {
2130
+ v1, v2 = val
2131
+ result = literal_concat v1, v2
2132
+ }
2133
+
2134
+ regexp_contents: none
2135
+ {
2136
+ result = nil
2137
+ }
2138
+ | regexp_contents string_content
2139
+ {
2140
+ v1, v2 = val
2141
+ result = literal_concat v1, v2
2142
+ }
2143
+
2144
+ string_content: tSTRING_CONTENT
2145
+ {
2146
+ result = new_string val
2147
+ }
2148
+ | tSTRING_DVAR
2149
+ {
2150
+ result = lexer.lex_strterm
2151
+
2152
+ lexer.lex_strterm = nil
2153
+ lexer.lex_state = EXPR_BEG
2154
+ }
2155
+ string_dvar
2156
+ {
2157
+ _, strterm, str = val
2158
+ lexer.lex_strterm = strterm
2159
+ result = s(:evstr, str).line str.line
2160
+ }
2161
+ | tSTRING_DBEG
2162
+ {
2163
+ result = [lexer.lex_strterm,
2164
+ lexer.brace_nest,
2165
+ lexer.string_nest, # TODO: remove
2166
+ lexer.lex_state,
2167
+ lexer.lineno,
2168
+ ]
2169
+
2170
+ lexer.cmdarg.push false
2171
+ lexer.cond.push false
2172
+
2173
+ lexer.lex_strterm = nil
2174
+ lexer.brace_nest = 0
2175
+ lexer.string_nest = 0
2176
+
2177
+ lexer.lex_state = EXPR_BEG
2178
+ }
2179
+ compstmt
2180
+ tSTRING_DEND
2181
+ {
2182
+ _, memo, stmt, _ = val
2183
+
2184
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2185
+ # TODO: heredoc_indent
2186
+
2187
+ lexer.lex_strterm = lex_strterm
2188
+ lexer.brace_nest = brace_nest
2189
+ lexer.string_nest = string_nest
2190
+
2191
+ lexer.cond.pop
2192
+ lexer.cmdarg.pop
2193
+
2194
+ lexer.lex_state = oldlex_state
2195
+
2196
+ case stmt
2197
+ when Sexp then
2198
+ case stmt.sexp_type
2199
+ when :str, :dstr, :evstr then
2200
+ result = stmt
2201
+ else
2202
+ result = s(:evstr, stmt).line line
2203
+ end
2204
+ when nil then
2205
+ result = s(:evstr).line line
2206
+ else
2207
+ debug 38
2208
+ raise "unknown string body: #{stmt.inspect}"
2209
+ end
2210
+ }
2211
+
2212
+ string_dvar: tGVAR
2213
+ {
2214
+ result = wrap :gvar, val[0]
2215
+ }
2216
+ | tIVAR
2217
+ {
2218
+ result = wrap :ivar, val[0]
2219
+ }
2220
+ | tCVAR
2221
+ {
2222
+ result = wrap :cvar, val[0]
2223
+ }
2224
+ | backref
2225
+
2226
+ symbol: ssym
2227
+ | dsym
2228
+
2229
+ ssym: tSYMBEG sym
2230
+ {
2231
+ lexer.lex_state = EXPR_END
2232
+ result = wrap :lit, val[1]
2233
+ }
2234
+ | tSYMBOL
2235
+ {
2236
+ lexer.lex_state = EXPR_END
2237
+ result = wrap :lit, val[0]
2238
+ }
2239
+
2240
+ sym: fname | tIVAR | tGVAR | tCVAR
2241
+
2242
+ dsym: tSYMBEG string_contents tSTRING_END
2243
+ {
2244
+ _, result, _ = val
2245
+
2246
+ lexer.lex_state = EXPR_END
2247
+
2248
+ result ||= s(:str, "").line lexer.lineno
2249
+
2250
+ case result.sexp_type
2251
+ when :dstr then
2252
+ result.sexp_type = :dsym
2253
+ when :str then
2254
+ result = s(:lit, result.last.to_sym).line result.line
2255
+ when :evstr then
2256
+ result = s(:dsym, "", result).line result.line
2257
+ else
2258
+ debug 39
2259
+ end
2260
+ }
2261
+
2262
+ numeric: simple_numeric
2263
+ | tUMINUS_NUM simple_numeric =tLOWEST
2264
+ {
2265
+ _, (num, line) = val
2266
+ result = [-num, line]
2267
+ }
2268
+
2269
+ simple_numeric: tINTEGER
2270
+ | tFLOAT
2271
+ | tRATIONAL
2272
+ | tIMAGINARY
2273
+
2274
+ user_variable: tIDENTIFIER
2275
+ | tIVAR
2276
+ | tGVAR
2277
+ | tCONSTANT
2278
+ | tCVAR
2279
+
2280
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2281
+ | kSELF { result = s(:self).line lexer.lineno }
2282
+ | kTRUE { result = s(:true).line lexer.lineno }
2283
+ | kFALSE { result = s(:false).line lexer.lineno }
2284
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2285
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2286
+ | k__ENCODING__
2287
+ {
2288
+ l = lexer.lineno
2289
+ result =
2290
+ if defined? Encoding then
2291
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2292
+ else
2293
+ s(:str, "Unsupported!").line l
2294
+ end
2295
+ }
2296
+
2297
+ var_ref: user_variable
2298
+ {
2299
+ raise "NO: #{val.inspect}" if Sexp === val.first
2300
+ (var, line), = val
2301
+ result = Sexp === var ? var : self.gettable(var)
2302
+ result.line line
2303
+ }
2304
+ | keyword_variable
2305
+ {
2306
+ var = val[0]
2307
+ result = Sexp === var ? var : self.gettable(var)
2308
+ }
2309
+
2310
+ var_lhs: user_variable
2311
+ {
2312
+ result = self.assignable val[0]
2313
+ }
2314
+ | keyword_variable
2315
+ {
2316
+ result = self.assignable val[0]
2317
+ debug 40
2318
+ }
2319
+
2320
+ backref: tNTH_REF
2321
+ {
2322
+ (ref, line), = val
2323
+ result = s(:nth_ref, ref).line line
2324
+ }
2325
+ | tBACK_REF
2326
+ {
2327
+ (ref, line), = val
2328
+ result = s(:back_ref, ref).line line
2329
+ }
2330
+
2331
+ superclass: tLT
2332
+ {
2333
+ lexer.lex_state = EXPR_BEG
2334
+ lexer.command_start = true
2335
+ }
2336
+ expr_value term
2337
+ {
2338
+ result = val[2]
2339
+ }
2340
+ | none
2341
+ {
2342
+ result = nil
2343
+ }
2344
+
2345
+ f_arglist: tLPAREN2 f_args rparen
2346
+ {
2347
+ result = end_args val
2348
+ }
2349
+ | {
2350
+ result = self.in_kwarg
2351
+ self.in_kwarg = true
2352
+ self.lexer.lex_state |= EXPR_LABEL
2353
+ }
2354
+ f_args term
2355
+ {
2356
+ result = end_args val
2357
+ }
2358
+
2359
+ args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
2360
+ {
2361
+ result = args val
2362
+ }
2363
+ | f_kwarg opt_f_block_arg
2364
+ {
2365
+ result = args val
2366
+ }
2367
+ | f_kwrest opt_f_block_arg
2368
+ {
2369
+ result = args val
2370
+ }
2371
+ | f_block_arg
2372
+
2373
+ opt_args_tail: tCOMMA args_tail
2374
+ {
2375
+ result = val[1]
2376
+ }
2377
+ |
2378
+ {
2379
+ result = nil
2380
+ }
2381
+
2382
+ f_args: f_arg tCOMMA f_optarg tCOMMA f_rest_arg opt_args_tail
2383
+ {
2384
+ result = args val
2385
+ }
2386
+ | f_arg tCOMMA f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2387
+ {
2388
+ result = args val
2389
+ }
2390
+ | f_arg tCOMMA f_optarg opt_args_tail
2391
+ {
2392
+ result = args val
2393
+ }
2394
+ | f_arg tCOMMA f_optarg tCOMMA f_arg opt_args_tail
2395
+ {
2396
+ result = args val
2397
+ }
2398
+ | f_arg tCOMMA f_rest_arg opt_args_tail
2399
+ {
2400
+ result = args val
2401
+ }
2402
+ | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2403
+ {
2404
+ result = args val
2405
+ }
2406
+ | f_arg opt_args_tail
2407
+ {
2408
+ result = args val
2409
+ }
2410
+ | f_optarg tCOMMA f_rest_arg opt_args_tail
2411
+ {
2412
+ result = args val
2413
+ }
2414
+ | f_optarg tCOMMA f_rest_arg tCOMMA f_arg opt_args_tail
2415
+ {
2416
+ result = args val
2417
+ }
2418
+ | f_optarg opt_args_tail
2419
+ {
2420
+ result = args val
2421
+ }
2422
+ | f_optarg tCOMMA f_arg opt_args_tail
2423
+ {
2424
+ result = args val
2425
+ }
2426
+ | f_rest_arg opt_args_tail
2427
+ {
2428
+ result = args val
2429
+ }
2430
+ | f_rest_arg tCOMMA f_arg opt_args_tail
2431
+ {
2432
+ result = args val
2433
+ }
2434
+ | args_tail
2435
+ {
2436
+ result = args val
2437
+ }
2438
+ |
2439
+ {
2440
+ result = args val
2441
+ # result.line lexer.lineno
2442
+ }
2443
+
2444
+
2445
+ f_bad_arg: tCONSTANT
2446
+ {
2447
+ yyerror "formal argument cannot be a constant"
2448
+ }
2449
+ | tIVAR
2450
+ {
2451
+ yyerror "formal argument cannot be an instance variable"
2452
+ }
2453
+ | tGVAR
2454
+ {
2455
+ yyerror "formal argument cannot be a global variable"
2456
+ }
2457
+ | tCVAR
2458
+ {
2459
+ yyerror "formal argument cannot be a class variable"
2460
+ }
2461
+
2462
+ f_norm_arg: f_bad_arg
2463
+ | tIDENTIFIER
2464
+ {
2465
+ (id, line), = val
2466
+ identifier = id.to_sym
2467
+ self.env[identifier] = :lvar
2468
+
2469
+ result = [identifier, line]
2470
+ }
2471
+
2472
+ f_arg_asgn: f_norm_arg
2473
+
2474
+ f_arg_item: f_arg_asgn
2475
+ | tLPAREN f_margs rparen
2476
+ {
2477
+ _, margs, _ = val
2478
+
2479
+ result = margs
2480
+ }
2481
+
2482
+ f_arg: f_arg_item
2483
+ {
2484
+ result = new_arg val
2485
+ }
2486
+ | f_arg tCOMMA f_arg_item
2487
+ {
2488
+ list, _, item = val
2489
+
2490
+ if list.sexp_type == :args then
2491
+ result = list
2492
+ else
2493
+ result = s(:args, list).line list.line
2494
+ end
2495
+
2496
+ result << (Sexp === item ? item : item.first)
2497
+ }
2498
+
2499
+ f_label: tLABEL
2500
+
2501
+ f_kw: f_label arg_value
2502
+ {
2503
+ # TODO: new_kw_arg
2504
+ (label, line), arg = val
2505
+
2506
+ identifier = label.to_sym
2507
+ self.env[identifier] = :lvar
2508
+
2509
+ kwarg = s(:kwarg, identifier, arg).line line
2510
+ result = s(:array, kwarg).line line
2511
+ }
2512
+ | f_label
2513
+ {
2514
+ (label, line), = val
2515
+
2516
+ id = label.to_sym
2517
+ self.env[id] = :lvar
2518
+
2519
+ result = s(:array, s(:kwarg, id).line(line)).line line
2520
+ }
2521
+
2522
+ f_block_kw: f_label primary_value
2523
+ {
2524
+ # TODO: new_kw_arg
2525
+ (label, line), expr = val
2526
+ id = label.to_sym
2527
+ self.env[id] = :lvar
2528
+
2529
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2530
+ }
2531
+ | f_label
2532
+ {
2533
+ # TODO: new_kw_arg
2534
+ (label, line), = val
2535
+ id = label.to_sym
2536
+ self.env[id] = :lvar
2537
+
2538
+ result = s(:array, s(:kwarg, id).line(line)).line line
2539
+ }
2540
+
2541
+ f_block_kwarg: f_block_kw
2542
+ | f_block_kwarg tCOMMA f_block_kw
2543
+ {
2544
+ list, _, item = val
2545
+ result = list << item.last
2546
+ }
2547
+
2548
+ f_kwarg: f_kw
2549
+ | f_kwarg tCOMMA f_kw
2550
+ {
2551
+ result = args val
2552
+ }
2553
+
2554
+ kwrest_mark: tPOW
2555
+ | tDSTAR
2556
+
2557
+
2558
+ f_kwrest: kwrest_mark tIDENTIFIER
2559
+ {
2560
+ _, (id, line) = val
2561
+
2562
+ name = id.to_sym
2563
+ self.assignable [name, line]
2564
+ result = [:"**#{name}", line]
2565
+ }
2566
+ | kwrest_mark
2567
+ {
2568
+ id = :"**"
2569
+ self.env[id] = :lvar # TODO: needed?!?
2570
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2571
+ }
2572
+
2573
+ f_opt: f_arg_asgn tEQL arg_value
2574
+ {
2575
+ lhs, _, rhs = val
2576
+ result = self.assignable lhs, rhs
2577
+ # TODO: detect duplicate names
2578
+ }
2579
+
2580
+ f_block_opt: f_arg_asgn tEQL primary_value
2581
+ {
2582
+ lhs, _, rhs = val
2583
+ result = self.assignable lhs, rhs
2584
+ }
2585
+
2586
+ f_block_optarg: f_block_opt
2587
+ {
2588
+ optblk, = val
2589
+ result = s(:block, optblk).line optblk.line
2590
+ }
2591
+ | f_block_optarg tCOMMA f_block_opt
2592
+ {
2593
+ optarg, _, optblk = val
2594
+ result = optarg
2595
+ result << optblk
2596
+ }
2597
+
2598
+ f_optarg: f_opt
2599
+ {
2600
+ opt, = val
2601
+ result = s(:block, opt).line opt.line
2602
+ }
2603
+ | f_optarg tCOMMA f_opt
2604
+ {
2605
+ result = self.block_append val[0], val[2]
2606
+ }
2607
+
2608
+ restarg_mark: tSTAR2 | tSTAR
2609
+
2610
+ f_rest_arg: restarg_mark tIDENTIFIER
2611
+ {
2612
+ # TODO: differs from parse.y - needs tests
2613
+ _, (id, line) = val
2614
+ name = id.to_sym
2615
+ self.assignable [name, line]
2616
+ result = [:"*#{name}", line]
2617
+ }
2618
+ | restarg_mark
2619
+ {
2620
+ name = :"*"
2621
+ self.env[name] = :lvar
2622
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2623
+ }
2624
+
2625
+ blkarg_mark: tAMPER2 | tAMPER
2626
+
2627
+ f_block_arg: blkarg_mark tIDENTIFIER
2628
+ {
2629
+ _, (id, line) = val
2630
+ identifier = id.to_sym
2631
+
2632
+ self.env[identifier] = :lvar
2633
+ result = ["&#{identifier}".to_sym, line]
2634
+ }
2635
+
2636
+ opt_f_block_arg: tCOMMA f_block_arg
2637
+ {
2638
+ _, arg = val
2639
+ result = arg
2640
+ }
2641
+ |
2642
+ {
2643
+ result = nil
2644
+ }
2645
+
2646
+ singleton: var_ref
2647
+ | tLPAREN2
2648
+ {
2649
+ lexer.lex_state = EXPR_BEG
2650
+ }
2651
+ expr rparen
2652
+ {
2653
+ result = val[2]
2654
+ yyerror "Can't define single method for literals." if
2655
+ result.sexp_type == :lit
2656
+ }
2657
+
2658
+ assoc_list: none
2659
+ {
2660
+ result = s(:array).line lexer.lineno
2661
+ }
2662
+ | assocs trailer
2663
+
2664
+ assocs: assoc
2665
+ | assocs tCOMMA assoc
2666
+ {
2667
+ list = val[0].dup
2668
+ more = val[2].sexp_body
2669
+ list.push(*more) unless more.empty?
2670
+ result = list
2671
+ result.sexp_type = :hash
2672
+ }
2673
+
2674
+ assoc: arg_value tASSOC arg_value
2675
+ {
2676
+ v1, _, v2 = val
2677
+ result = s(:array, v1, v2).line v1.line
2678
+ }
2679
+ | tLABEL arg_value
2680
+ {
2681
+ label, arg = val
2682
+
2683
+ lit = wrap :lit, label
2684
+ result = s(:array, lit, arg).line lit.line
2685
+ }
2686
+ | tSTRING_BEG string_contents tLABEL_END arg_value
2687
+ {
2688
+ (_, line), sym, _, value = val
2689
+
2690
+ sym.sexp_type = :dsym
2691
+
2692
+ result = s(:array, sym, value).line line
2693
+ }
2694
+ | tDSTAR arg_value
2695
+ {
2696
+ _, arg = val
2697
+ line = arg.line
2698
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2699
+ }
2700
+
2701
+ operation: tIDENTIFIER | tCONSTANT | tFID
2702
+ operation2: tIDENTIFIER | tCONSTANT | tFID | op
2703
+ operation3: tIDENTIFIER | tFID | op
2704
+ dot_or_colon: tDOT | tCOLON2
2705
+ call_op: tDOT
2706
+ | tLONELY # TODO: rename tANDDOT?
2707
+
2708
+ call_op2: call_op
2709
+ | tCOLON2
2710
+
2711
+ opt_terms: | terms
2712
+ opt_nl: | tNL
2713
+ rparen: opt_nl tRPAREN
2714
+ rbracket: opt_nl tRBRACK
2715
+ trailer: | tNL | tCOMMA
2716
+
2717
+ term: tSEMI { yyerrok }
2718
+ | tNL
2719
+
2720
+ terms: term
2721
+ | terms tSEMI { yyerrok }
2722
+
2723
+ none: { result = nil; }
2724
+ end
2725
+
2726
+ ---- inner
2727
+
2728
+ require "ruby_lexer"
2729
+ require "ruby_parser_extras"
2730
+ include RubyLexer::State::Values
2731
+
2732
+ # :stopdoc:
2733
+
2734
+ # Local Variables: **
2735
+ # racc-token-length-max:14 **
2736
+ # End: **