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