ruby_parser 3.0.0 → 3.19.1

Sign up to get free protection for your applications and to get access to all the features.
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: **