ruby_parser 3.0.0 → 3.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +36 -19
  4. data/History.rdoc +1297 -0
  5. data/Manifest.txt +35 -7
  6. data/{README.txt → README.rdoc} +44 -14
  7. data/Rakefile +308 -110
  8. data/bin/ruby_parse +3 -1
  9. data/bin/ruby_parse_extract_error +36 -16
  10. data/compare/normalize.rb +218 -0
  11. data/debugging.md +190 -0
  12. data/gauntlet.md +107 -0
  13. data/lib/.document +1 -0
  14. data/lib/rp_extensions.rb +53 -0
  15. data/lib/rp_stringscanner.rb +33 -0
  16. data/lib/ruby20_parser.rb +10973 -0
  17. data/lib/ruby20_parser.y +2683 -0
  18. data/lib/ruby21_parser.rb +10980 -0
  19. data/lib/ruby21_parser.y +2700 -0
  20. data/lib/ruby22_parser.rb +11123 -0
  21. data/lib/ruby22_parser.y +2711 -0
  22. data/lib/ruby23_parser.rb +11132 -0
  23. data/lib/ruby23_parser.y +2713 -0
  24. data/lib/ruby24_parser.rb +11231 -0
  25. data/lib/ruby24_parser.y +2721 -0
  26. data/lib/ruby25_parser.rb +11231 -0
  27. data/lib/ruby25_parser.y +2721 -0
  28. data/lib/ruby26_parser.rb +11253 -0
  29. data/lib/ruby26_parser.y +2736 -0
  30. data/lib/ruby27_parser.rb +12980 -0
  31. data/lib/ruby27_parser.y +3324 -0
  32. data/lib/ruby30_parser.rb +13242 -0
  33. data/lib/ruby30_parser.y +3447 -0
  34. data/lib/ruby31_parser.rb +13622 -0
  35. data/lib/ruby31_parser.y +3481 -0
  36. data/lib/ruby3_parser.yy +3536 -0
  37. data/lib/ruby_lexer.rb +933 -1232
  38. data/lib/ruby_lexer.rex +185 -0
  39. data/lib/ruby_lexer.rex.rb +399 -0
  40. data/lib/ruby_lexer_strings.rb +638 -0
  41. data/lib/ruby_parser.rb +97 -3
  42. data/lib/ruby_parser.yy +3465 -0
  43. data/lib/ruby_parser_extras.rb +1216 -687
  44. data/test/test_ruby_lexer.rb +2249 -1092
  45. data/test/test_ruby_parser.rb +5156 -975
  46. data/test/test_ruby_parser_extras.rb +47 -77
  47. data/tools/munge.rb +250 -0
  48. data/tools/ripper.rb +44 -0
  49. data.tar.gz.sig +1 -1
  50. metadata +200 -155
  51. metadata.gz.sig +0 -0
  52. data/.gemtest +0 -0
  53. data/History.txt +0 -482
  54. data/lib/gauntlet_rubyparser.rb +0 -120
  55. data/lib/ruby18_parser.rb +0 -5747
  56. data/lib/ruby18_parser.y +0 -1873
  57. data/lib/ruby19_parser.rb +0 -6110
  58. data/lib/ruby19_parser.y +0 -2078
@@ -0,0 +1,2721 @@
1
+ # -*- racc -*-
2
+
3
+ class Ruby24Parser
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
+ compstmt
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: **