ruby_parser 3.12.0 → 3.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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