ruby_parser 3.12.0 → 3.18.1

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