ruby_parser 3.13.1 → 3.21.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +18 -29
  4. data/History.rdoc +312 -0
  5. data/Manifest.txt +16 -15
  6. data/README.rdoc +13 -9
  7. data/Rakefile +237 -106
  8. data/bin/ruby_parse +3 -1
  9. data/bin/ruby_parse_extract_error +9 -4
  10. data/compare/normalize.rb +54 -6
  11. data/debugging.md +172 -0
  12. data/gauntlet.md +107 -0
  13. data/lib/rp_extensions.rb +15 -36
  14. data/lib/rp_stringscanner.rb +20 -51
  15. data/lib/ruby_lexer.rb +515 -812
  16. data/lib/ruby_lexer.rex +33 -27
  17. data/lib/ruby_lexer.rex.rb +64 -31
  18. data/lib/ruby_lexer_strings.rb +638 -0
  19. data/lib/ruby_parser.rb +46 -36
  20. data/lib/{ruby_parser.yy → ruby_parser2.yy} +1400 -488
  21. data/lib/ruby_parser20.rb +10953 -0
  22. data/lib/ruby_parser21.rb +10978 -0
  23. data/lib/ruby_parser22.rb +11119 -0
  24. data/lib/ruby_parser23.rb +11160 -0
  25. data/lib/ruby_parser24.rb +11209 -0
  26. data/lib/ruby_parser25.rb +11209 -0
  27. data/lib/ruby_parser26.rb +11231 -0
  28. data/lib/ruby_parser27.rb +12960 -0
  29. data/lib/{ruby26_parser.y → ruby_parser3.yy} +1652 -521
  30. data/lib/ruby_parser30.rb +13292 -0
  31. data/lib/ruby_parser31.rb +13625 -0
  32. data/lib/ruby_parser32.rb +13577 -0
  33. data/lib/ruby_parser33.rb +13577 -0
  34. data/lib/ruby_parser_extras.rb +988 -474
  35. data/test/test_ruby_lexer.rb +1339 -1155
  36. data/test/test_ruby_parser.rb +4255 -2103
  37. data/test/test_ruby_parser_extras.rb +39 -4
  38. data/tools/munge.rb +52 -13
  39. data/tools/ripper.rb +24 -6
  40. data.tar.gz.sig +0 -0
  41. metadata +73 -56
  42. metadata.gz.sig +0 -0
  43. data/lib/ruby20_parser.rb +0 -6869
  44. data/lib/ruby20_parser.y +0 -2431
  45. data/lib/ruby21_parser.rb +0 -6944
  46. data/lib/ruby21_parser.y +0 -2449
  47. data/lib/ruby22_parser.rb +0 -6968
  48. data/lib/ruby22_parser.y +0 -2458
  49. data/lib/ruby23_parser.rb +0 -6987
  50. data/lib/ruby23_parser.y +0 -2460
  51. data/lib/ruby24_parser.rb +0 -6994
  52. data/lib/ruby24_parser.y +0 -2466
  53. data/lib/ruby25_parser.rb +0 -6994
  54. data/lib/ruby25_parser.y +0 -2466
  55. data/lib/ruby26_parser.rb +0 -7012
@@ -14,6 +14,8 @@ class Ruby24Parser
14
14
  class Ruby25Parser
15
15
  #elif V == 26
16
16
  class Ruby26Parser
17
+ #elif V == 27
18
+ class Ruby27Parser
17
19
  #else
18
20
  fail "version not specified or supported on code generation"
19
21
  #endif
@@ -34,7 +36,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
34
36
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
35
37
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
36
38
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
37
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
39
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
38
40
  #if V >= 21
39
41
  tRATIONAL tIMAGINARY
40
42
  #endif
@@ -44,31 +46,34 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
44
46
  #if V >= 23
45
47
  tLONELY
46
48
  #endif
49
+ #if V >= 26
50
+ tBDOT2 tBDOT3
51
+ #endif
47
52
 
48
- prechigh
49
- right tBANG tTILDE tUPLUS
50
- right tPOW
51
- right tUMINUS_NUM tUMINUS
52
- left tSTAR2 tDIVIDE tPERCENT
53
- left tPLUS tMINUS
54
- left tLSHFT tRSHFT
55
- left tAMPER2
56
- left tPIPE tCARET
57
- left tGT tGEQ tLT tLEQ
58
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
59
- left tANDOP
60
- left tOROP
61
- nonassoc tDOT2 tDOT3
62
- right tEH tCOLON
63
- left kRESCUE_MOD
64
- right tEQL tOP_ASGN
65
- nonassoc kDEFINED
66
- right kNOT
67
- left kOR kAND
68
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
69
- nonassoc tLBRACE_ARG
70
- nonassoc tLOWEST
71
53
  preclow
54
+ nonassoc tLOWEST
55
+ nonassoc tLBRACE_ARG
56
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
57
+ left kOR kAND
58
+ right kNOT
59
+ nonassoc kDEFINED
60
+ right tEQL tOP_ASGN
61
+ left kRESCUE_MOD
62
+ right tEH tCOLON
63
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
64
+ left tOROP
65
+ left tANDOP
66
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
67
+ left tGT tGEQ tLT tLEQ
68
+ left tPIPE tCARET
69
+ left tAMPER2
70
+ left tLSHFT tRSHFT
71
+ left tPLUS tMINUS
72
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
73
+ right tUMINUS_NUM tUMINUS
74
+ right tPOW
75
+ right tBANG tTILDE tUPLUS
76
+ prechigh
72
77
 
73
78
  rule
74
79
 
@@ -78,11 +83,15 @@ rule
78
83
  top_compstmt
79
84
  {
80
85
  result = new_compstmt val
86
+
87
+ lexer.cond.pop # local_pop
88
+ lexer.cmdarg.pop
81
89
  }
82
90
 
83
91
  top_compstmt: top_stmts opt_terms
84
92
  {
85
- result = val[0]
93
+ stmt, _ = val
94
+ result = stmt
86
95
  }
87
96
 
88
97
  top_stmts: none
@@ -94,38 +103,41 @@ rule
94
103
  | error top_stmt
95
104
 
96
105
  top_stmt: stmt
97
- {
98
- result = val[0]
99
-
100
- # TODO: remove once I have more confidence this is fixed
101
- # result.each_of_type :call_args do |s|
102
- # debug20 666, s, result
103
- # end
104
- }
105
106
  | klBEGIN
106
107
  {
107
108
  if (self.in_def || self.in_single > 0) then
108
- debug20 1
109
+ debug 11
109
110
  yyerror "BEGIN in method"
110
111
  end
111
112
  self.env.extend
112
113
  }
113
114
  begin_block
114
115
  {
115
- _, _, block = val
116
- result = block
116
+ (_, lineno), _, iter = val
117
+ iter.line lineno
118
+
119
+ (_, preexe,) = iter
120
+ preexe.line lineno
121
+
122
+ result = iter
117
123
  }
118
124
 
119
- begin_block: tLCURLY top_compstmt tRCURLY
125
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
120
126
  {
121
- _, stmt, _ = val
122
- result = new_iter s(:preexe), 0, stmt
127
+ _, line, stmt, _ = val
128
+ result = new_iter s(:preexe).line(line), 0, stmt
123
129
  }
124
130
 
125
131
  bodystmt: compstmt opt_rescue k_else
126
132
  {
127
133
  res = _values[-2]
134
+ # TODO: move down to main match so I can just use val
135
+
136
+ #if V >= 26
128
137
  yyerror "else without rescue is useless" unless res
138
+ #else
139
+ warn "else without rescue is useless" unless res
140
+ #endif
129
141
  }
130
142
  compstmt
131
143
  opt_ensure
@@ -155,40 +167,37 @@ rule
155
167
  | error stmt
156
168
  {
157
169
  result = val[1]
158
- debug20 2, val, result
170
+ debug 12
159
171
  }
160
172
 
161
173
  stmt_or_begin: stmt
162
174
  | klBEGIN
163
175
  {
164
- if (self.in_def || self.in_single > 0) then
165
- debug20 1
166
- yyerror "BEGIN in method"
167
- end
168
- self.env.extend
176
+ yyerror "BEGIN is permitted only at toplevel"
169
177
  }
170
- begin_block
178
+ begin_block
171
179
  {
172
- _, _, stmt = val
173
- result = stmt
180
+ result = val[2] # wtf?
174
181
  }
175
182
 
176
183
  stmt: kALIAS fitem
177
184
  {
178
185
  lexer.lex_state = EXPR_FNAME
179
- result = self.lexer.lineno
180
186
  }
181
187
  fitem
182
188
  {
183
- result = s(:alias, val[1], val[3]).line(val[2])
189
+ (_, line), lhs, _, rhs = val
190
+ result = s(:alias, lhs, rhs).line(line).line line
184
191
  }
185
192
  | kALIAS tGVAR tGVAR
186
193
  {
187
- result = s(:valias, val[1].to_sym, val[2].to_sym)
194
+ (_, line), (lhs, _), (rhs, _) = val
195
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
188
196
  }
189
197
  | kALIAS tGVAR tBACK_REF
190
198
  {
191
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
199
+ (_, line), (lhs, _), (rhs, _) = val
200
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
192
201
  }
193
202
  | kALIAS tGVAR tNTH_REF
194
203
  {
@@ -200,32 +209,41 @@ rule
200
209
  }
201
210
  | stmt kIF_MOD expr_value
202
211
  {
203
- result = new_if val[2], val[0], nil
212
+ t, _, c = val
213
+ result = new_if c, t, nil
204
214
  }
205
215
  | stmt kUNLESS_MOD expr_value
206
216
  {
207
- result = new_if val[2], nil, val[0]
217
+ f, _, c = val
218
+ result = new_if c, nil, f
208
219
  }
209
220
  | stmt kWHILE_MOD expr_value
210
221
  {
211
- result = new_while val[0], val[2], true
222
+ e, _, c = val
223
+ result = new_while e, c, true
212
224
  }
213
225
  | stmt kUNTIL_MOD expr_value
214
226
  {
215
- result = new_until val[0], val[2], true
227
+ e, _, c = val
228
+ result = new_until e, c, true
216
229
  }
217
230
  | stmt kRESCUE_MOD stmt
218
231
  {
219
232
  body, _, resbody = val
220
- result = new_rescue body, new_resbody(s(:array), resbody)
233
+
234
+ resbody = new_resbody s(:array).line(resbody.line), resbody
235
+ result = new_rescue body, resbody
221
236
  }
222
237
  | klEND tLCURLY compstmt tRCURLY
223
238
  {
239
+ (_, line), _, stmt, _ = val
240
+
224
241
  if (self.in_def || self.in_single > 0) then
225
- debug20 3
242
+ debug 13
226
243
  yyerror "END in method; use at_exit"
227
244
  end
228
- result = new_iter s(:postexe), 0, val[2]
245
+
246
+ result = new_iter s(:postexe).line(line), 0, stmt
229
247
  }
230
248
  | command_asgn
231
249
  | mlhs tEQL command_call
@@ -234,13 +252,28 @@ rule
234
252
  }
235
253
  | lhs tEQL mrhs
236
254
  {
237
- result = new_assign val[0], s(:svalue, val[2])
255
+ lhs, _, rhs = val
256
+
257
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
238
258
  }
239
259
  #if V == 20
240
260
  | mlhs tEQL arg_value
241
261
  {
242
262
  result = new_masgn val[0], val[2], :wrap
243
263
  }
264
+ #endif
265
+ #if V >= 27
266
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
267
+ {
268
+ # unwraps s(:to_ary, rhs)
269
+ lhs, _, (_, rhs), _, resbody = val
270
+
271
+ resbody = new_resbody s(:array).line(resbody.line), resbody
272
+
273
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
274
+ }
275
+ #endif
276
+ #if V == 20
244
277
  | mlhs tEQL mrhs
245
278
  #else
246
279
  | mlhs tEQL mrhs_arg
@@ -264,33 +297,35 @@ rule
264
297
  }
265
298
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
266
299
  {
267
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
300
+ result = new_op_asgn1 val
268
301
  }
269
302
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
270
303
  {
271
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
272
- if val[1] == '&.'
273
- result.sexp_type = :safe_op_asgn
274
- end
275
- result.line = val[0].line
304
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
305
+
306
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
307
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
308
+ result.line prim.line
276
309
  }
277
310
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
278
311
  {
279
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
280
- if val[1] == '&.'
281
- result.sexp_type = :safe_op_asgn
282
- end
283
- result.line = val[0].line
312
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
313
+
314
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
315
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
316
+ result.line prim.line
284
317
  }
285
318
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
286
319
  {
287
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
288
- debug20 4, val, result
320
+ lhs1, _, (lhs2, line), (id, _), rhs = val
321
+
322
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
289
323
  }
290
324
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
291
325
  {
292
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
293
- debug20 5, val, result
326
+ lhs1, _, (lhs2, line), (id, _), rhs = val
327
+
328
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
294
329
  }
295
330
  | backref tOP_ASGN command_rhs
296
331
  {
@@ -305,9 +340,11 @@ rule
305
340
  #if V >= 24
306
341
  | command_call kRESCUE_MOD stmt
307
342
  {
308
- expr, _, resbody = val
343
+ expr, (_, line), resbody = val
344
+
309
345
  expr = value_expr expr
310
- result = new_rescue(expr, new_resbody(s(:array), resbody))
346
+ ary = s(:array).line line
347
+ result = new_rescue(expr, new_resbody(ary, resbody))
311
348
  }
312
349
  #endif
313
350
  | command_asgn
@@ -315,21 +352,52 @@ rule
315
352
  expr: command_call
316
353
  | expr kAND expr
317
354
  {
318
- result = logical_op :and, val[0], val[2]
355
+ lhs, _, rhs = val
356
+ result = logical_op :and, lhs, rhs
319
357
  }
320
358
  | expr kOR expr
321
359
  {
322
- result = logical_op :or, val[0], val[2]
360
+ lhs, _, rhs = val
361
+ result = logical_op :or, lhs, rhs
323
362
  }
324
363
  | kNOT opt_nl expr
325
364
  {
326
- result = s(:call, val[2], :"!")
365
+ (_, line), _, expr = val
366
+ result = new_call(expr, :"!").line line
367
+ # REFACTOR: call_uni_op
327
368
  }
328
369
  | tBANG command_call
329
370
  {
330
- result = s(:call, val[1], :"!")
371
+ _, cmd = val
372
+ result = new_call(cmd, :"!").line cmd.line
373
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
374
+ # REFACTOR: call_uni_op -- see parse26.y
331
375
  }
376
+ #if V >= 27
332
377
  | arg
378
+ kIN
379
+ {
380
+ # TODO? value_expr($1);
381
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
382
+ self.lexer.command_start = false
383
+ result = self.in_kwarg
384
+ self.in_kwarg = true
385
+ self.env.extend
386
+ }
387
+ p_expr
388
+ {
389
+ self.env.unextend
390
+
391
+ expr, _, old_kwarg, pat = val
392
+
393
+ expr = value_expr expr
394
+
395
+ self.in_kwarg = old_kwarg
396
+ pat_in = new_in pat, nil, nil, expr.line
397
+ result = new_case expr, pat_in, expr.line
398
+ }
399
+ #endif
400
+ | arg =tLBRACE_ARG
333
401
 
334
402
  expr_value: expr
335
403
  {
@@ -354,7 +422,8 @@ rule
354
422
  block_command: block_call
355
423
  | block_call call_op2 operation2 command_args
356
424
  {
357
- result = new_call val[0], val[2].to_sym, val[3]
425
+ blk, _, (msg, _line), args = val
426
+ result = new_call(blk, msg.to_sym, args).line blk.line
358
427
  }
359
428
 
360
429
  cmd_brace_block: tLBRACE_ARG
@@ -367,37 +436,45 @@ rule
367
436
  _, line, body, _ = val
368
437
 
369
438
  result = body
370
- result.line = line
439
+ result.line line
371
440
 
372
441
  # self.env.unextend
373
442
  }
374
443
 
375
444
  fcall: operation
376
445
  {
377
- result = new_call nil, val[0].to_sym
446
+ (msg, line), = val
447
+ result = new_call(nil, msg.to_sym).line line
378
448
  }
379
449
 
380
450
  command: fcall command_args =tLOWEST
381
451
  {
382
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
452
+ call, args = val
453
+ result = call.concat args.sexp_body
383
454
  }
384
455
  | fcall command_args cmd_brace_block
385
456
  {
386
- result = val[0].concat val[1].sexp_body
387
- if val[2] then
388
- block_dup_check result, val[2]
457
+ call, args, block = val
389
458
 
390
- result, operation = val[2], result
459
+ result = call.concat args.sexp_body
460
+
461
+ if block then
462
+ block_dup_check result, block
463
+
464
+ result, operation = block, result
391
465
  result.insert 1, operation
392
466
  end
393
467
  }
394
468
  | primary_value call_op operation2 command_args =tLOWEST
395
469
  {
396
- result = new_call val[0], val[2].to_sym, val[3], val[1]
470
+ lhs, callop, (op, _), args = val
471
+
472
+ result = new_call lhs, op.to_sym, args, callop
473
+ result.line lhs.line
397
474
  }
398
475
  | primary_value call_op operation2 command_args cmd_brace_block
399
476
  {
400
- recv, _, msg, args, block = val
477
+ recv, _, (msg, _line), args, block = val
401
478
  call = new_call recv, msg.to_sym, args, val[1]
402
479
 
403
480
  block_dup_check call, block
@@ -407,11 +484,14 @@ rule
407
484
  }
408
485
  | primary_value tCOLON2 operation2 command_args =tLOWEST
409
486
  {
410
- result = new_call val[0], val[2].to_sym, val[3]
487
+ lhs, _, (id, line), args = val
488
+
489
+ result = new_call lhs, id.to_sym, args
490
+ result.line line
411
491
  }
412
492
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
413
493
  {
414
- recv, _, msg, args, block = val
494
+ recv, _, (msg, _line), args, block = val
415
495
  call = new_call recv, msg.to_sym, args
416
496
 
417
497
  block_dup_check call, block
@@ -425,7 +505,9 @@ rule
425
505
  }
426
506
  | kYIELD command_args
427
507
  {
428
- result = new_yield val[1]
508
+ (_, line), args = val
509
+ result = new_yield args
510
+ result.line line # TODO: push to new_yield
429
511
  }
430
512
  | k_return call_args
431
513
  {
@@ -434,8 +516,8 @@ rule
434
516
  }
435
517
  | kBREAK call_args
436
518
  {
437
- line = val[0].last
438
- result = s(:break, ret_args(val[1])).line(line)
519
+ (_, line), args = val
520
+ result = s(:break, ret_args(args)).line line
439
521
  }
440
522
  | kNEXT call_args
441
523
  {
@@ -452,56 +534,79 @@ rule
452
534
  mlhs_inner: mlhs_basic
453
535
  | tLPAREN mlhs_inner rparen
454
536
  {
455
- result = s(:masgn, s(:array, val[1]))
537
+ _, arg, _ = val
538
+ l = arg.line
539
+
540
+ result = s(:masgn, s(:array, arg).line(l)).line l
456
541
  }
457
542
 
458
543
  mlhs_basic: mlhs_head
459
544
  {
460
- result = s(:masgn, val[0])
545
+ head, = val
546
+ result = s(:masgn, head).line head.line
461
547
  }
462
548
  | mlhs_head mlhs_item
463
549
  {
464
- result = s(:masgn, val[0] << val[1].compact)
550
+ lhs, rhs = val
551
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
465
552
  }
466
553
  | mlhs_head tSTAR mlhs_node
467
554
  {
468
- result = s(:masgn, val[0] << s(:splat, val[2]))
555
+ head, _, tail = val
556
+ head << s(:splat, tail).line(tail.line)
557
+ result = s(:masgn, head).line head.line
469
558
  }
470
559
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
471
560
  {
472
561
  ary1, _, splat, _, ary2 = val
473
562
 
474
- result = list_append ary1, s(:splat, splat)
563
+ result = list_append ary1, s(:splat, splat).line(splat.line)
475
564
  result.concat ary2.sexp_body
476
- result = s(:masgn, result)
565
+ result = s(:masgn, result).line result.line
477
566
  }
478
567
  | mlhs_head tSTAR
479
568
  {
480
- result = s(:masgn, val[0] << s(:splat))
569
+ head, _ = val
570
+ l = head.line
571
+ result = s(:masgn, head << s(:splat).line(l)).line l
481
572
  }
482
573
  | mlhs_head tSTAR tCOMMA mlhs_post
483
574
  {
484
- ary = list_append val[0], s(:splat)
485
- ary.concat val[3].sexp_body
486
- result = s(:masgn, ary)
575
+ head, _, _, post = val
576
+ ary = list_append head, s(:splat).line(head.line)
577
+ ary.concat post.sexp_body
578
+ result = s(:masgn, ary).line ary.line
487
579
  }
488
580
  | tSTAR mlhs_node
489
581
  {
490
- result = s(:masgn, s(:array, s(:splat, val[1])))
582
+ _, node = val
583
+ l = node.line
584
+ splat = s(:splat, node).line l
585
+ ary = s(:array, splat).line l
586
+ result = s(:masgn, ary).line l
491
587
  }
492
588
  | tSTAR mlhs_node tCOMMA mlhs_post
493
589
  {
494
- ary = s(:array, s(:splat, val[1]))
495
- ary.concat val[3].sexp_body
496
- result = s(:masgn, ary)
590
+ _, node, _, post = val
591
+
592
+ splat = s(:splat, node).line node.line
593
+ ary = s(:array, splat).line splat.line
594
+ ary.concat post.sexp_body
595
+ result = s(:masgn, ary).line ary.line
497
596
  }
498
597
  | tSTAR
499
598
  {
500
- result = s(:masgn, s(:array, s(:splat)))
599
+ l = lexer.lineno
600
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
501
601
  }
502
602
  | tSTAR tCOMMA mlhs_post
503
603
  {
504
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
604
+ _, _, post = val
605
+ l = post.line
606
+
607
+ splat = s(:splat).line l
608
+ ary = s(:array, splat, *post.sexp_body).line l
609
+ result = s(:masgn, ary).line l
505
610
  }
506
611
 
507
612
  mlhs_item: mlhs_node
@@ -512,7 +617,8 @@ rule
512
617
 
513
618
  mlhs_head: mlhs_item tCOMMA
514
619
  {
515
- result = s(:array, val[0])
620
+ lhs, _ = val
621
+ result = s(:array, lhs).line lhs.line
516
622
  }
517
623
  | mlhs_head mlhs_item tCOMMA
518
624
  {
@@ -521,7 +627,8 @@ rule
521
627
 
522
628
  mlhs_post: mlhs_item
523
629
  {
524
- result = s(:array, val[0])
630
+ item, = val
631
+ result = s(:array, item).line item.line
525
632
  }
526
633
  | mlhs_post tCOMMA mlhs_item
527
634
  {
@@ -542,81 +649,111 @@ rule
542
649
  }
543
650
  | primary_value call_op tIDENTIFIER
544
651
  {
545
- result = new_attrasgn val[0], val[2], val[1]
652
+ lhs, call_op, (id, _line) = val
653
+
654
+ result = new_attrasgn lhs, id, call_op
546
655
  }
547
656
  | primary_value tCOLON2 tIDENTIFIER
548
657
  {
549
- result = s(:attrasgn, val[0], :"#{val[2]}=")
658
+ recv, _, (id, _line) = val
659
+ result = new_attrasgn recv, id
550
660
  }
551
661
  | primary_value call_op tCONSTANT
552
662
  {
553
- result = new_attrasgn val[0], val[2], val[1]
663
+ lhs, call_op, (id, _line) = val
664
+
665
+ result = new_attrasgn lhs, id, call_op
554
666
  }
555
667
  | primary_value tCOLON2 tCONSTANT
556
668
  {
557
669
  if (self.in_def || self.in_single > 0) then
558
- debug20 7
670
+ debug 14
559
671
  yyerror "dynamic constant assignment"
560
672
  end
561
673
 
562
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
674
+ expr, _, (id, _line) = val
675
+ l = expr.line
676
+
677
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
563
678
  }
564
679
  | tCOLON3 tCONSTANT
565
680
  {
566
681
  if (self.in_def || self.in_single > 0) then
567
- debug20 8
682
+ debug 15
568
683
  yyerror "dynamic constant assignment"
569
684
  end
570
685
 
571
- result = s(:const, nil, s(:colon3, val[1].to_sym))
686
+ _, (id, l) = val
687
+
688
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
572
689
  }
573
690
  | backref
574
691
  {
575
- self.backref_assign_error val[0]
692
+ ref, = val
693
+
694
+ self.backref_assign_error ref
576
695
  }
577
696
 
578
697
  lhs: user_variable
579
698
  {
580
- result = self.assignable val[0]
699
+ var, = val
700
+
701
+ result = self.assignable var
581
702
  }
582
703
  | keyword_variable
583
704
  {
584
- result = self.assignable val[0]
585
- debug20 9, val, result
705
+ var, = val
706
+
707
+ result = self.assignable var
708
+
709
+ debug 16
586
710
  }
587
711
  | primary_value tLBRACK2 opt_call_args rbracket
588
712
  {
589
- result = self.aryset val[0], val[2]
713
+ lhs, _, args, _ = val
714
+
715
+ result = self.aryset lhs, args
590
716
  }
591
717
  | primary_value call_op tIDENTIFIER # REFACTOR
592
718
  {
593
- result = new_attrasgn val[0], val[2], val[1]
719
+ lhs, op, (id, _line) = val
720
+
721
+ result = new_attrasgn lhs, id, op
594
722
  }
595
723
  | primary_value tCOLON2 tIDENTIFIER
596
724
  {
597
- result = s(:attrasgn, val[0], :"#{val[2]}=")
725
+ lhs, _, (id, _line) = val
726
+
727
+ result = new_attrasgn lhs, id
598
728
  }
599
729
  | primary_value call_op tCONSTANT # REFACTOR?
600
730
  {
601
- result = new_attrasgn val[0], val[2], val[1]
731
+ lhs, call_op, (id, _line) = val
732
+
733
+ result = new_attrasgn lhs, id, call_op
602
734
  }
603
735
  | primary_value tCOLON2 tCONSTANT
604
736
  {
737
+ expr, _, (id, _line) = val
738
+
605
739
  if (self.in_def || self.in_single > 0) then
606
- debug20 10
740
+ debug 17
607
741
  yyerror "dynamic constant assignment"
608
742
  end
609
743
 
610
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
744
+ l = expr.line
745
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
611
746
  }
612
747
  | tCOLON3 tCONSTANT
613
748
  {
749
+ _, (id, l) = val
750
+
614
751
  if (self.in_def || self.in_single > 0) then
615
- debug20 11
752
+ debug 18
616
753
  yyerror "dynamic constant assignment"
617
754
  end
618
755
 
619
- result = s(:const, s(:colon3, val[1].to_sym))
756
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
620
757
  }
621
758
  | backref
622
759
  {
@@ -631,38 +768,34 @@ rule
631
768
 
632
769
  cpath: tCOLON3 cname
633
770
  {
634
- result = s(:colon3, val[1].to_sym)
771
+ result = wrap :colon3, val[1]
635
772
  }
636
773
  | cname
637
774
  {
638
- result = val[0].to_sym
775
+ (id, line), = val
776
+ result = [id.to_sym, line] # TODO: sexp?
639
777
  }
640
778
  | primary_value tCOLON2 cname
641
779
  {
642
- result = s(:colon2, val[0], val[2].to_sym)
780
+ pval, _, (name, _line) = val
781
+
782
+ result = s(:colon2, pval, name.to_sym)
783
+ result.line pval.line
643
784
  }
644
785
 
645
786
  fname: tIDENTIFIER | tCONSTANT | tFID
646
787
  | op
647
788
  {
648
789
  lexer.lex_state = EXPR_END
649
- result = val[0]
650
790
  }
651
791
 
652
792
  | reswords
653
- {
654
- (sym, _line), = val
655
- lexer.lex_state = EXPR_END
656
- result = sym
657
- }
658
-
659
- fsym: fname | symbol
660
793
 
661
- fitem: fsym
794
+ fitem: fname
662
795
  {
663
- result = s(:lit, val[0].to_sym)
796
+ result = wrap :lit, val[0]
664
797
  }
665
- | dsym
798
+ | symbol
666
799
 
667
800
  undef_list: fitem
668
801
  {
@@ -683,9 +816,6 @@ rule
683
816
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
684
817
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
685
818
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
686
- #if V >= 20
687
- | tUBANG
688
- #endif
689
819
 
690
820
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
691
821
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -707,8 +837,7 @@ rule
707
837
  }
708
838
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
709
839
  {
710
- val[2].sexp_type = :arglist if val[2]
711
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
840
+ result = new_op_asgn1 val
712
841
  }
713
842
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
714
843
  {
@@ -720,24 +849,22 @@ rule
720
849
  }
721
850
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
722
851
  {
723
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
852
+ lhs, _, (id, _line), (op, _), rhs = val
853
+
854
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
724
855
  }
725
856
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
726
857
  {
727
- lhs1, _, lhs2, op, rhs = val
858
+ lhs1, _, (lhs2, _line), op, rhs = val
728
859
 
729
860
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
730
861
  result = new_const_op_asgn [lhs, op, rhs]
731
862
  }
732
- | tCOLON3 tCONSTANT
733
- {
734
- result = self.lexer.lineno
735
- }
736
- tOP_ASGN arg_rhs
863
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
737
864
  {
738
- _, lhs, line, op, rhs = val
865
+ _, lhs, op, rhs = val
739
866
 
740
- lhs = s(:colon3, lhs.to_sym).line line
867
+ lhs = wrap :colon3, lhs
741
868
  result = new_const_op_asgn [lhs, op, rhs]
742
869
  }
743
870
  | backref tOP_ASGN arg_rhs
@@ -749,35 +876,55 @@ rule
749
876
  | arg tDOT2 arg
750
877
  {
751
878
  v1, v2 = val[0], val[2]
752
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
753
- result = s(:lit, (v1.last)..(v2.last))
879
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
880
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
754
881
  else
755
- result = s(:dot2, v1, v2)
882
+ result = s(:dot2, v1, v2).line v1.line
756
883
  end
757
884
  }
758
885
  | arg tDOT3 arg
759
886
  {
760
887
  v1, v2 = val[0], val[2]
761
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
762
- result = s(:lit, (v1.last)...(v2.last))
888
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
889
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
763
890
  else
764
- result = s(:dot3, v1, v2)
891
+ result = s(:dot3, v1, v2).line v1.line
765
892
  end
766
893
  }
767
894
  #if V >= 26
768
895
  | arg tDOT2
769
896
  {
770
- v1, v2 = val[0], nil
897
+ v1, _ = val
898
+ v2 = nil
771
899
 
772
- result = s(:dot2, v1, v2)
900
+ result = s(:dot2, v1, v2).line v1.line
773
901
  }
774
902
  | arg tDOT3
775
903
  {
776
- v1, v2 = val[0], nil
904
+ v1, _ = val
905
+ v2 = nil
906
+
907
+ result = s(:dot3, v1, v2).line v1.line
908
+ }
909
+ #endif
910
+
911
+ #if V >= 27
912
+ | tBDOT2 arg
913
+ {
914
+ _, v2, = val
915
+ v1 = nil
916
+
917
+ result = s(:dot2, v1, v2).line v2.line
918
+ }
919
+ | tBDOT3 arg
920
+ {
921
+ _, v2 = val
922
+ v1 = nil
777
923
 
778
- result = s(:dot3, v1, v2)
924
+ result = s(:dot3, v1, v2).line v2.line
779
925
  }
780
926
  #endif
927
+
781
928
  | arg tPLUS arg
782
929
  {
783
930
  result = new_call val[0], :+, argl(val[2])
@@ -805,17 +952,22 @@ rule
805
952
  #if V == 20
806
953
  | tUMINUS_NUM tINTEGER tPOW arg
807
954
  {
808
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
955
+ _, (num, line), _, arg = val
956
+ lit = s(:lit, num).line line
957
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
809
958
  }
810
959
  | tUMINUS_NUM tFLOAT tPOW arg
811
960
  #else
812
961
  | tUMINUS_NUM simple_numeric tPOW arg
813
962
  #endif
814
963
  {
815
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
964
+ _, (num, line), _, arg = val
965
+ lit = s(:lit, num).line line
966
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
967
+
816
968
  #if V == 20
817
969
  ## TODO: why is this 2.0 only?
818
- debug20 12, val, result
970
+ debug 19
819
971
  #endif
820
972
  }
821
973
  | tUPLUS arg
@@ -857,15 +1009,19 @@ rule
857
1009
  }
858
1010
  | arg tMATCH arg
859
1011
  {
860
- result = new_match val[0], val[2]
1012
+ lhs, _, rhs = val
1013
+ result = new_match lhs, rhs
861
1014
  }
862
1015
  | arg tNMATCH arg
863
1016
  {
864
- result = s(:not, new_match(val[0], val[2]))
1017
+ lhs, _, rhs = val
1018
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
865
1019
  }
866
1020
  | tBANG arg
867
1021
  {
868
- result = new_call val[1], :"!"
1022
+ _, arg = val
1023
+ result = new_call arg, :"!"
1024
+ result.line arg.line
869
1025
  }
870
1026
  | tTILDE arg
871
1027
  {
@@ -893,11 +1049,13 @@ rule
893
1049
  }
894
1050
  | kDEFINED opt_nl arg
895
1051
  {
896
- result = s(:defined, val[2])
1052
+ (_, line), _, arg = val
1053
+ result = s(:defined, arg).line line
897
1054
  }
898
1055
  | arg tEH arg opt_nl tCOLON arg
899
1056
  {
900
- result = s(:if, val[0], val[2], val[5])
1057
+ c, _, t, _, _, f = val
1058
+ result = s(:if, c, t, f).line c.line
901
1059
  }
902
1060
  | primary
903
1061
 
@@ -908,12 +1066,12 @@ rule
908
1066
 
909
1067
  rel_expr: arg relop arg =tGT
910
1068
  {
911
- lhs, op, rhs = val
1069
+ lhs, (op, _), rhs = val
912
1070
  result = new_call lhs, op.to_sym, argl(rhs)
913
1071
  }
914
1072
  | rel_expr relop arg =tGT
915
1073
  {
916
- lhs, op, rhs = val
1074
+ lhs, (op, _), rhs = val
917
1075
  warn "comparison '%s' after comparison", op
918
1076
  result = new_call lhs, op.to_sym, argl(rhs)
919
1077
  }
@@ -940,28 +1098,47 @@ rule
940
1098
  arg_rhs: arg =tOP_ASGN
941
1099
  | arg kRESCUE_MOD arg
942
1100
  {
943
- body, _, resbody = val
1101
+ body, (_, line), resbody = val
944
1102
  body = value_expr body
945
1103
  resbody = remove_begin resbody
946
- result = new_rescue(body, new_resbody(s(:array), resbody))
1104
+
1105
+ ary = s(:array).line line
1106
+ result = new_rescue(body, new_resbody(ary, resbody))
947
1107
  }
948
1108
 
949
1109
  paren_args: tLPAREN2 opt_call_args rparen
950
1110
  {
951
- result = val[1]
1111
+ _, args, (_, line_max) = val
1112
+
1113
+ result = args
1114
+ result.line_max = line_max if args
1115
+ }
1116
+ #if V >= 27
1117
+ | tLPAREN2 args tCOMMA args_forward rparen
1118
+ {
1119
+ yyerror "Unexpected ..." unless
1120
+ self.lexer.is_local_id(:"*") &&
1121
+ self.lexer.is_local_id(:"**") &&
1122
+ self.lexer.is_local_id(:"&")
1123
+
1124
+ result = call_args val
1125
+ }
1126
+ | tLPAREN2 args_forward rparen
1127
+ {
1128
+ yyerror "Unexpected ..." unless
1129
+ self.lexer.is_local_id(:"*") &&
1130
+ self.lexer.is_local_id(:"**") &&
1131
+ self.lexer.is_local_id(:"&")
1132
+
1133
+ result = call_args val
952
1134
  }
1135
+ #endif
953
1136
 
954
1137
  opt_paren_args: none
955
1138
  | paren_args
956
1139
 
957
1140
  opt_call_args: none
958
- {
959
- result = val[0]
960
- }
961
1141
  | call_args
962
- {
963
- result = val[0]
964
- }
965
1142
  | args tCOMMA
966
1143
  {
967
1144
  result = args val
@@ -983,17 +1160,14 @@ rule
983
1160
  | args opt_block_arg
984
1161
  {
985
1162
  result = call_args val
986
- result = self.arg_blk_pass val[0], val[1]
987
1163
  }
988
1164
  | assocs opt_block_arg
989
1165
  {
990
- result = call_args [array_to_hash(val[0])]
991
- result = self.arg_blk_pass result, val[1]
1166
+ result = call_args [array_to_hash(val[0]), val[1]]
992
1167
  }
993
1168
  | args tCOMMA assocs opt_block_arg
994
1169
  {
995
- result = call_args [val[0], array_to_hash(val[2])]
996
- result = self.arg_blk_pass result, val[3]
1170
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
997
1171
  }
998
1172
  | block_arg
999
1173
  {
@@ -1001,17 +1175,45 @@ rule
1001
1175
  }
1002
1176
 
1003
1177
  command_args: {
1004
- result = lexer.cmdarg.store true
1178
+ # parse26.y line 2200
1179
+
1180
+ # If call_args starts with a open paren '(' or
1181
+ # '[', look-ahead reading of the letters calls
1182
+ # CMDARG_PUSH(0), but the push must be done
1183
+ # after CMDARG_PUSH(1). So this code makes them
1184
+ # consistent by first cancelling the premature
1185
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1186
+ # finally redoing CMDARG_PUSH(0).
1187
+
1188
+ result = yychar = self.last_token_type.first
1189
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1190
+ lexer.cmdarg.pop if lookahead
1191
+ lexer.cmdarg.push true
1192
+ lexer.cmdarg.push false if lookahead
1005
1193
  }
1006
1194
  call_args
1007
1195
  {
1008
- lexer.cmdarg.restore val[0]
1009
- result = val[1]
1196
+ yychar, args = val
1197
+
1198
+ # call_args can be followed by tLBRACE_ARG (that
1199
+ # does CMDARG_PUSH(0) in the lexer) but the push
1200
+ # must be done after CMDARG_POP() in the parser.
1201
+ # So this code does CMDARG_POP() to pop 0 pushed
1202
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1203
+ # by command_args, and CMDARG_PUSH(0) to restore
1204
+ # back the flag set by tLBRACE_ARG.
1205
+
1206
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1207
+ lexer.cmdarg.pop if lookahead
1208
+ lexer.cmdarg.pop
1209
+ lexer.cmdarg.push false if lookahead
1210
+ result = args
1010
1211
  }
1011
1212
 
1012
1213
  block_arg: tAMPER arg_value
1013
1214
  {
1014
- result = s(:block_pass, val[1])
1215
+ _, arg = val
1216
+ result = s(:block_pass, arg).line arg.line
1015
1217
  }
1016
1218
 
1017
1219
  opt_block_arg: tCOMMA block_arg
@@ -1022,19 +1224,27 @@ rule
1022
1224
 
1023
1225
  args: arg_value
1024
1226
  {
1025
- result = s(:array, val[0])
1227
+ arg, = val
1228
+ lineno = arg.line || lexer.lineno # HACK
1229
+
1230
+ result = s(:array, arg).line lineno
1026
1231
  }
1027
1232
  | tSTAR arg_value
1028
1233
  {
1029
- result = s(:array, s(:splat, val[1]))
1234
+ _, arg = val
1235
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1030
1236
  }
1031
1237
  | args tCOMMA arg_value
1032
1238
  {
1033
- result = self.list_append val[0], val[2]
1239
+ args, _, id = val
1240
+ result = self.list_append args, id
1034
1241
  }
1035
1242
  | args tCOMMA tSTAR arg_value
1036
1243
  {
1037
- result = self.list_append val[0], s(:splat, val[3])
1244
+ # TODO: the line number from tSTAR has been dropped
1245
+ args, _, _, id = val
1246
+ line = lexer.lineno
1247
+ result = self.list_append args, s(:splat, id).line(line)
1038
1248
  }
1039
1249
 
1040
1250
  #if V >= 21
@@ -1054,11 +1264,14 @@ rule
1054
1264
  }
1055
1265
  | args tCOMMA tSTAR arg_value
1056
1266
  {
1057
- result = self.arg_concat val[0], val[3]
1267
+ # TODO: make all tXXXX terminals include lexer.lineno
1268
+ arg, _, _, splat = val
1269
+ result = self.arg_concat arg, splat
1058
1270
  }
1059
1271
  | tSTAR arg_value
1060
1272
  {
1061
- result = s(:splat, val[1])
1273
+ _, arg = val
1274
+ result = s(:splat, arg).line arg.line
1062
1275
  }
1063
1276
 
1064
1277
  primary: literal
@@ -1073,65 +1286,65 @@ rule
1073
1286
  | backref
1074
1287
  | tFID
1075
1288
  {
1076
- result = new_call nil, val[0].to_sym
1289
+ (msg, line), = val
1290
+ result = new_call nil, msg.to_sym
1291
+ result.line line
1077
1292
  }
1078
1293
  | k_begin
1079
1294
  {
1080
- result = self.lexer.lineno
1081
- # TODO:
1082
- # $<val>1 = cmdarg_stack;
1083
- # CMDARG_SET(0);
1295
+ lexer.cmdarg.push false
1084
1296
  }
1085
1297
  bodystmt k_end
1086
1298
  {
1087
- # TODO: CMDARG_SET($<val>1);
1088
- unless val[2] then
1089
- result = s(:nil)
1090
- else
1091
- result = s(:begin, val[2])
1092
- end
1093
-
1094
- result.line = val[1]
1299
+ lexer.cmdarg.pop
1300
+ result = new_begin val
1095
1301
  }
1096
- | tLPAREN_ARG rparen
1302
+ | tLPAREN_ARG
1097
1303
  {
1098
- # TODO: lex_state = EXPR_ENDARG in between
1099
- debug20 13, val, result
1304
+ lexer.lex_state = EXPR_ENDARG
1305
+ result = lexer.lineno
1100
1306
  }
1101
- | tLPAREN_ARG
1307
+ rparen
1102
1308
  {
1103
- result = lexer.cmdarg.store false
1104
- # result = self.lexer.cmdarg.stack.dup
1105
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1309
+ _, line, _ = val
1310
+ result = s(:begin).line line
1106
1311
  }
1312
+ | tLPAREN_ARG
1107
1313
  stmt
1108
1314
  {
1109
1315
  lexer.lex_state = EXPR_ENDARG
1110
1316
  }
1111
1317
  rparen
1112
1318
  {
1113
- _, cmdarg, stmt, _, _, = val
1114
- warning "(...) interpreted as grouped expression"
1115
- lexer.cmdarg.restore cmdarg
1319
+ _, stmt, _, _, = val
1320
+ # warning "(...) interpreted as grouped expression"
1116
1321
  result = stmt
1117
1322
  }
1118
1323
  | tLPAREN compstmt tRPAREN
1119
1324
  {
1120
- result = val[1] || s(:nil)
1325
+ _, stmt, _ = val
1326
+ result = stmt
1327
+ result ||= s(:nil).line lexer.lineno
1121
1328
  result.paren = true
1122
1329
  }
1123
1330
  | primary_value tCOLON2 tCONSTANT
1124
1331
  {
1125
- result = s(:colon2, val[0], val[2].to_sym)
1332
+ expr, _, (id, _line) = val
1333
+
1334
+ result = s(:colon2, expr, id.to_sym).line expr.line
1126
1335
  }
1127
1336
  | tCOLON3 tCONSTANT
1128
1337
  {
1129
- result = s(:colon3, val[1].to_sym)
1338
+ result = wrap :colon3, val[1]
1130
1339
  }
1131
- | tLBRACK aref_args tRBRACK
1340
+ | tLBRACK { result = lexer.lineno } aref_args rbracket
1132
1341
  {
1133
- result = val[1] || s(:array)
1342
+ _, line, args, (_, line_max) = val
1343
+
1344
+ result = args || s(:array)
1134
1345
  result.sexp_type = :array # aref_args is :args
1346
+ result.line line
1347
+ result.line_max = line_max
1135
1348
  }
1136
1349
  | tLBRACE
1137
1350
  {
@@ -1143,39 +1356,49 @@ rule
1143
1356
  }
1144
1357
  | k_return
1145
1358
  {
1146
- result = s(:return)
1359
+ (_, line), = val
1360
+ result = s(:return).line line
1147
1361
  }
1148
1362
  | kYIELD tLPAREN2 call_args rparen
1149
1363
  {
1150
- result = new_yield val[2]
1364
+ (_, line), _, args, _ = val
1365
+
1366
+ result = new_yield(args).line line
1151
1367
  }
1152
1368
  | kYIELD tLPAREN2 rparen
1153
1369
  {
1154
- result = new_yield
1370
+ (_, line), _, _ = val
1371
+
1372
+ result = new_yield.line line
1155
1373
  }
1156
1374
  | kYIELD
1157
1375
  {
1158
- result = new_yield
1376
+ (_, line), = val
1377
+
1378
+ result = new_yield.line line
1159
1379
  }
1160
1380
  | kDEFINED opt_nl tLPAREN2 expr rparen
1161
1381
  {
1162
- result = s(:defined, val[3])
1382
+ (_, line), _, _, arg, _ = val
1383
+
1384
+ result = s(:defined, arg).line line
1163
1385
  }
1164
1386
  | kNOT tLPAREN2 expr rparen
1165
1387
  {
1166
- result = s(:call, val[2], :"!")
1388
+ _, _, lhs, _ = val
1389
+ result = new_call lhs, :"!"
1167
1390
  }
1168
1391
  | kNOT tLPAREN2 rparen
1169
1392
  {
1170
- debug20 14, val, result
1393
+ debug 20
1171
1394
  }
1172
1395
  | fcall brace_block
1173
1396
  {
1174
- oper, iter = val[0], val[1]
1175
- call = oper # FIX
1397
+ call, iter = val
1398
+
1176
1399
  iter.insert 1, call
1177
1400
  result = iter
1178
- call.line = iter.line
1401
+ # FIX: probably not: call.line = iter.line
1179
1402
  }
1180
1403
  | method_call
1181
1404
  | method_call brace_block
@@ -1185,9 +1408,10 @@ rule
1185
1408
  iter.insert 1, call # FIX
1186
1409
  result = iter
1187
1410
  }
1188
- | tLAMBDA lambda
1411
+ | lambda
1189
1412
  {
1190
- result = val[1] # TODO: fix lineno
1413
+ expr, = val
1414
+ result = expr
1191
1415
  }
1192
1416
  | k_if expr_value then compstmt if_tail k_end
1193
1417
  {
@@ -1219,18 +1443,22 @@ rule
1219
1443
  (_, line), _, body, _ = val
1220
1444
  result = new_case nil, body, line
1221
1445
  }
1446
+ #if V >= 27
1447
+ | k_case expr_value opt_terms p_case_body k_end
1448
+ {
1449
+ (_, line), expr, _, body, _ = val
1450
+
1451
+ result = new_case expr, body, line
1452
+ }
1453
+ #endif
1222
1454
  | k_for for_var kIN expr_value_do compstmt k_end
1223
1455
  {
1224
1456
  _, var, _, iter, body, _ = val
1225
1457
  result = new_for iter, var, body
1226
1458
  }
1227
1459
  | k_class
1228
- {
1229
- result = self.lexer.lineno
1230
- }
1231
1460
  cpath superclass
1232
1461
  {
1233
- self.comments.push self.lexer.comments
1234
1462
  if (self.in_def || self.in_single > 0) then
1235
1463
  yyerror "class definition in method body"
1236
1464
  end
@@ -1240,12 +1468,8 @@ rule
1240
1468
  {
1241
1469
  result = new_class val
1242
1470
  self.env.unextend
1243
- self.lexer.comments # we don't care about comments in the body
1244
1471
  }
1245
1472
  | k_class tLSHFT
1246
- {
1247
- result = self.lexer.lineno
1248
- }
1249
1473
  expr
1250
1474
  {
1251
1475
  result = self.in_def
@@ -1261,15 +1485,10 @@ rule
1261
1485
  {
1262
1486
  result = new_sclass val
1263
1487
  self.env.unextend
1264
- self.lexer.comments # we don't care about comments in the body
1265
1488
  }
1266
1489
  | k_module
1267
- {
1268
- result = self.lexer.lineno
1269
- }
1270
1490
  cpath
1271
1491
  {
1272
- self.comments.push self.lexer.comments
1273
1492
  yyerror "module definition in method body" if
1274
1493
  self.in_def or self.in_single > 0
1275
1494
 
@@ -1279,70 +1498,82 @@ rule
1279
1498
  {
1280
1499
  result = new_module val
1281
1500
  self.env.unextend
1282
- self.lexer.comments # we don't care about comments in the body
1283
1501
  }
1284
1502
  | k_def fname
1285
1503
  {
1286
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1504
+ result = self.in_def
1287
1505
 
1288
- self.comments.push self.lexer.comments
1289
- self.in_def = true
1506
+ self.in_def = true # group = local_push
1290
1507
  self.env.extend
1291
- # TODO: local->cmdargs = cmdarg_stack;
1292
- # TODO: port local_push_gen and local_pop_gen
1293
- lexer.cmdarg.stack.replace [false]
1508
+ lexer.cmdarg.push false
1509
+ lexer.cond.push false
1294
1510
  }
1295
1511
  f_arglist bodystmt k_end
1296
1512
  {
1297
- in_def, cmdarg = val[2]
1298
-
1299
- result = new_defn val
1513
+ result, in_def = new_defn val
1300
1514
 
1301
- lexer.cmdarg.stack.replace cmdarg
1515
+ lexer.cond.pop # group = local_pop
1516
+ lexer.cmdarg.pop
1302
1517
  self.env.unextend
1303
1518
  self.in_def = in_def
1304
- self.lexer.comments # we don't care about comments in the body
1305
1519
  }
1306
1520
  | k_def singleton dot_or_colon
1307
1521
  {
1308
- self.comments.push self.lexer.comments
1309
1522
  lexer.lex_state = EXPR_FNAME
1310
1523
  }
1311
1524
  fname
1312
1525
  {
1313
- self.in_single += 1
1526
+ result = self.in_def
1527
+
1528
+ self.in_single += 1 # TODO: remove?
1529
+
1530
+ self.in_def = true # local_push
1314
1531
  self.env.extend
1315
- lexer.lex_state = EXPR_ENDFN # force for args
1316
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1317
- lexer.cmdarg.stack.replace [false]
1532
+ lexer.cmdarg.push false
1533
+ lexer.cond.push false
1534
+
1535
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1318
1536
  }
1319
1537
  f_arglist bodystmt k_end
1320
1538
  {
1321
- line, cmdarg = val[5]
1322
- result = new_defs val
1323
- result[3].line line
1324
1539
 
1325
- lexer.cmdarg.stack.replace cmdarg
1540
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1541
+ # =>
1542
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1543
+
1544
+ val.delete_at 3
1545
+ val.delete_at 2
1546
+
1547
+ result, in_def = new_defs val
1326
1548
 
1549
+ lexer.cond.pop # group = local_pop
1550
+ lexer.cmdarg.pop
1327
1551
  self.env.unextend
1552
+ self.in_def = in_def
1553
+
1328
1554
  self.in_single -= 1
1329
- self.lexer.comments # we don't care about comments in the body
1555
+
1556
+ # TODO: restore cur_arg ? what's cur_arg?
1330
1557
  }
1331
1558
  | kBREAK
1332
1559
  {
1333
- result = s(:break)
1560
+ (_, line), = val
1561
+ result = s(:break).line line
1334
1562
  }
1335
1563
  | kNEXT
1336
1564
  {
1337
- result = s(:next)
1565
+ (_, line), = val
1566
+ result = s(:next).line line
1338
1567
  }
1339
1568
  | kREDO
1340
1569
  {
1341
- result = s(:redo)
1570
+ (_, line), = val
1571
+ result = s(:redo).line line
1342
1572
  }
1343
1573
  | kRETRY
1344
1574
  {
1345
- result = s(:retry)
1575
+ (_, line), = val
1576
+ result = s(:retry).line line
1346
1577
  }
1347
1578
 
1348
1579
  primary_value: primary
@@ -1359,8 +1590,17 @@ rule
1359
1590
  k_case: kCASE
1360
1591
  k_for: kFOR
1361
1592
  k_class: kCLASS
1593
+ {
1594
+ result << self.lexer.comment
1595
+ }
1362
1596
  k_module: kMODULE
1597
+ {
1598
+ result << self.lexer.comment
1599
+ }
1363
1600
  k_def: kDEF
1601
+ {
1602
+ result << self.lexer.comment
1603
+ }
1364
1604
  k_do: kDO
1365
1605
  k_do_block: kDO_BLOCK
1366
1606
  k_rescue: kRESCUE
@@ -1381,7 +1621,9 @@ rule
1381
1621
  if_tail: opt_else
1382
1622
  | k_elsif expr_value then compstmt if_tail
1383
1623
  {
1384
- result = s(:if, val[1], val[3], val[4])
1624
+ (_, line), c, _, t, rest = val
1625
+
1626
+ result = s(:if, c, t, rest).line line
1385
1627
  }
1386
1628
 
1387
1629
  opt_else: none
@@ -1404,7 +1646,9 @@ rule
1404
1646
 
1405
1647
  f_marg_list: f_marg
1406
1648
  {
1407
- result = s(:array, val[0])
1649
+ sym, = val
1650
+
1651
+ result = s(:array, sym).line lexer.lineno
1408
1652
  }
1409
1653
  | f_marg_list tCOMMA f_marg
1410
1654
  {
@@ -1417,51 +1661,42 @@ rule
1417
1661
 
1418
1662
  result = block_var args
1419
1663
  }
1420
- | f_marg_list tCOMMA tSTAR f_norm_arg
1664
+ | f_marg_list tCOMMA f_rest_marg
1421
1665
  {
1422
- args, _, _, splat = val
1666
+ args, _, rest = val
1423
1667
 
1424
- result = block_var args, "*#{splat}".to_sym
1668
+ result = block_var args, rest
1425
1669
  }
1426
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1670
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1427
1671
  {
1428
- args, _, _, splat, _, args2 = val
1672
+ lhs, _, splat, _, rhs = val
1429
1673
 
1430
- result = block_var args, "*#{splat}".to_sym, args2
1674
+ result = block_var lhs, splat, rhs
1431
1675
  }
1432
- | f_marg_list tCOMMA tSTAR
1676
+ | f_rest_marg
1433
1677
  {
1434
- args, _, _ = val
1678
+ rest, = val
1435
1679
 
1436
- result = block_var args, :*
1680
+ result = block_var rest
1437
1681
  }
1438
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1682
+ | f_rest_marg tCOMMA f_marg_list
1439
1683
  {
1440
- args, _, _, _, args2 = val
1684
+ splat, _, rest = val
1441
1685
 
1442
- result = block_var args, :*, args2
1686
+ result = block_var splat, rest
1443
1687
  }
1444
- | tSTAR f_norm_arg
1445
- {
1446
- _, splat = val
1447
1688
 
1448
- result = block_var :"*#{splat}"
1449
- }
1450
- | tSTAR f_norm_arg tCOMMA f_marg_list
1689
+ f_rest_marg: tSTAR f_norm_arg
1451
1690
  {
1452
- _, splat, _, args = val
1691
+ _, (id, line) = val
1453
1692
 
1454
- result = block_var :"*#{splat}", args
1693
+ result = args ["*#{id}".to_sym]
1694
+ result.line line
1455
1695
  }
1456
1696
  | tSTAR
1457
1697
  {
1458
- result = block_var :*
1459
- }
1460
- | tSTAR tCOMMA f_marg_list
1461
- {
1462
- _, _, args = val
1463
-
1464
- result = block_var :*, args
1698
+ result = args [:*]
1699
+ result.line lexer.lineno # FIX: tSTAR -> line
1465
1700
  }
1466
1701
 
1467
1702
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1476,9 +1711,17 @@ rule
1476
1711
  {
1477
1712
  result = call_args val
1478
1713
  }
1714
+ #if V >= 27
1715
+ | f_no_kwarg opt_f_block_arg
1716
+ {
1717
+ result = args val
1718
+ }
1719
+ #endif
1479
1720
  | f_block_arg
1480
1721
  {
1481
- result = call_args val
1722
+ (id, line), = val
1723
+ result = call_args [id]
1724
+ result.line line
1482
1725
  }
1483
1726
 
1484
1727
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1509,7 +1752,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1509
1752
  }
1510
1753
  | f_arg tCOMMA
1511
1754
  {
1512
- result = args val
1755
+ result = args(val) << nil
1513
1756
  }
1514
1757
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1515
1758
  {
@@ -1561,7 +1804,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1561
1804
  }
1562
1805
  | tOROP
1563
1806
  {
1564
- result = s(:args)
1807
+ result = s(:args).line lexer.lineno
1565
1808
  }
1566
1809
  | tPIPE block_param opt_bv_decl tPIPE
1567
1810
  {
@@ -1586,34 +1829,32 @@ opt_block_args_tail: tCOMMA block_args_tail
1586
1829
 
1587
1830
  bvar: tIDENTIFIER
1588
1831
  {
1589
- result = s(:shadow, val[0].to_sym)
1832
+ result = wrap :shadow, val[0]
1590
1833
  }
1591
1834
  | f_bad_arg
1592
1835
 
1593
- lambda: {
1836
+ lambda: tLAMBDA
1837
+ {
1594
1838
  self.env.extend :dynamic
1595
- result = self.lexer.lineno
1596
-
1597
- result = lexer.lpar_beg
1839
+ result = [lexer.lineno, lexer.lpar_beg]
1598
1840
  lexer.paren_nest += 1
1599
1841
  lexer.lpar_beg = lexer.paren_nest
1600
1842
  }
1601
1843
  f_larglist
1602
1844
  {
1603
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1845
+ lexer.cmdarg.push false
1604
1846
  }
1605
1847
  lambda_body
1606
1848
  {
1607
- lpar, args, (cmdarg, lineno), body = val
1849
+ _, (line, lpar), args, _cmdarg, body = val
1608
1850
  lexer.lpar_beg = lpar
1609
1851
 
1610
- lexer.cmdarg.restore cmdarg
1611
- lexer.cmdarg.lexpop
1852
+ lexer.cmdarg.pop
1612
1853
 
1613
- call = new_call nil, :lambda
1854
+ call = s(:lambda).line line
1614
1855
  result = new_iter call, args, body
1615
- result.line = lineno
1616
- self.env.unextend
1856
+ result.line line
1857
+ self.env.unextend # TODO: dynapush & dynapop
1617
1858
  }
1618
1859
 
1619
1860
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1637,8 +1878,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1637
1878
 
1638
1879
  do_block: k_do_block do_body kEND
1639
1880
  {
1640
- # TODO: maybe fix lineno to kDO's lineno?
1641
- result = val[1]
1881
+ (_, line), iter, _ = val
1882
+ result = iter.line line
1642
1883
  }
1643
1884
 
1644
1885
  block_call: command do_block
@@ -1647,21 +1888,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1647
1888
  ## if (nd_type($1) == NODE_YIELD) {
1648
1889
  ## compile_error(PARSER_ARG "block given to yield");
1649
1890
 
1891
+ cmd, blk = val
1892
+
1650
1893
  syntax_error "Both block arg and actual block given." if
1651
- val[0].block_pass?
1894
+ cmd.block_pass?
1652
1895
 
1653
- val = invert_block_call val if inverted? val
1896
+ if inverted? val then
1897
+ val = invert_block_call val
1898
+ cmd, blk = val
1899
+ end
1654
1900
 
1655
- result = val[1]
1656
- result.insert 1, val[0]
1901
+ result = blk
1902
+ result.insert 1, cmd
1657
1903
  }
1658
1904
  | block_call call_op2 operation2 opt_paren_args
1659
1905
  {
1660
- result = new_call val[0], val[2].to_sym, val[3]
1906
+ lhs, _, (id, _line), args = val
1907
+
1908
+ result = new_call lhs, id.to_sym, args
1661
1909
  }
1662
1910
  | block_call call_op2 operation2 opt_paren_args brace_block
1663
1911
  {
1664
- iter1, _, name, args, iter2 = val
1912
+ iter1, _, (name, _line), args, iter2 = val
1665
1913
 
1666
1914
  call = new_call iter1, name.to_sym, args
1667
1915
  iter2.insert 1, call
@@ -1670,7 +1918,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1670
1918
  }
1671
1919
  | block_call call_op2 operation2 command_args do_block
1672
1920
  {
1673
- iter1, _, name, args, iter2 = val
1921
+ iter1, _, (name, _line), args, iter2 = val
1674
1922
 
1675
1923
  call = new_call iter1, name.to_sym, args
1676
1924
  iter2.insert 1, call
@@ -1678,26 +1926,35 @@ opt_block_args_tail: tCOMMA block_args_tail
1678
1926
  result = iter2
1679
1927
  }
1680
1928
 
1681
- method_call: fcall
1929
+ method_call: fcall paren_args
1682
1930
  {
1683
- result = self.lexer.lineno
1684
- }
1685
- paren_args
1686
- {
1687
- args = self.call_args val[2..-1]
1688
- result = val[0].concat args.sexp_body
1931
+ call, args = val
1932
+
1933
+ result = call
1934
+
1935
+ if args then
1936
+ call.concat args.sexp_body
1937
+ result.line_max = args.line_max
1938
+ end
1689
1939
  }
1690
1940
  | primary_value call_op operation2 opt_paren_args
1691
1941
  {
1692
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1942
+ recv, call_op, (op, op_line), args = val
1943
+
1944
+ result = new_call recv, op.to_sym, args, call_op
1945
+ result.line_max = op_line unless args
1693
1946
  }
1694
1947
  | primary_value tCOLON2 operation2 paren_args
1695
1948
  {
1696
- result = new_call val[0], val[2].to_sym, val[3]
1949
+ recv, _, (op, _line), args = val
1950
+
1951
+ result = new_call recv, op.to_sym, args
1697
1952
  }
1698
1953
  | primary_value tCOLON2 operation3
1699
1954
  {
1700
- result = new_call val[0], val[2].to_sym
1955
+ lhs, _, (id, _line) = val
1956
+
1957
+ result = new_call lhs, id.to_sym
1701
1958
  }
1702
1959
  | primary_value call_op paren_args
1703
1960
  {
@@ -1713,7 +1970,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1713
1970
  }
1714
1971
  | kSUPER
1715
1972
  {
1716
- result = s(:zsuper)
1973
+ result = s(:zsuper).line lexer.lineno
1717
1974
  }
1718
1975
  | primary_value tLBRACK2 opt_call_args rbracket
1719
1976
  {
@@ -1730,7 +1987,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1730
1987
  _, line, body, _ = val
1731
1988
 
1732
1989
  result = body
1733
- result.line = line
1990
+ result.line line
1734
1991
 
1735
1992
  self.env.unextend
1736
1993
  }
@@ -1744,7 +2001,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1744
2001
  _, line, body, _ = val
1745
2002
 
1746
2003
  result = body
1747
- result.line = line
2004
+ result.line line
1748
2005
 
1749
2006
  self.env.unextend
1750
2007
  }
@@ -1762,7 +2019,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1762
2019
  }
1763
2020
 
1764
2021
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1765
- { result = lexer.cmdarg.store(false) }
2022
+ { lexer.cmdarg.push false }
1766
2023
  opt_block_param
1767
2024
  #if V >= 25
1768
2025
  bodystmt
@@ -1770,32 +2027,565 @@ opt_block_args_tail: tCOMMA block_args_tail
1770
2027
  compstmt
1771
2028
  #endif
1772
2029
  {
1773
- line, cmdarg, param, cmpstmt = val
2030
+ line, _cmdarg, param, cmpstmt = val
1774
2031
 
1775
2032
  result = new_do_body param, cmpstmt, line
2033
+ lexer.cmdarg.pop
1776
2034
  self.env.unextend
1777
- lexer.cmdarg.restore cmdarg
2035
+ }
2036
+
2037
+ case_args: arg_value
2038
+ {
2039
+ arg, = val
2040
+
2041
+ result = s(:array, arg).line arg.line
2042
+ }
2043
+ | tSTAR arg_value
2044
+ {
2045
+ _, arg = val
2046
+
2047
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2048
+ }
2049
+ | case_args tCOMMA arg_value
2050
+ {
2051
+ args, _, id = val
2052
+
2053
+ result = self.list_append args, id
2054
+ }
2055
+ | case_args tCOMMA tSTAR arg_value
2056
+ {
2057
+ args, _, _, id = val
2058
+
2059
+ result = self.list_append args, s(:splat, id).line(id.line)
1778
2060
  }
1779
2061
 
1780
2062
  case_body: k_when
1781
2063
  {
1782
2064
  result = self.lexer.lineno
1783
2065
  }
1784
- args then compstmt cases
2066
+ case_args then compstmt cases
1785
2067
  {
1786
2068
  result = new_when(val[2], val[4])
1787
- result.line = val[1]
2069
+ result.line val[1]
1788
2070
  result << val[5] if val[5]
1789
2071
  }
1790
2072
 
1791
2073
  cases: opt_else | case_body
2074
+ #if V >= 27
2075
+ ######################################################################
2076
+
2077
+ p_case_body: kIN
2078
+ {
2079
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2080
+ self.lexer.command_start = false
2081
+ result = self.in_kwarg
2082
+ self.in_kwarg = true
2083
+ push_pvtbl
2084
+ push_pktbl
2085
+ }
2086
+ p_top_expr then
2087
+ {
2088
+ pop_pktbl
2089
+ pop_pvtbl
2090
+ old_kwargs = _values[-3]
2091
+ self.in_kwarg = old_kwargs
2092
+ }
2093
+ compstmt
2094
+ p_cases
2095
+ {
2096
+ (_, line), _, pat, _, _, body, cases = val
2097
+
2098
+ result = new_in pat, body, cases, line
2099
+ }
2100
+
2101
+ p_cases: opt_else
2102
+ | p_case_body
2103
+
2104
+ p_top_expr: p_top_expr_body
2105
+ | p_top_expr_body kIF_MOD expr_value
2106
+ {
2107
+ body, _, cond = val
2108
+ body = remove_begin body
2109
+
2110
+ result = s(:if, cond, body, nil).line body.line
2111
+ }
2112
+ | p_top_expr_body kUNLESS_MOD expr_value
2113
+ {
2114
+ body, _, cond = val
2115
+ body = remove_begin body
2116
+
2117
+ result = s(:if, cond, nil, body).line body.line
2118
+ }
2119
+
2120
+ p_top_expr_body: p_expr
2121
+ | p_expr tCOMMA
2122
+ {
2123
+ expr, _ = val
2124
+
2125
+ tail = new_array_pattern_tail nil, true, nil, nil
2126
+ result = new_array_pattern nil, expr, tail, expr.line
2127
+ }
2128
+ | p_expr tCOMMA p_args
2129
+ {
2130
+ expr, _, args = val
2131
+
2132
+ result = new_array_pattern nil, expr, args, expr.line
2133
+ }
2134
+ | p_args_tail
2135
+ {
2136
+ args, = val
2137
+ result = new_array_pattern nil, nil, args, args.line
2138
+ }
2139
+ | p_kwargs
2140
+ {
2141
+ kwargs, = val
2142
+ result = new_hash_pattern nil, kwargs, kwargs.line
2143
+ }
2144
+
2145
+ p_expr: p_as
2146
+
2147
+ p_as: p_expr tASSOC p_variable
2148
+ {
2149
+ # NODE *n = NEW_LIST($1, &@$);
2150
+ # n = list_append(p, n, $3);
2151
+ # $$ = new_hash(p, n, &@$);
2152
+
2153
+ expr, _, var = val
2154
+
2155
+ id = var.last
2156
+
2157
+ self.env[id] = :lvar # HACK: need to extend env
2158
+ lhs = s(:lasgn, id).line var.line
2159
+
2160
+ result = new_assign lhs, expr
2161
+ }
2162
+ | p_alt
2163
+
2164
+ p_alt: p_alt tPIPE p_expr_basic
2165
+ {
2166
+ lhs, _, rhs = val
2167
+
2168
+ result = s(:or, lhs, rhs).line lhs.line
2169
+ }
2170
+ | p_expr_basic
2171
+
2172
+ p_lparen: tLPAREN2 { push_pktbl }
2173
+ p_lbracket: tLBRACK2 { push_pktbl }
2174
+
2175
+ p_expr_basic: p_value
2176
+ | p_const p_lparen p_args tRPAREN
2177
+ {
2178
+ lhs, _, args, _ = val
2179
+
2180
+ pop_pktbl
2181
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2182
+ }
2183
+ | p_const p_lparen p_kwargs tRPAREN
2184
+ {
2185
+ lhs, _, kwargs, _ = val
2186
+
2187
+ pop_pktbl
2188
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2189
+ }
2190
+ | p_const tLPAREN2 tRPAREN
2191
+ {
2192
+ const, _, _ = val
2193
+
2194
+ tail = new_array_pattern_tail nil, nil, nil, nil
2195
+ result = new_array_pattern const, nil, tail, const.line
2196
+ }
2197
+ | p_const p_lbracket p_args rbracket
2198
+ {
2199
+ const, _, pre_arg, _ = val
2200
+
2201
+ pop_pktbl
2202
+ result = new_array_pattern const, nil, pre_arg, const.line
2203
+ }
2204
+ | p_const p_lbracket p_kwargs rbracket
2205
+ {
2206
+ const, _, kwargs, _ = val
2207
+
2208
+ result = new_hash_pattern const, kwargs, const.line
2209
+ }
2210
+ | p_const tLBRACK2 rbracket
2211
+ {
2212
+ const, _, _ = val
2213
+
2214
+ tail = new_array_pattern_tail nil, nil, nil, nil
2215
+ result = new_array_pattern const, nil, tail, const.line
2216
+ }
2217
+ | tLBRACK { push_pktbl } p_args rbracket
2218
+ {
2219
+ _, _, pat, _ = val
2220
+
2221
+ pop_pktbl
2222
+ result = new_array_pattern nil, nil, pat, pat.line
2223
+ }
2224
+ | tLBRACK rbracket
2225
+ {
2226
+ (_, line), _ = val
2227
+
2228
+ result = s(:array_pat).line line
2229
+ }
2230
+ | tLBRACE
2231
+ {
2232
+ push_pktbl
2233
+ result = self.in_kwarg
2234
+ self.in_kwarg = false
2235
+ }
2236
+ p_kwargs rbrace
2237
+ {
2238
+ _, in_kwarg, kwargs, _ = val
2239
+
2240
+ pop_pktbl
2241
+ self.in_kwarg = in_kwarg
2242
+
2243
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2244
+ }
2245
+ | tLBRACE rbrace
2246
+ {
2247
+ (_, line), _ = val
2248
+
2249
+ tail = new_hash_pattern_tail nil, nil, line
2250
+ result = new_hash_pattern nil, tail, line
2251
+ }
2252
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2253
+ {
2254
+ _, _, expr, _ = val
2255
+
2256
+ pop_pktbl
2257
+ result = expr
2258
+ }
2259
+
2260
+ p_args: p_expr
2261
+ {
2262
+ expr, = val
2263
+
2264
+ ary = s(:array_TAIL, expr).line expr.line
2265
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2266
+ }
2267
+ | p_args_head
2268
+ {
2269
+ head, = val
2270
+
2271
+ result = new_array_pattern_tail head, true, nil, nil
2272
+ }
2273
+ | p_args_head p_arg
2274
+ {
2275
+ head, tail = val
2276
+
2277
+ both = array_pat_concat head, tail
2278
+
2279
+ result = new_array_pattern_tail both, nil, nil, nil
2280
+ result.line head.line
2281
+ }
2282
+ | p_args_head tSTAR tIDENTIFIER
2283
+ {
2284
+ head, _, (id, _line) = val
2285
+
2286
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2287
+ result.line head.line
2288
+ }
2289
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2290
+ {
2291
+ head, _, (id, _line), _, post = val
2292
+
2293
+ result = new_array_pattern_tail head, true, id.to_sym, post
2294
+ result.line head.line
2295
+ }
2296
+ | p_args_head tSTAR
2297
+ {
2298
+ expr, _ = val
2299
+
2300
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2301
+ }
2302
+ | p_args_head tSTAR tCOMMA p_args_post
2303
+ {
2304
+ head, _, _, post = val
2305
+
2306
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2307
+ }
2308
+ | p_args_tail
2309
+
2310
+ p_args_head: p_arg tCOMMA
2311
+ {
2312
+ arg, _ = val
2313
+ result = arg
2314
+ }
2315
+ | p_args_head p_arg tCOMMA
2316
+ {
2317
+ head, tail, _ = val
2318
+
2319
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2320
+ result.line head.line
2321
+ }
2322
+
2323
+ p_args_tail: tSTAR tIDENTIFIER
2324
+ {
2325
+ _, (id, line) = val
2326
+
2327
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2328
+ result.line line
2329
+ }
2330
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2331
+ {
2332
+ _, (id, line), _, rhs = val
2333
+
2334
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2335
+ result.line line
2336
+ }
2337
+ | tSTAR
2338
+ {
2339
+ (_, line), = val
2340
+
2341
+ result = new_array_pattern_tail nil, true, nil, nil
2342
+ result.line line
2343
+ }
2344
+ | tSTAR tCOMMA p_args_post
2345
+ {
2346
+ (_, line), _, args = val
2347
+
2348
+ result = new_array_pattern_tail nil, true, nil, args
2349
+ result.line line
2350
+ }
2351
+
2352
+ p_args_post: p_arg
2353
+ | p_args_post tCOMMA p_arg
2354
+ {
2355
+ lhs, _, rhs = val
2356
+
2357
+ result = array_pat_concat lhs, rhs
2358
+ }
2359
+
2360
+ p_arg: p_expr
2361
+ {
2362
+ expr, = val
2363
+ expr = s(:array_TAIL, expr).line expr.line unless
2364
+ expr.sexp_type == :array_TAIL
2365
+ result = expr
2366
+ }
2367
+
2368
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2369
+ {
2370
+ kw_arg, _, rest = val
2371
+ # TODO? new_unique_key_hash(p, $1, &@$)
2372
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2373
+ }
2374
+ | p_kwarg
2375
+ {
2376
+ kwarg, = val
2377
+ # TODO? new_unique_key_hash(p, $1, &@$)
2378
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2379
+ }
2380
+ | p_kwarg tCOMMA
2381
+ {
2382
+ kwarg, _ = val
2383
+ # TODO? new_unique_key_hash(p, $1, &@$)
2384
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2385
+ }
2386
+ | p_kwrest
2387
+ {
2388
+ rest, = val
2389
+
2390
+ result = new_hash_pattern_tail nil, rest, rest.line
2391
+ }
2392
+ | p_kwarg tCOMMA p_kwnorest
2393
+ {
2394
+ kwarg, _, norest = val
2395
+
2396
+ # TODO? new_unique_key_hash(p, $1, &@$)
2397
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2398
+ }
2399
+ | p_kwnorest
2400
+ {
2401
+ norest, = val
2402
+
2403
+ result = new_hash_pattern_tail nil, norest, norest.line
2404
+ }
2405
+
2406
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2407
+ | p_kwarg tCOMMA p_kw
2408
+ {
2409
+ kwarg, _, kw = val
2410
+ kwarg.concat kw.sexp_body
2411
+ result = kwarg
2412
+ }
2413
+
2414
+ p_kw: p_kw_label p_expr
2415
+ {
2416
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2417
+ lhs, rhs = val
2418
+
2419
+ result = s(:PAIR, lhs, rhs).line lhs.line
2420
+ }
2421
+ | p_kw_label
2422
+ {
2423
+ lhs, = val
2424
+
2425
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2426
+
2427
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2428
+ # yyerror1(&@1, "key must be valid as local variables");
2429
+ # }
2430
+
2431
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2432
+ # assignable(p, $1, 0, &@$));
2433
+
2434
+
2435
+ case lhs.sexp_type
2436
+ when :lit then
2437
+ assignable [lhs.value, lhs.line]
2438
+ else
2439
+ # TODO or done?
2440
+ debug 666
2441
+ end
2442
+
2443
+ # TODO PAIR -> LIST ?
2444
+ result = s(:PAIR, lhs, nil).line lhs.line
2445
+ }
2446
+
2447
+ p_kw_label: tLABEL
2448
+ {
2449
+ result = wrap :lit, val[0]
2450
+ }
2451
+
2452
+ p_kwrest: kwrest_mark tIDENTIFIER
2453
+ {
2454
+ _, (id, line) = val
2455
+
2456
+ name = id.to_sym
2457
+ self.assignable [name, line]
2458
+ result = s(:kwrest, :"**#{name}").line line
2459
+ }
2460
+ | kwrest_mark
2461
+ {
2462
+ (_, line), = val
2463
+
2464
+ result = s(:kwrest, :"**").line line
2465
+ }
2466
+
2467
+ p_kwnorest: kwrest_mark kNIL
2468
+ {
2469
+ (_, line), _ = val
2470
+
2471
+ # TODO: or s(:norest)? s(:**nil)?
2472
+ result = s(:kwrest, :"**nil").line line
2473
+ }
2474
+
2475
+ p_value: p_primitive
2476
+ | p_primitive tDOT2 p_primitive
2477
+ {
2478
+ lhs, _, rhs = val
2479
+
2480
+ lhs = value_expr lhs
2481
+ rhs = value_expr rhs
2482
+
2483
+ result = s(:dot2, lhs, rhs).line lhs.line
2484
+ }
2485
+ | p_primitive tDOT3 p_primitive
2486
+ {
2487
+ lhs, _, rhs = val
2488
+
2489
+ lhs = value_expr lhs
2490
+ rhs = value_expr rhs
2491
+
2492
+ result = s(:dot3, lhs, rhs).line lhs.line
2493
+ }
2494
+ | p_primitive tDOT2
2495
+ {
2496
+ v1, _ = val
2497
+
2498
+ result = s(:dot2, v1, nil).line v1.line
2499
+ }
2500
+ | p_primitive tDOT3
2501
+ {
2502
+ v1, _ = val
2503
+
2504
+ result = s(:dot3, v1, nil).line v1.line
2505
+ }
2506
+ | p_variable
2507
+ | p_var_ref
2508
+ | p_const
2509
+ | tBDOT2 p_primitive
2510
+ {
2511
+ _, v1 = val
2512
+
2513
+ result = s(:dot2, nil, v1).line v1.line
2514
+ }
2515
+ | tBDOT3 p_primitive
2516
+ {
2517
+ _, v1 = val
2518
+
2519
+ result = s(:dot3, nil, v1).line v1.line
2520
+ }
2521
+
2522
+ p_primitive: literal
2523
+ | strings
2524
+ | xstring
2525
+ | regexp
2526
+ | words
2527
+ {
2528
+ result = ary_to_pat val[0]
2529
+ }
2530
+ | qwords
2531
+ {
2532
+ result = ary_to_pat val[0]
2533
+ }
2534
+ | symbols
2535
+ {
2536
+ result = ary_to_pat val[0]
2537
+ }
2538
+ | qsymbols
2539
+ {
2540
+ result = ary_to_pat val[0]
2541
+ }
2542
+ | keyword_variable
2543
+ {
2544
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2545
+ var, = val
2546
+
2547
+ result = var
2548
+ }
2549
+ | lambda
2550
+
2551
+ p_variable: tIDENTIFIER
2552
+ {
2553
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2554
+ # TODO: assignable(p, $1, 0, &@$);
2555
+ result = wrap :lasgn, val[0]
2556
+ }
2557
+
2558
+ p_var_ref: tCARET tIDENTIFIER
2559
+ {
2560
+ # TODO: check id against env for lvar or dvar
2561
+ result = wrap :lvar, val[1]
2562
+ }
2563
+
2564
+ p_const: tCOLON3 cname
2565
+ {
2566
+ result = wrap :colon3, val[1]
2567
+ }
2568
+ | p_const tCOLON2 cname
2569
+ {
2570
+ lhs, _, (id, _line) = val
2571
+
2572
+ l = lhs.line
2573
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2574
+ }
2575
+ | tCONSTANT
2576
+ {
2577
+ # TODO $$ = gettable(p, $1, &@$);
2578
+ result = wrap :const, val[0]
2579
+ }
2580
+ ######################################################################
2581
+ #endif
1792
2582
 
1793
2583
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1794
2584
  {
1795
2585
  (_, line), klasses, var, _, body, rest = val
1796
2586
 
1797
2587
  klasses ||= s(:array)
1798
- klasses << new_assign(var, s(:gvar, :"$!")) if var
2588
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1799
2589
  klasses.line line
1800
2590
 
1801
2591
  result = new_resbody(klasses, body)
@@ -1808,7 +2598,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1808
2598
 
1809
2599
  exc_list: arg_value
1810
2600
  {
1811
- result = s(:array, val[0])
2601
+ arg, = val
2602
+ result = s(:array, arg).line arg.line
1812
2603
  }
1813
2604
  | mrhs
1814
2605
  | none
@@ -1821,31 +2612,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1821
2612
 
1822
2613
  opt_ensure: k_ensure compstmt
1823
2614
  {
1824
- _, body = val
2615
+ (_, line), body = val
1825
2616
 
1826
- result = body || s(:nil)
2617
+ result = body || s(:nil).line(line)
1827
2618
  }
1828
2619
  | none
1829
2620
 
1830
2621
  literal: numeric
1831
2622
  {
1832
- result = s(:lit, val[0])
2623
+ (lit, line), = val
2624
+ result = s(:lit, lit).line line
1833
2625
  }
1834
2626
  | symbol
1835
- {
1836
- result = s(:lit, val[0])
1837
- }
1838
- | dsym
1839
2627
 
1840
2628
  strings: string
1841
2629
  {
1842
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1843
- result = val[0]
2630
+ str, = val
2631
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2632
+ result = str
1844
2633
  }
1845
2634
 
1846
2635
  string: tCHAR
1847
2636
  {
1848
- debug20 23, val, result
2637
+ debug 37
1849
2638
  }
1850
2639
  | string1
1851
2640
  | string string1
@@ -1855,7 +2644,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
2644
 
1856
2645
  string1: tSTRING_BEG string_contents tSTRING_END
1857
2646
  {
1858
- result = val[1]
2647
+ (_, line), str, (_, func) = val
2648
+
2649
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2650
+
2651
+ result = str.line line
1859
2652
  }
1860
2653
  | tSTRING
1861
2654
  {
@@ -1864,7 +2657,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
2657
 
1865
2658
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1866
2659
  {
1867
- result = new_xstring val[1]
2660
+ result = new_xstring val
2661
+ # TODO: dedent?!?! SERIOUSLY?!?
1868
2662
  }
1869
2663
 
1870
2664
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1874,11 +2668,17 @@ opt_block_args_tail: tCOMMA block_args_tail
1874
2668
 
1875
2669
  words: tWORDS_BEG tSPACE tSTRING_END
1876
2670
  {
1877
- result = s(:array)
2671
+ (_, line), _, (_, line_max) = val
2672
+
2673
+ result = s(:array).line line
2674
+ result.line_max = line_max
1878
2675
  }
1879
2676
  | tWORDS_BEG word_list tSTRING_END
1880
2677
  {
1881
- result = val[1]
2678
+ (_, line), list, (_, line_max) = val
2679
+
2680
+ result = list.line line
2681
+ result.line_max = line_max
1882
2682
  }
1883
2683
 
1884
2684
  word_list: none
@@ -1898,11 +2698,17 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
2698
 
1899
2699
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1900
2700
  {
1901
- result = s(:array)
2701
+ (_, line), _, (_, line_max) = val
2702
+
2703
+ result = s(:array).line line
2704
+ result.line_max = line_max
1902
2705
  }
1903
2706
  | tSYMBOLS_BEG symbol_list tSTRING_END
1904
2707
  {
1905
- result = val[1]
2708
+ (_, line), list, (_, line_max), = val
2709
+
2710
+ result = list.line line
2711
+ result.line_max = line_max
1906
2712
  }
1907
2713
 
1908
2714
  symbol_list: none
@@ -1911,25 +2717,38 @@ opt_block_args_tail: tCOMMA block_args_tail
1911
2717
  }
1912
2718
  | symbol_list word tSPACE
1913
2719
  {
1914
- result = val[0].dup << new_symbol_list_entry(val)
2720
+ list, * = val
2721
+ result = list.dup << new_symbol_list_entry(val)
1915
2722
  }
1916
2723
 
1917
2724
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1918
2725
  {
1919
- result = s(:array)
2726
+ (_, line), _, (_, line_max) = val
2727
+
2728
+ result = s(:array).line line
2729
+ result.line_max = line_max
1920
2730
  }
1921
2731
  | tQWORDS_BEG qword_list tSTRING_END
1922
2732
  {
1923
- result = val[1]
2733
+ (_, line), list, (_, line_max) = val
2734
+
2735
+ result = list.line line
2736
+ result.line_max = line_max
1924
2737
  }
1925
2738
 
1926
2739
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1927
2740
  {
1928
- result = s(:array)
2741
+ (_, line), _, (_, line_max) = val
2742
+
2743
+ result = s(:array).line line
2744
+ result.line_max = line_max
1929
2745
  }
1930
2746
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1931
2747
  {
1932
- result = val[1]
2748
+ (_, line), list, (_, line_max) = val
2749
+
2750
+ result = list.line line
2751
+ result.line_max = line_max
1933
2752
  }
1934
2753
 
1935
2754
  qword_list: none
@@ -1952,11 +2771,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1952
2771
 
1953
2772
  string_contents: none
1954
2773
  {
1955
- result = s(:str, "")
2774
+ line = prev_value_to_lineno _values.last
2775
+ result = s(:str, +"").line line
1956
2776
  }
1957
2777
  | string_contents string_content
1958
2778
  {
1959
- result = literal_concat(val[0], val[1])
2779
+ v1, v2 = val
2780
+ result = literal_concat v1, v2
1960
2781
  }
1961
2782
 
1962
2783
  xstring_contents: none
@@ -1965,7 +2786,8 @@ xstring_contents: none
1965
2786
  }
1966
2787
  | xstring_contents string_content
1967
2788
  {
1968
- result = literal_concat(val[0], val[1])
2789
+ v1, v2 = val
2790
+ result = literal_concat v1, v2
1969
2791
  }
1970
2792
 
1971
2793
  regexp_contents: none
@@ -1974,7 +2796,8 @@ regexp_contents: none
1974
2796
  }
1975
2797
  | regexp_contents string_content
1976
2798
  {
1977
- result = literal_concat(val[0], val[1])
2799
+ v1, v2 = val
2800
+ result = literal_concat v1, v2
1978
2801
  }
1979
2802
 
1980
2803
  string_content: tSTRING_CONTENT
@@ -1990,19 +2813,22 @@ regexp_contents: none
1990
2813
  }
1991
2814
  string_dvar
1992
2815
  {
1993
- lexer.lex_strterm = val[1]
1994
- result = s(:evstr, val[2])
2816
+ _, strterm, str = val
2817
+ lexer.lex_strterm = strterm
2818
+ result = s(:evstr, str).line str.line
1995
2819
  }
1996
2820
  | tSTRING_DBEG
1997
2821
  {
1998
2822
  result = [lexer.lex_strterm,
1999
2823
  lexer.brace_nest,
2000
2824
  lexer.string_nest, # TODO: remove
2001
- lexer.cond.store,
2002
- lexer.cmdarg.store,
2003
2825
  lexer.lex_state,
2826
+ lexer.lineno,
2004
2827
  ]
2005
2828
 
2829
+ lexer.cmdarg.push false
2830
+ lexer.cond.push false
2831
+
2006
2832
  lexer.lex_strterm = nil
2007
2833
  lexer.brace_nest = 0
2008
2834
  lexer.string_nest = 0
@@ -2014,14 +2840,15 @@ regexp_contents: none
2014
2840
  {
2015
2841
  _, memo, stmt, _ = val
2016
2842
 
2017
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2843
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2844
+ # TODO: heredoc_indent
2018
2845
 
2019
2846
  lexer.lex_strterm = lex_strterm
2020
2847
  lexer.brace_nest = brace_nest
2021
2848
  lexer.string_nest = string_nest
2022
2849
 
2023
- lexer.cond.restore oldcond
2024
- lexer.cmdarg.restore oldcmdarg
2850
+ lexer.cond.pop
2851
+ lexer.cmdarg.pop
2025
2852
 
2026
2853
  lexer.lex_state = oldlex_state
2027
2854
 
@@ -2031,49 +2858,63 @@ regexp_contents: none
2031
2858
  when :str, :dstr, :evstr then
2032
2859
  result = stmt
2033
2860
  else
2034
- result = s(:evstr, stmt)
2861
+ result = s(:evstr, stmt).line line
2035
2862
  end
2036
2863
  when nil then
2037
- result = s(:evstr)
2864
+ result = s(:evstr).line line
2038
2865
  else
2039
- debug20 25
2866
+ debug 38
2040
2867
  raise "unknown string body: #{stmt.inspect}"
2041
2868
  end
2042
2869
  }
2043
2870
 
2044
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
2045
- | tIVAR { result = s(:ivar, val[0].to_sym) }
2046
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2871
+ string_dvar: tGVAR
2872
+ {
2873
+ result = wrap :gvar, val[0]
2874
+ }
2875
+ | tIVAR
2876
+ {
2877
+ result = wrap :ivar, val[0]
2878
+ }
2879
+ | tCVAR
2880
+ {
2881
+ result = wrap :cvar, val[0]
2882
+ }
2047
2883
  | backref
2048
2884
 
2049
- symbol: tSYMBEG sym
2885
+ symbol: ssym
2886
+ | dsym
2887
+
2888
+ ssym: tSYMBEG sym
2050
2889
  {
2051
2890
  lexer.lex_state = EXPR_END
2052
- result = val[1].to_sym
2891
+ result = wrap :lit, val[1]
2053
2892
  }
2054
2893
  | tSYMBOL
2055
2894
  {
2056
- result = val[0].to_sym
2895
+ lexer.lex_state = EXPR_END
2896
+ result = wrap :lit, val[0]
2057
2897
  }
2058
2898
 
2059
2899
  sym: fname | tIVAR | tGVAR | tCVAR
2060
2900
 
2061
- dsym: tSYMBEG xstring_contents tSTRING_END
2901
+ dsym: tSYMBEG string_contents tSTRING_END
2062
2902
  {
2903
+ _, result, _ = val
2904
+
2063
2905
  lexer.lex_state = EXPR_END
2064
- result = val[1]
2065
2906
 
2066
- result ||= s(:str, "")
2907
+ result ||= s(:str, "").line lexer.lineno
2067
2908
 
2068
2909
  case result.sexp_type
2069
2910
  when :dstr then
2070
2911
  result.sexp_type = :dsym
2071
2912
  when :str then
2072
- result = s(:lit, result.last.to_sym)
2913
+ result = s(:lit, result.last.to_sym).line result.line
2073
2914
  when :evstr then
2074
- result = s(:dsym, "", result)
2915
+ result = s(:dsym, "", result).line result.line
2075
2916
  else
2076
- debug20 26, val, result
2917
+ debug 39
2077
2918
  end
2078
2919
  }
2079
2920
 
@@ -2083,15 +2924,17 @@ regexp_contents: none
2083
2924
  | tUMINUS_NUM tINTEGER =tLOWEST
2084
2925
  #else
2085
2926
  numeric: simple_numeric
2086
- | tUMINUS_NUM simple_numeric
2927
+ | tUMINUS_NUM simple_numeric =tLOWEST
2087
2928
  #endif
2088
2929
  {
2089
- result = -val[1] # TODO: pt_testcase
2930
+ _, (num, line) = val
2931
+ result = [-num, line]
2090
2932
  #if V == 20
2091
2933
  }
2092
2934
  | tUMINUS_NUM tFLOAT =tLOWEST
2093
2935
  {
2094
- result = -val[1] # TODO: pt_testcase
2936
+ _, (num, line) = val
2937
+ result = [-num, line]
2095
2938
  #endif
2096
2939
  }
2097
2940
 
@@ -2108,26 +2951,29 @@ regexp_contents: none
2108
2951
  | tCONSTANT
2109
2952
  | tCVAR
2110
2953
 
2111
- keyword_variable: kNIL { result = s(:nil) }
2112
- | kSELF { result = s(:self) }
2113
- | kTRUE { result = s(:true) }
2114
- | kFALSE { result = s(:false) }
2115
- | k__FILE__ { result = s(:str, self.file) }
2116
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2954
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2955
+ | kSELF { result = s(:self).line lexer.lineno }
2956
+ | kTRUE { result = s(:true).line lexer.lineno }
2957
+ | kFALSE { result = s(:false).line lexer.lineno }
2958
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2959
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2117
2960
  | k__ENCODING__
2118
2961
  {
2962
+ l = lexer.lineno
2119
2963
  result =
2120
2964
  if defined? Encoding then
2121
- s(:colon2, s(:const, :Encoding), :UTF_8)
2965
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2122
2966
  else
2123
- s(:str, "Unsupported!")
2967
+ s(:str, "Unsupported!").line l
2124
2968
  end
2125
2969
  }
2126
2970
 
2127
2971
  var_ref: user_variable
2128
2972
  {
2129
- var = val[0]
2973
+ raise "NO: #{val.inspect}" if Sexp === val.first
2974
+ (var, line), = val
2130
2975
  result = Sexp === var ? var : self.gettable(var)
2976
+ result.line line
2131
2977
  }
2132
2978
  | keyword_variable
2133
2979
  {
@@ -2142,11 +2988,19 @@ keyword_variable: kNIL { result = s(:nil) }
2142
2988
  | keyword_variable
2143
2989
  {
2144
2990
  result = self.assignable val[0]
2145
- debug20 29, val, result
2991
+ debug 40
2146
2992
  }
2147
2993
 
2148
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2149
- | tBACK_REF { result = s(:back_ref, val[0]) }
2994
+ backref: tNTH_REF
2995
+ {
2996
+ (ref, line), = val
2997
+ result = s(:nth_ref, ref).line line
2998
+ }
2999
+ | tBACK_REF
3000
+ {
3001
+ (ref, line), = val
3002
+ result = s(:back_ref, ref).line line
3003
+ }
2150
3004
 
2151
3005
  superclass: tLT
2152
3006
  {
@@ -2164,10 +3018,18 @@ keyword_variable: kNIL { result = s(:nil) }
2164
3018
 
2165
3019
  f_arglist: tLPAREN2 f_args rparen
2166
3020
  {
2167
- result = val[1]
2168
- self.lexer.lex_state = EXPR_BEG
2169
- self.lexer.command_start = true
3021
+ result = end_args val
3022
+ }
3023
+ #if V == 27
3024
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3025
+ {
3026
+ result = end_args val
3027
+ }
3028
+ | tLPAREN2 args_forward rparen
3029
+ {
3030
+ result = end_args val
2170
3031
  }
3032
+ #endif
2171
3033
  | {
2172
3034
  result = self.in_kwarg
2173
3035
  self.in_kwarg = true
@@ -2175,12 +3037,7 @@ keyword_variable: kNIL { result = s(:nil) }
2175
3037
  }
2176
3038
  f_args term
2177
3039
  {
2178
- kwarg, args, _ = val
2179
-
2180
- self.in_kwarg = kwarg
2181
- result = args
2182
- lexer.lex_state = EXPR_BEG
2183
- lexer.command_start = true
3040
+ result = end_args val
2184
3041
  }
2185
3042
 
2186
3043
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2195,6 +3052,12 @@ keyword_variable: kNIL { result = s(:nil) }
2195
3052
  {
2196
3053
  result = args val
2197
3054
  }
3055
+ #if V >= 27
3056
+ | f_no_kwarg opt_f_block_arg
3057
+ {
3058
+ result = args val
3059
+ }
3060
+ #endif
2198
3061
  | f_block_arg
2199
3062
 
2200
3063
  opt_args_tail: tCOMMA args_tail
@@ -2265,8 +3128,16 @@ keyword_variable: kNIL { result = s(:nil) }
2265
3128
  |
2266
3129
  {
2267
3130
  result = args val
3131
+ # result.line lexer.lineno
2268
3132
  }
2269
3133
 
3134
+ #if V >= 27
3135
+ args_forward: tBDOT3
3136
+ {
3137
+ result = s(:forward_args).line lexer.lineno
3138
+ }
3139
+ #endif
3140
+
2270
3141
  f_bad_arg: tCONSTANT
2271
3142
  {
2272
3143
  yyerror "formal argument cannot be a constant"
@@ -2287,10 +3158,11 @@ keyword_variable: kNIL { result = s(:nil) }
2287
3158
  f_norm_arg: f_bad_arg
2288
3159
  | tIDENTIFIER
2289
3160
  {
2290
- identifier = val[0].to_sym
3161
+ (id, line), = val
3162
+ identifier = id.to_sym
2291
3163
  self.env[identifier] = :lvar
2292
3164
 
2293
- result = identifier
3165
+ result = [identifier, line]
2294
3166
  }
2295
3167
 
2296
3168
  #if V >= 22
@@ -2299,28 +3171,23 @@ keyword_variable: kNIL { result = s(:nil) }
2299
3171
  f_arg_item: f_arg_asgn
2300
3172
  | tLPAREN f_margs rparen
2301
3173
  {
2302
- result = val[1]
3174
+ _, margs, _ = val
3175
+
3176
+ result = margs
2303
3177
  }
2304
3178
  #else
2305
3179
  f_arg_item: f_norm_arg
2306
3180
  | tLPAREN f_margs rparen
2307
3181
  {
2308
- result = val[1]
3182
+ _, margs, _ = val
3183
+
3184
+ result = margs
2309
3185
  }
2310
3186
  #endif
2311
3187
 
2312
3188
  f_arg: f_arg_item
2313
3189
  {
2314
- case val[0]
2315
- when Symbol then
2316
- result = s(:args)
2317
- result << val[0]
2318
- when Sexp then
2319
- result = val[0]
2320
- else
2321
- debug20 32
2322
- raise "Unknown f_arg type: #{val.inspect}"
2323
- end
3190
+ result = new_arg val
2324
3191
  }
2325
3192
  | f_arg tCOMMA f_arg_item
2326
3193
  {
@@ -2329,10 +3196,17 @@ keyword_variable: kNIL { result = s(:nil) }
2329
3196
  if list.sexp_type == :args then
2330
3197
  result = list
2331
3198
  else
2332
- result = s(:args, list)
3199
+ result = s(:args, list).line list.line
3200
+ end
3201
+
3202
+ if Sexp === item then
3203
+ line_max = item.line_max
3204
+ else
3205
+ item, line_max = item
2333
3206
  end
2334
3207
 
2335
3208
  result << item
3209
+ result.line_max = line_max
2336
3210
  }
2337
3211
 
2338
3212
  #if V == 20
@@ -2343,21 +3217,24 @@ keyword_variable: kNIL { result = s(:nil) }
2343
3217
  f_kw: f_label arg_value
2344
3218
  #endif
2345
3219
  {
2346
- # TODO: call_args
2347
- label, _ = val[0] # TODO: fix lineno?
3220
+ # TODO: new_kw_arg
3221
+ (label, line), arg = val
3222
+
2348
3223
  identifier = label.to_sym
2349
3224
  self.env[identifier] = :lvar
2350
3225
 
2351
- result = s(:array, s(:kwarg, identifier, val[1]))
3226
+ kwarg = s(:kwarg, identifier, arg).line line
3227
+ result = s(:array, kwarg).line line
2352
3228
  }
2353
3229
  #if V >= 21
2354
3230
  | f_label
2355
3231
  {
2356
- label, _ = val[0] # TODO: fix lineno?
2357
- identifier = label.to_sym
2358
- self.env[identifier] = :lvar
3232
+ (label, line), = val
2359
3233
 
2360
- result = s(:array, s(:kwarg, identifier))
3234
+ id = label.to_sym
3235
+ self.env[id] = :lvar
3236
+
3237
+ result = s(:array, s(:kwarg, id).line(line)).line line
2361
3238
  }
2362
3239
  #endif
2363
3240
 
@@ -2367,21 +3244,22 @@ keyword_variable: kNIL { result = s(:nil) }
2367
3244
  f_block_kw: f_label primary_value
2368
3245
  #endif
2369
3246
  {
2370
- # TODO: call_args
2371
- label, _ = val[0] # TODO: fix lineno?
2372
- identifier = label.to_sym
2373
- self.env[identifier] = :lvar
3247
+ # TODO: new_kw_arg
3248
+ (label, line), expr = val
3249
+ id = label.to_sym
3250
+ self.env[id] = :lvar
2374
3251
 
2375
- result = s(:array, s(:kwarg, identifier, val[1]))
3252
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2376
3253
  }
2377
3254
  #if V >= 21
2378
3255
  | f_label
2379
3256
  {
2380
- label, _ = val[0] # TODO: fix lineno?
2381
- identifier = label.to_sym
2382
- self.env[identifier] = :lvar
3257
+ # TODO: new_kw_arg
3258
+ (label, line), = val
3259
+ id = label.to_sym
3260
+ self.env[id] = :lvar
2383
3261
 
2384
- result = s(:array, s(:kwarg, identifier))
3262
+ result = s(:array, s(:kwarg, id).line(line)).line line
2385
3263
  }
2386
3264
  #endif
2387
3265
 
@@ -2401,15 +3279,26 @@ keyword_variable: kNIL { result = s(:nil) }
2401
3279
  kwrest_mark: tPOW
2402
3280
  | tDSTAR
2403
3281
 
3282
+ #if V >= 27
3283
+ f_no_kwarg: kwrest_mark kNIL
3284
+ {
3285
+ result = :"**nil"
3286
+ }
3287
+ #endif
3288
+
2404
3289
  f_kwrest: kwrest_mark tIDENTIFIER
2405
3290
  {
2406
- name = val[1].to_sym
2407
- self.assignable name
2408
- result = :"**#{name}"
3291
+ _, (id, line) = val
3292
+
3293
+ name = id.to_sym
3294
+ self.assignable [name, line]
3295
+ result = [:"**#{name}", line]
2409
3296
  }
2410
3297
  | kwrest_mark
2411
3298
  {
2412
- result = :"**"
3299
+ id = :"**"
3300
+ self.env[id] = :lvar # TODO: needed?!?
3301
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2413
3302
  }
2414
3303
 
2415
3304
  #if V == 20
@@ -2420,7 +3309,8 @@ keyword_variable: kNIL { result = s(:nil) }
2420
3309
  f_opt: f_arg_asgn tEQL arg_value
2421
3310
  #endif
2422
3311
  {
2423
- result = self.assignable val[0], val[2]
3312
+ lhs, _, rhs = val
3313
+ result = self.assignable lhs, rhs
2424
3314
  # TODO: detect duplicate names
2425
3315
  }
2426
3316
 
@@ -2432,22 +3322,26 @@ keyword_variable: kNIL { result = s(:nil) }
2432
3322
  f_block_opt: f_arg_asgn tEQL primary_value
2433
3323
  #endif
2434
3324
  {
2435
- result = self.assignable val[0], val[2]
3325
+ lhs, _, rhs = val
3326
+ result = self.assignable lhs, rhs
2436
3327
  }
2437
3328
 
2438
3329
  f_block_optarg: f_block_opt
2439
3330
  {
2440
- result = s(:block, val[0])
3331
+ optblk, = val
3332
+ result = s(:block, optblk).line optblk.line
2441
3333
  }
2442
3334
  | f_block_optarg tCOMMA f_block_opt
2443
3335
  {
2444
- result = val[0]
2445
- result << val[2]
3336
+ optarg, _, optblk = val
3337
+ result = optarg
3338
+ result << optblk
2446
3339
  }
2447
3340
 
2448
3341
  f_optarg: f_opt
2449
3342
  {
2450
- result = s(:block, val[0])
3343
+ opt, = val
3344
+ result = s(:block, opt).line opt.line
2451
3345
  }
2452
3346
  | f_optarg tCOMMA f_opt
2453
3347
  {
@@ -2459,30 +3353,33 @@ keyword_variable: kNIL { result = s(:nil) }
2459
3353
  f_rest_arg: restarg_mark tIDENTIFIER
2460
3354
  {
2461
3355
  # TODO: differs from parse.y - needs tests
2462
- name = val[1].to_sym
2463
- self.assignable name
2464
- result = :"*#{name}"
3356
+ _, (id, line) = val
3357
+ name = id.to_sym
3358
+ self.assignable [name, line]
3359
+ result = [:"*#{name}", line]
2465
3360
  }
2466
3361
  | restarg_mark
2467
3362
  {
2468
3363
  name = :"*"
2469
3364
  self.env[name] = :lvar
2470
- result = name
3365
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2471
3366
  }
2472
3367
 
2473
3368
  blkarg_mark: tAMPER2 | tAMPER
2474
3369
 
2475
3370
  f_block_arg: blkarg_mark tIDENTIFIER
2476
3371
  {
2477
- identifier = val[1].to_sym
3372
+ _, (id, line) = val
3373
+ identifier = id.to_sym
2478
3374
 
2479
3375
  self.env[identifier] = :lvar
2480
- result = "&#{identifier}".to_sym
3376
+ result = ["&#{identifier}".to_sym, line]
2481
3377
  }
2482
3378
 
2483
3379
  opt_f_block_arg: tCOMMA f_block_arg
2484
3380
  {
2485
- result = val[1]
3381
+ _, arg = val
3382
+ result = arg
2486
3383
  }
2487
3384
  |
2488
3385
  {
@@ -2501,14 +3398,11 @@ keyword_variable: kNIL { result = s(:nil) }
2501
3398
  result.sexp_type == :lit
2502
3399
  }
2503
3400
 
2504
- assoc_list: none # [!nil]
2505
- {
2506
- result = s(:array)
2507
- }
2508
- | assocs trailer # [!nil]
3401
+ assoc_list: none
2509
3402
  {
2510
- result = val[0]
3403
+ result = s(:array).line lexer.lineno
2511
3404
  }
3405
+ | assocs trailer
2512
3406
 
2513
3407
  assocs: assoc
2514
3408
  | assocs tCOMMA assoc
@@ -2522,24 +3416,31 @@ keyword_variable: kNIL { result = s(:nil) }
2522
3416
 
2523
3417
  assoc: arg_value tASSOC arg_value
2524
3418
  {
2525
- result = s(:array, val[0], val[2])
3419
+ v1, _, v2 = val
3420
+ result = s(:array, v1, v2).line v1.line
2526
3421
  }
2527
3422
  | tLABEL arg_value
2528
3423
  {
2529
- (label, _), arg = val
2530
- result = s(:array, s(:lit, label.to_sym), arg)
3424
+ label, arg = val
3425
+
3426
+ lit = wrap :lit, label
3427
+ result = s(:array, lit, arg).line lit.line
2531
3428
  }
2532
3429
  #if V >= 22
2533
3430
  | tSTRING_BEG string_contents tLABEL_END arg_value
2534
3431
  {
2535
- _, sym, _, value = val
3432
+ (_, line), sym, _, value = val
3433
+
2536
3434
  sym.sexp_type = :dsym
2537
- result = s(:array, sym, value)
3435
+
3436
+ result = s(:array, sym, value).line line
2538
3437
  }
2539
3438
  #endif
2540
3439
  | tDSTAR arg_value
2541
3440
  {
2542
- result = s(:array, s(:kwsplat, val[1]))
3441
+ _, arg = val
3442
+ line = arg.line
3443
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2543
3444
  }
2544
3445
 
2545
3446
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2557,7 +3458,18 @@ keyword_variable: kNIL { result = s(:nil) }
2557
3458
  opt_terms: | terms
2558
3459
  opt_nl: | tNL
2559
3460
  rparen: opt_nl tRPAREN
3461
+ {
3462
+ _, close = val
3463
+ result = [close, lexer.lineno]
3464
+ }
2560
3465
  rbracket: opt_nl tRBRACK
3466
+ {
3467
+ _, close = val
3468
+ result = [close, lexer.lineno]
3469
+ }
3470
+ #if V >= 27
3471
+ rbrace: opt_nl tRCURLY
3472
+ #endif
2561
3473
  trailer: | tNL | tCOMMA
2562
3474
 
2563
3475
  term: tSEMI { yyerrok }