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