ruby_parser 3.13.1 → 3.15.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.
@@ -6,9 +6,9 @@ class RubyLexer
6
6
 
7
7
  macro
8
8
 
9
- IDENT /^#{IDENT_CHAR}+/o
9
+ IDENT_CHAR /[a-zA-Z0-9_[:^ascii:]]/
10
10
 
11
- ESC /\\((?>[0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|u[0-9a-fA-F]{1,4}|u\{[0-9a-fA-F]+\}|[^0-7xMCc]))/
11
+ ESC /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
12
12
  SIMPLE_STRING /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
13
13
  SSTRING /((\\.|[^\'])*)/
14
14
 
@@ -62,7 +62,7 @@ rule
62
62
  | /\=(?=begin\b)/ { result arg_state, TOKENS[text], text }
63
63
 
64
64
  ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
65
- /\"(#{SIMPLE_STRING})\"/o { result EXPR_END, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
65
+ /\"(#{SIMPLE_STRING})\"/o process_simple_string
66
66
  /\"/ { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
67
67
 
68
68
  /\@\@?\d/ { rb_compile_error "`#{text}` is not allowed as a variable name" }
@@ -164,13 +164,12 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
164
164
  | in_fname? /\$([1-9]\d*)/ process_gvar
165
165
  | /\$([1-9]\d*)/ process_nthref
166
166
  | /\$0/ process_gvar
167
- | /\$[^[:ascii:]]+/ process_gvar
167
+ | /\$#{IDENT_CHAR}+/ process_gvar
168
168
  | /\$\W|\$\z/ process_gvar_oddity
169
- | /\$\w+/ process_gvar
170
169
 
171
170
  /\_/ process_underscore
172
171
 
173
- /#{IDENT}/o process_token
172
+ /#{IDENT_CHAR}+/o process_token
174
173
 
175
174
  /\004|\032|\000|\Z/ { [RubyLexer::EOF, RubyLexer::EOF] }
176
175
 
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  #--
3
3
  # This file is automatically generated. Do not modify it.
4
- # Generated by: oedipus_lex version 2.5.0.
4
+ # Generated by: oedipus_lex version 2.5.2.
5
5
  # Source: lib/ruby_lexer.rex
6
6
  #++
7
7
 
@@ -16,8 +16,8 @@ class RubyLexer
16
16
  require 'strscan'
17
17
 
18
18
  # :stopdoc:
19
- IDENT = /^#{IDENT_CHAR}+/o
20
- ESC = /\\((?>[0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|u[0-9a-fA-F]{1,4}|u\{[0-9a-fA-F]+\}|[^0-7xMCc]))/
19
+ IDENT_CHAR = /[a-zA-Z0-9_[:^ascii:]]/
20
+ ESC = /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
21
21
  SIMPLE_STRING = /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
22
22
  SSTRING = /((\\.|[^\'])*)/
23
23
  INT_DEC = /[+]?(?:(?:[1-9][\d_]*|0)(?!\.\d)(ri|r|i)?\b|0d[0-9_]+)(ri|r|i)?/i
@@ -160,7 +160,7 @@ class RubyLexer
160
160
  when ruby22_label? && (text = ss.scan(/\"#{SIMPLE_STRING}\":/o)) then
161
161
  process_label text
162
162
  when text = ss.scan(/\"(#{SIMPLE_STRING})\"/o) then
163
- action { result EXPR_END, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
163
+ process_simple_string text
164
164
  when text = ss.scan(/\"/) then
165
165
  action { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
166
166
  when text = ss.scan(/\@\@?\d/) then
@@ -328,16 +328,14 @@ class RubyLexer
328
328
  process_nthref text
329
329
  when text = ss.scan(/\$0/) then
330
330
  process_gvar text
331
- when text = ss.scan(/\$[^[:ascii:]]+/) then
331
+ when text = ss.scan(/\$#{IDENT_CHAR}+/) then
332
332
  process_gvar text
333
333
  when text = ss.scan(/\$\W|\$\z/) then
334
334
  process_gvar_oddity text
335
- when text = ss.scan(/\$\w+/) then
336
- process_gvar text
337
335
  end # group /\$/
338
336
  when text = ss.scan(/\_/) then
339
337
  process_underscore text
340
- when text = ss.scan(/#{IDENT}/o) then
338
+ when text = ss.scan(/#{IDENT_CHAR}+/o) then
341
339
  process_token text
342
340
  when ss.skip(/\004|\032|\000|\Z/) then
343
341
  action { [RubyLexer::EOF, RubyLexer::EOF] }
@@ -11,23 +11,22 @@ class RubyParser
11
11
 
12
12
  attr_accessor :current
13
13
 
14
- class Parser < Racc::Parser
15
- include RubyParserStuff
16
-
17
- def self.inherited x
18
- RubyParser::VERSIONS << x
19
- end
20
-
21
- def self.version= v
22
- @version = v
23
- end
14
+ def self.for_current_ruby
15
+ name = "V#{RUBY_VERSION[/^\d+\.\d+/].delete "."}"
16
+ klass = if const_defined? name then
17
+ const_get name
18
+ else
19
+ latest = VERSIONS.first
20
+ warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
21
+ latest
22
+ end
24
23
 
25
- def self.version
26
- @version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
27
- end
24
+ klass.new
28
25
  end
29
26
 
30
- class SyntaxError < RuntimeError; end
27
+ def self.latest
28
+ VERSIONS.first.new
29
+ end
31
30
 
32
31
  def process s, f = "(string)", t = 10
33
32
  e = nil
@@ -48,22 +47,23 @@ class RubyParser
48
47
  # do nothing
49
48
  end
50
49
 
51
- def self.latest
52
- VERSIONS.first.new
53
- end
50
+ class Parser < Racc::Parser
51
+ include RubyParserStuff
54
52
 
55
- def self.for_current_ruby
56
- name = "V#{RUBY_VERSION[/^\d+\.\d+/].delete "."}"
57
- klass = if const_defined? name then
58
- const_get name
59
- else
60
- latest = VERSIONS.first
61
- warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
62
- latest
63
- end
53
+ def self.inherited x
54
+ RubyParser::VERSIONS << x
55
+ end
64
56
 
65
- klass.new
57
+ def self.version= v
58
+ @version = v
59
+ end
60
+
61
+ def self.version
62
+ @version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
63
+ end
66
64
  end
65
+
66
+ class SyntaxError < RuntimeError; end
67
67
  end
68
68
 
69
69
  ##
@@ -78,10 +78,12 @@ require "ruby23_parser"
78
78
  require "ruby24_parser"
79
79
  require "ruby25_parser"
80
80
  require "ruby26_parser"
81
+ require "ruby27_parser"
81
82
 
82
83
  class RubyParser # HACK
83
84
  VERSIONS.clear # also a HACK caused by racc namespace issues
84
85
 
86
+ class V27 < ::Ruby27Parser; end
85
87
  class V26 < ::Ruby26Parser; end
86
88
  class V25 < ::Ruby25Parser; end
87
89
  class V24 < ::Ruby24Parser; end
@@ -14,6 +14,8 @@ class Ruby24Parser
14
14
  class Ruby25Parser
15
15
  #elif V == 26
16
16
  class Ruby26Parser
17
+ #elif V == 27
18
+ class Ruby27Parser
17
19
  #else
18
20
  fail "version not specified or supported on code generation"
19
21
  #endif
@@ -45,30 +47,30 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
45
47
  tLONELY
46
48
  #endif
47
49
 
48
- prechigh
49
- right tBANG tTILDE tUPLUS
50
- right tPOW
51
- right tUMINUS_NUM tUMINUS
52
- left tSTAR2 tDIVIDE tPERCENT
53
- left tPLUS tMINUS
54
- left tLSHFT tRSHFT
55
- left tAMPER2
56
- left tPIPE tCARET
57
- left tGT tGEQ tLT tLEQ
58
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
59
- left tANDOP
60
- left tOROP
61
- nonassoc tDOT2 tDOT3
62
- right tEH tCOLON
63
- left kRESCUE_MOD
64
- right tEQL tOP_ASGN
65
- nonassoc kDEFINED
66
- right kNOT
67
- left kOR kAND
68
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
69
- nonassoc tLBRACE_ARG
70
- nonassoc tLOWEST
71
50
  preclow
51
+ nonassoc tLOWEST
52
+ nonassoc tLBRACE_ARG
53
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
54
+ left kOR kAND
55
+ right kNOT
56
+ nonassoc kDEFINED
57
+ right tEQL tOP_ASGN
58
+ left kRESCUE_MOD
59
+ right tEH tCOLON
60
+ nonassoc tDOT2 tDOT3
61
+ left tOROP
62
+ left tANDOP
63
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
64
+ left tGT tGEQ tLT tLEQ
65
+ left tPIPE tCARET
66
+ left tAMPER2
67
+ left tLSHFT tRSHFT
68
+ left tPLUS tMINUS
69
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
70
+ right tUMINUS_NUM tUMINUS
71
+ right tPOW
72
+ right tBANG tTILDE tUPLUS
73
+ prechigh
72
74
 
73
75
  rule
74
76
 
@@ -82,7 +84,8 @@ rule
82
84
 
83
85
  top_compstmt: top_stmts opt_terms
84
86
  {
85
- result = val[0]
87
+ stmt, _ = val
88
+ result = stmt
86
89
  }
87
90
 
88
91
  top_stmts: none
@@ -94,14 +97,6 @@ rule
94
97
  | error top_stmt
95
98
 
96
99
  top_stmt: stmt
97
- {
98
- result = val[0]
99
-
100
- # TODO: remove once I have more confidence this is fixed
101
- # result.each_of_type :call_args do |s|
102
- # debug20 666, s, result
103
- # end
104
- }
105
100
  | klBEGIN
106
101
  {
107
102
  if (self.in_def || self.in_single > 0) then
@@ -112,14 +107,19 @@ rule
112
107
  }
113
108
  begin_block
114
109
  {
115
- _, _, block = val
116
- result = block
110
+ (_, lineno), _, iter = val
111
+ iter.line lineno
112
+
113
+ (_, preexe,) = iter
114
+ preexe.line lineno
115
+
116
+ result = iter
117
117
  }
118
118
 
119
- begin_block: tLCURLY top_compstmt tRCURLY
119
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
120
120
  {
121
- _, stmt, _ = val
122
- result = new_iter s(:preexe), 0, stmt
121
+ _, line, stmt, _ = val
122
+ result = new_iter s(:preexe).line(line), 0, stmt
123
123
  }
124
124
 
125
125
  bodystmt: compstmt opt_rescue k_else
@@ -161,34 +161,27 @@ rule
161
161
  stmt_or_begin: stmt
162
162
  | klBEGIN
163
163
  {
164
- if (self.in_def || self.in_single > 0) then
165
- debug20 1
166
- yyerror "BEGIN in method"
167
- end
168
- self.env.extend
169
- }
170
- begin_block
171
- {
172
- _, _, stmt = val
173
- result = stmt
164
+ yyerror "BEGIN is permitted only at toplevel"
174
165
  }
175
166
 
176
167
  stmt: kALIAS fitem
177
168
  {
178
169
  lexer.lex_state = EXPR_FNAME
179
- result = self.lexer.lineno
180
170
  }
181
171
  fitem
182
172
  {
183
- result = s(:alias, val[1], val[3]).line(val[2])
173
+ (_, line), lhs, _, rhs = val
174
+ result = s(:alias, lhs, rhs).line(line).line line
184
175
  }
185
176
  | kALIAS tGVAR tGVAR
186
177
  {
187
- result = s(:valias, val[1].to_sym, val[2].to_sym)
178
+ (_, line), lhs, rhs = val
179
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
188
180
  }
189
181
  | kALIAS tGVAR tBACK_REF
190
182
  {
191
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
183
+ (_, line), lhs, rhs = val
184
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
192
185
  }
193
186
  | kALIAS tGVAR tNTH_REF
194
187
  {
@@ -200,32 +193,41 @@ rule
200
193
  }
201
194
  | stmt kIF_MOD expr_value
202
195
  {
203
- result = new_if val[2], val[0], nil
196
+ t, _, c = val
197
+ result = new_if c, t, nil
204
198
  }
205
199
  | stmt kUNLESS_MOD expr_value
206
200
  {
207
- result = new_if val[2], nil, val[0]
201
+ f, _, c = val
202
+ result = new_if c, nil, f
208
203
  }
209
204
  | stmt kWHILE_MOD expr_value
210
205
  {
211
- result = new_while val[0], val[2], true
206
+ e, _, c = val
207
+ result = new_while e, c, true
212
208
  }
213
209
  | stmt kUNTIL_MOD expr_value
214
210
  {
215
- result = new_until val[0], val[2], true
211
+ e, _, c = val
212
+ result = new_until e, c, true
216
213
  }
217
214
  | stmt kRESCUE_MOD stmt
218
215
  {
219
216
  body, _, resbody = val
220
- result = new_rescue body, new_resbody(s(:array), resbody)
217
+
218
+ resbody = new_resbody s(:array).line(resbody.line), resbody
219
+ result = new_rescue body, resbody
221
220
  }
222
221
  | klEND tLCURLY compstmt tRCURLY
223
222
  {
223
+ (_, line), _, stmt, _ = val
224
+
224
225
  if (self.in_def || self.in_single > 0) then
225
226
  debug20 3
226
227
  yyerror "END in method; use at_exit"
227
228
  end
228
- result = new_iter s(:postexe), 0, val[2]
229
+
230
+ result = new_iter s(:postexe).line(line), 0, stmt
229
231
  }
230
232
  | command_asgn
231
233
  | mlhs tEQL command_call
@@ -234,7 +236,8 @@ rule
234
236
  }
235
237
  | lhs tEQL mrhs
236
238
  {
237
- result = new_assign val[0], s(:svalue, val[2])
239
+ lhs, _, rhs = val
240
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
238
241
  }
239
242
  #if V == 20
240
243
  | mlhs tEQL arg_value
@@ -264,11 +267,12 @@ rule
264
267
  }
265
268
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
266
269
  {
267
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
270
+ result = new_op_asgn1 val
268
271
  }
269
272
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
270
273
  {
271
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
274
+ prim, _, id, opasgn, rhs = val
275
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
272
276
  if val[1] == '&.'
273
277
  result.sexp_type = :safe_op_asgn
274
278
  end
@@ -284,13 +288,15 @@ rule
284
288
  }
285
289
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
286
290
  {
287
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
288
- debug20 4, val, result
291
+ lhs1, _, lhs2, op, rhs = val
292
+
293
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
289
294
  }
290
295
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
291
296
  {
292
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
293
- debug20 5, val, result
297
+ lhs1, _, lhs2, op, rhs = val
298
+
299
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
294
300
  }
295
301
  | backref tOP_ASGN command_rhs
296
302
  {
@@ -305,9 +311,11 @@ rule
305
311
  #if V >= 24
306
312
  | command_call kRESCUE_MOD stmt
307
313
  {
308
- expr, _, resbody = val
314
+ expr, (_, line), resbody = val
315
+
309
316
  expr = value_expr expr
310
- result = new_rescue(expr, new_resbody(s(:array), resbody))
317
+ ary = s(:array).line line
318
+ result = new_rescue(expr, new_resbody(ary, resbody))
311
319
  }
312
320
  #endif
313
321
  | command_asgn
@@ -315,19 +323,26 @@ rule
315
323
  expr: command_call
316
324
  | expr kAND expr
317
325
  {
318
- result = logical_op :and, val[0], val[2]
326
+ lhs, _, rhs = val
327
+ result = logical_op :and, lhs, rhs
319
328
  }
320
329
  | expr kOR expr
321
330
  {
322
- result = logical_op :or, val[0], val[2]
331
+ lhs, _, rhs = val
332
+ result = logical_op :or, lhs, rhs
323
333
  }
324
334
  | kNOT opt_nl expr
325
335
  {
326
- result = s(:call, val[2], :"!")
336
+ (_, line), _, expr = val
337
+ result = new_call(expr, :"!").line line
338
+ # REFACTOR: call_uni_op
327
339
  }
328
340
  | tBANG command_call
329
341
  {
330
- result = s(:call, val[1], :"!")
342
+ _, cmd = val
343
+ result = new_call(cmd, :"!").line cmd.line
344
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
345
+ # REFACTOR: call_uni_op -- see parse26.y
331
346
  }
332
347
  | arg
333
348
 
@@ -354,7 +369,8 @@ rule
354
369
  block_command: block_call
355
370
  | block_call call_op2 operation2 command_args
356
371
  {
357
- result = new_call val[0], val[2].to_sym, val[3]
372
+ blk, _, msg, args = val
373
+ result = new_call(blk, msg.to_sym, args).line blk.line
358
374
  }
359
375
 
360
376
  cmd_brace_block: tLBRACE_ARG
@@ -374,26 +390,32 @@ rule
374
390
 
375
391
  fcall: operation
376
392
  {
377
- result = new_call nil, val[0].to_sym
393
+ msg, = val
394
+ result = new_call(nil, msg.to_sym).line lexer.lineno
378
395
  }
379
396
 
380
397
  command: fcall command_args =tLOWEST
381
398
  {
382
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
399
+ call, args = val
400
+ result = call.concat args.sexp_body
383
401
  }
384
402
  | fcall command_args cmd_brace_block
385
403
  {
386
- result = val[0].concat val[1].sexp_body
387
- if val[2] then
388
- block_dup_check result, val[2]
404
+ call, args, block = val
389
405
 
390
- result, operation = val[2], result
406
+ result = call.concat args.sexp_body
407
+
408
+ if block then
409
+ block_dup_check result, block
410
+
411
+ result, operation = block, result
391
412
  result.insert 1, operation
392
413
  end
393
414
  }
394
415
  | primary_value call_op operation2 command_args =tLOWEST
395
416
  {
396
- result = new_call val[0], val[2].to_sym, val[3], val[1]
417
+ lhs, callop, op, args = val
418
+ result = new_call lhs, op.to_sym, args, callop
397
419
  }
398
420
  | primary_value call_op operation2 command_args cmd_brace_block
399
421
  {
@@ -425,7 +447,9 @@ rule
425
447
  }
426
448
  | kYIELD command_args
427
449
  {
428
- result = new_yield val[1]
450
+ (_, line), args = val
451
+ result = new_yield args
452
+ result.line line # TODO: push to new_yield
429
453
  }
430
454
  | k_return call_args
431
455
  {
@@ -434,8 +458,8 @@ rule
434
458
  }
435
459
  | kBREAK call_args
436
460
  {
437
- line = val[0].last
438
- result = s(:break, ret_args(val[1])).line(line)
461
+ (_, line), args = val
462
+ result = s(:break, ret_args(args)).line line
439
463
  }
440
464
  | kNEXT call_args
441
465
  {
@@ -452,56 +476,79 @@ rule
452
476
  mlhs_inner: mlhs_basic
453
477
  | tLPAREN mlhs_inner rparen
454
478
  {
455
- result = s(:masgn, s(:array, val[1]))
479
+ _, arg, _ = val
480
+ l = arg.line
481
+
482
+ result = s(:masgn, s(:array, arg).line(l)).line l
456
483
  }
457
484
 
458
485
  mlhs_basic: mlhs_head
459
486
  {
460
- result = s(:masgn, val[0])
487
+ head, = val
488
+ result = s(:masgn, head).line head.line
461
489
  }
462
490
  | mlhs_head mlhs_item
463
491
  {
464
- result = s(:masgn, val[0] << val[1].compact)
492
+ lhs, rhs = val
493
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
465
494
  }
466
495
  | mlhs_head tSTAR mlhs_node
467
496
  {
468
- result = s(:masgn, val[0] << s(:splat, val[2]))
497
+ head, _, tail = val
498
+ head << s(:splat, tail).line(tail.line)
499
+ result = s(:masgn, head).line head.line
469
500
  }
470
501
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
471
502
  {
472
503
  ary1, _, splat, _, ary2 = val
473
504
 
474
- result = list_append ary1, s(:splat, splat)
505
+ result = list_append ary1, s(:splat, splat).line(splat.line)
475
506
  result.concat ary2.sexp_body
476
- result = s(:masgn, result)
507
+ result = s(:masgn, result).line result.line
477
508
  }
478
509
  | mlhs_head tSTAR
479
510
  {
480
- result = s(:masgn, val[0] << s(:splat))
511
+ head, _ = val
512
+ l = head.line
513
+ result = s(:masgn, head << s(:splat).line(l)).line l
481
514
  }
482
515
  | mlhs_head tSTAR tCOMMA mlhs_post
483
516
  {
484
- ary = list_append val[0], s(:splat)
485
- ary.concat val[3].sexp_body
486
- result = s(:masgn, ary)
517
+ head, _, _, post = val
518
+ ary = list_append head, s(:splat).line(head.line)
519
+ ary.concat post.sexp_body
520
+ result = s(:masgn, ary).line ary.line
487
521
  }
488
522
  | tSTAR mlhs_node
489
523
  {
490
- result = s(:masgn, s(:array, s(:splat, val[1])))
524
+ _, node = val
525
+ l = node.line
526
+ splat = s(:splat, node).line l
527
+ ary = s(:array, splat).line l
528
+ result = s(:masgn, ary).line l
491
529
  }
492
530
  | tSTAR mlhs_node tCOMMA mlhs_post
493
531
  {
494
- ary = s(:array, s(:splat, val[1]))
495
- ary.concat val[3].sexp_body
496
- result = s(:masgn, ary)
532
+ _, node, _, post = val
533
+
534
+ splat = s(:splat, node).line node.line
535
+ ary = s(:array, splat).line splat.line
536
+ ary.concat post.sexp_body
537
+ result = s(:masgn, ary).line ary.line
497
538
  }
498
539
  | tSTAR
499
540
  {
500
- result = s(:masgn, s(:array, s(:splat)))
541
+ l = lexer.lineno
542
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
501
543
  }
502
544
  | tSTAR tCOMMA mlhs_post
503
545
  {
504
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
546
+ _, _, post = val
547
+ l = post.line
548
+
549
+ splat = s(:splat).line l
550
+ ary = s(:array, splat, *post.sexp_body).line l
551
+ result = s(:masgn, ary).line l
505
552
  }
506
553
 
507
554
  mlhs_item: mlhs_node
@@ -512,7 +559,8 @@ rule
512
559
 
513
560
  mlhs_head: mlhs_item tCOMMA
514
561
  {
515
- result = s(:array, val[0])
562
+ lhs, _ = val
563
+ result = s(:array, lhs).line lhs.line
516
564
  }
517
565
  | mlhs_head mlhs_item tCOMMA
518
566
  {
@@ -521,7 +569,8 @@ rule
521
569
 
522
570
  mlhs_post: mlhs_item
523
571
  {
524
- result = s(:array, val[0])
572
+ item, = val
573
+ result = s(:array, item).line item.line
525
574
  }
526
575
  | mlhs_post tCOMMA mlhs_item
527
576
  {
@@ -546,7 +595,8 @@ rule
546
595
  }
547
596
  | primary_value tCOLON2 tIDENTIFIER
548
597
  {
549
- result = s(:attrasgn, val[0], :"#{val[2]}=")
598
+ recv, _, id = val
599
+ result = new_attrasgn recv, id
550
600
  }
551
601
  | primary_value call_op tCONSTANT
552
602
  {
@@ -559,7 +609,10 @@ rule
559
609
  yyerror "dynamic constant assignment"
560
610
  end
561
611
 
562
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
612
+ expr, _, id = val
613
+ l = expr.line
614
+
615
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
563
616
  }
564
617
  | tCOLON3 tCONSTANT
565
618
  {
@@ -568,7 +621,10 @@ rule
568
621
  yyerror "dynamic constant assignment"
569
622
  end
570
623
 
571
- result = s(:const, nil, s(:colon3, val[1].to_sym))
624
+ _, id = val
625
+ l = lexer.lineno
626
+
627
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
572
628
  }
573
629
  | backref
574
630
  {
@@ -577,24 +633,31 @@ rule
577
633
 
578
634
  lhs: user_variable
579
635
  {
636
+ line = lexer.lineno
580
637
  result = self.assignable val[0]
638
+ result.line = line
581
639
  }
582
640
  | keyword_variable
583
641
  {
642
+ line = lexer.lineno
584
643
  result = self.assignable val[0]
644
+ result.line = line
585
645
  debug20 9, val, result
586
646
  }
587
647
  | primary_value tLBRACK2 opt_call_args rbracket
588
648
  {
589
- result = self.aryset val[0], val[2]
649
+ lhs, _, args, _ = val
650
+ result = self.aryset lhs, args
590
651
  }
591
652
  | primary_value call_op tIDENTIFIER # REFACTOR
592
653
  {
593
- result = new_attrasgn val[0], val[2], val[1]
654
+ lhs, op, id = val
655
+ result = new_attrasgn lhs, id, op
594
656
  }
595
657
  | primary_value tCOLON2 tIDENTIFIER
596
658
  {
597
- result = s(:attrasgn, val[0], :"#{val[2]}=")
659
+ lhs, _, id = val
660
+ result = new_attrasgn lhs, id
598
661
  }
599
662
  | primary_value call_op tCONSTANT # REFACTOR?
600
663
  {
@@ -602,21 +665,27 @@ rule
602
665
  }
603
666
  | primary_value tCOLON2 tCONSTANT
604
667
  {
668
+ expr, _, id = val
669
+
605
670
  if (self.in_def || self.in_single > 0) then
606
671
  debug20 10
607
672
  yyerror "dynamic constant assignment"
608
673
  end
609
674
 
610
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
675
+ l = expr.line
676
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
611
677
  }
612
678
  | tCOLON3 tCONSTANT
613
679
  {
680
+ _, id = val
681
+
614
682
  if (self.in_def || self.in_single > 0) then
615
683
  debug20 11
616
684
  yyerror "dynamic constant assignment"
617
685
  end
618
686
 
619
- result = s(:const, s(:colon3, val[1].to_sym))
687
+ l = lexer.lineno
688
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
620
689
  }
621
690
  | backref
622
691
  {
@@ -631,7 +700,8 @@ rule
631
700
 
632
701
  cpath: tCOLON3 cname
633
702
  {
634
- result = s(:colon3, val[1].to_sym)
703
+ _, name = val
704
+ result = s(:colon3, name.to_sym).line lexer.lineno
635
705
  }
636
706
  | cname
637
707
  {
@@ -639,7 +709,10 @@ rule
639
709
  }
640
710
  | primary_value tCOLON2 cname
641
711
  {
642
- result = s(:colon2, val[0], val[2].to_sym)
712
+ pval, _, name = val
713
+
714
+ result = s(:colon2, pval, name.to_sym)
715
+ result.line pval.line
643
716
  }
644
717
 
645
718
  fname: tIDENTIFIER | tCONSTANT | tFID
@@ -660,7 +733,8 @@ rule
660
733
 
661
734
  fitem: fsym
662
735
  {
663
- result = s(:lit, val[0].to_sym)
736
+ id, = val
737
+ result = s(:lit, id.to_sym).line lexer.lineno
664
738
  }
665
739
  | dsym
666
740
 
@@ -684,6 +758,7 @@ rule
684
758
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
685
759
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
686
760
  #if V >= 20
761
+ # TODO: tUBANG dead?
687
762
  | tUBANG
688
763
  #endif
689
764
 
@@ -707,8 +782,7 @@ rule
707
782
  }
708
783
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
709
784
  {
710
- val[2].sexp_type = :arglist if val[2]
711
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
785
+ result = new_op_asgn1 val
712
786
  }
713
787
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
714
788
  {
@@ -720,7 +794,9 @@ rule
720
794
  }
721
795
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
722
796
  {
723
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
797
+ lhs, _, id, op, rhs = val
798
+
799
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
724
800
  }
725
801
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
726
802
  {
@@ -750,32 +826,34 @@ rule
750
826
  {
751
827
  v1, v2 = val[0], val[2]
752
828
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
753
- result = s(:lit, (v1.last)..(v2.last))
829
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
754
830
  else
755
- result = s(:dot2, v1, v2)
831
+ result = s(:dot2, v1, v2).line v1.line
756
832
  end
757
833
  }
758
834
  | arg tDOT3 arg
759
835
  {
760
836
  v1, v2 = val[0], val[2]
761
837
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
762
- result = s(:lit, (v1.last)...(v2.last))
838
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
763
839
  else
764
- result = s(:dot3, v1, v2)
840
+ result = s(:dot3, v1, v2).line v1.line
765
841
  end
766
842
  }
767
843
  #if V >= 26
768
844
  | arg tDOT2
769
845
  {
770
- v1, v2 = val[0], nil
846
+ v1, _ = val
847
+ v2 = nil
771
848
 
772
- result = s(:dot2, v1, v2)
849
+ result = s(:dot2, v1, v2).line v1.line
773
850
  }
774
851
  | arg tDOT3
775
852
  {
776
- v1, v2 = val[0], nil
853
+ v1, _ = val
854
+ v2 = nil
777
855
 
778
- result = s(:dot3, v1, v2)
856
+ result = s(:dot3, v1, v2).line v1.line
779
857
  }
780
858
  #endif
781
859
  | arg tPLUS arg
@@ -805,14 +883,17 @@ rule
805
883
  #if V == 20
806
884
  | tUMINUS_NUM tINTEGER tPOW arg
807
885
  {
808
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
886
+ lit = s(:lit, val[1]).line lexer.lineno
887
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
809
888
  }
810
889
  | tUMINUS_NUM tFLOAT tPOW arg
811
890
  #else
812
891
  | tUMINUS_NUM simple_numeric tPOW arg
813
892
  #endif
814
893
  {
815
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
894
+ lit = s(:lit, val[1]).line lexer.lineno
895
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
896
+
816
897
  #if V == 20
817
898
  ## TODO: why is this 2.0 only?
818
899
  debug20 12, val, result
@@ -857,15 +938,19 @@ rule
857
938
  }
858
939
  | arg tMATCH arg
859
940
  {
860
- result = new_match val[0], val[2]
941
+ lhs, _, rhs = val
942
+ result = new_match lhs, rhs
861
943
  }
862
944
  | arg tNMATCH arg
863
945
  {
864
- result = s(:not, new_match(val[0], val[2]))
946
+ lhs, _, rhs = val
947
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
865
948
  }
866
949
  | tBANG arg
867
950
  {
868
- result = new_call val[1], :"!"
951
+ _, arg = val
952
+ result = new_call arg, :"!"
953
+ result.line arg.line
869
954
  }
870
955
  | tTILDE arg
871
956
  {
@@ -893,11 +978,13 @@ rule
893
978
  }
894
979
  | kDEFINED opt_nl arg
895
980
  {
896
- result = s(:defined, val[2])
981
+ (_, line), _, arg = val
982
+ result = s(:defined, arg).line line
897
983
  }
898
984
  | arg tEH arg opt_nl tCOLON arg
899
985
  {
900
- result = s(:if, val[0], val[2], val[5])
986
+ c, _, t, _, _, f = val
987
+ result = s(:if, c, t, f).line c.line
901
988
  }
902
989
  | primary
903
990
 
@@ -940,28 +1027,25 @@ rule
940
1027
  arg_rhs: arg =tOP_ASGN
941
1028
  | arg kRESCUE_MOD arg
942
1029
  {
943
- body, _, resbody = val
1030
+ body, (_, line), resbody = val
944
1031
  body = value_expr body
945
1032
  resbody = remove_begin resbody
946
- result = new_rescue(body, new_resbody(s(:array), resbody))
1033
+
1034
+ ary = s(:array).line line
1035
+ result = new_rescue(body, new_resbody(ary, resbody))
947
1036
  }
948
1037
 
949
1038
  paren_args: tLPAREN2 opt_call_args rparen
950
1039
  {
951
- result = val[1]
1040
+ _, args, _ = val
1041
+ result = args
952
1042
  }
953
1043
 
954
1044
  opt_paren_args: none
955
1045
  | paren_args
956
1046
 
957
1047
  opt_call_args: none
958
- {
959
- result = val[0]
960
- }
961
1048
  | call_args
962
- {
963
- result = val[0]
964
- }
965
1049
  | args tCOMMA
966
1050
  {
967
1051
  result = args val
@@ -983,17 +1067,14 @@ rule
983
1067
  | args opt_block_arg
984
1068
  {
985
1069
  result = call_args val
986
- result = self.arg_blk_pass val[0], val[1]
987
1070
  }
988
1071
  | assocs opt_block_arg
989
1072
  {
990
- result = call_args [array_to_hash(val[0])]
991
- result = self.arg_blk_pass result, val[1]
1073
+ result = call_args [array_to_hash(val[0]), val[1]]
992
1074
  }
993
1075
  | args tCOMMA assocs opt_block_arg
994
1076
  {
995
- result = call_args [val[0], array_to_hash(val[2])]
996
- result = self.arg_blk_pass result, val[3]
1077
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
997
1078
  }
998
1079
  | block_arg
999
1080
  {
@@ -1001,17 +1082,45 @@ rule
1001
1082
  }
1002
1083
 
1003
1084
  command_args: {
1004
- result = lexer.cmdarg.store true
1085
+ # parse26.y line 2200
1086
+
1087
+ # If call_args starts with a open paren '(' or
1088
+ # '[', look-ahead reading of the letters calls
1089
+ # CMDARG_PUSH(0), but the push must be done
1090
+ # after CMDARG_PUSH(1). So this code makes them
1091
+ # consistent by first cancelling the premature
1092
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1093
+ # finally redoing CMDARG_PUSH(0).
1094
+
1095
+ result = yychar = self.last_token_type.first
1096
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1097
+ lexer.cmdarg.pop if lookahead
1098
+ lexer.cmdarg.push true
1099
+ lexer.cmdarg.push false if lookahead
1005
1100
  }
1006
1101
  call_args
1007
1102
  {
1008
- lexer.cmdarg.restore val[0]
1009
- result = val[1]
1103
+ yychar, args = val
1104
+
1105
+ # call_args can be followed by tLBRACE_ARG (that
1106
+ # does CMDARG_PUSH(0) in the lexer) but the push
1107
+ # must be done after CMDARG_POP() in the parser.
1108
+ # So this code does CMDARG_POP() to pop 0 pushed
1109
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1110
+ # by command_args, and CMDARG_PUSH(0) to restore
1111
+ # back the flag set by tLBRACE_ARG.
1112
+
1113
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1114
+ lexer.cmdarg.pop if lookahead
1115
+ lexer.cmdarg.pop
1116
+ lexer.cmdarg.push false if lookahead
1117
+ result = args
1010
1118
  }
1011
1119
 
1012
1120
  block_arg: tAMPER arg_value
1013
1121
  {
1014
- result = s(:block_pass, val[1])
1122
+ _, arg = val
1123
+ result = s(:block_pass, arg).line arg.line
1015
1124
  }
1016
1125
 
1017
1126
  opt_block_arg: tCOMMA block_arg
@@ -1022,19 +1131,27 @@ rule
1022
1131
 
1023
1132
  args: arg_value
1024
1133
  {
1025
- result = s(:array, val[0])
1134
+ arg, = val
1135
+ lineno = arg.line || lexer.lineno # HACK
1136
+
1137
+ result = s(:array, arg).line lineno
1026
1138
  }
1027
1139
  | tSTAR arg_value
1028
1140
  {
1029
- result = s(:array, s(:splat, val[1]))
1141
+ _, arg = val
1142
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1030
1143
  }
1031
1144
  | args tCOMMA arg_value
1032
1145
  {
1033
- result = self.list_append val[0], val[2]
1146
+ args, _, id = val
1147
+ result = self.list_append args, id
1034
1148
  }
1035
1149
  | args tCOMMA tSTAR arg_value
1036
1150
  {
1037
- result = self.list_append val[0], s(:splat, val[3])
1151
+ # TODO: the line number from tSTAR has been dropped
1152
+ args, _, _, id = val
1153
+ line = lexer.lineno
1154
+ result = self.list_append args, s(:splat, id).line(line)
1038
1155
  }
1039
1156
 
1040
1157
  #if V >= 21
@@ -1054,11 +1171,14 @@ rule
1054
1171
  }
1055
1172
  | args tCOMMA tSTAR arg_value
1056
1173
  {
1057
- result = self.arg_concat val[0], val[3]
1174
+ # TODO: make all tXXXX terminals include lexer.lineno
1175
+ arg, _, _, splat = val
1176
+ result = self.arg_concat arg, splat
1058
1177
  }
1059
1178
  | tSTAR arg_value
1060
1179
  {
1061
- result = s(:splat, val[1])
1180
+ _, arg = val
1181
+ result = s(:splat, arg).line arg.line
1062
1182
  }
1063
1183
 
1064
1184
  primary: literal
@@ -1073,65 +1193,65 @@ rule
1073
1193
  | backref
1074
1194
  | tFID
1075
1195
  {
1076
- result = new_call nil, val[0].to_sym
1196
+ msg, = val
1197
+ result = new_call nil, msg.to_sym
1077
1198
  }
1078
1199
  | k_begin
1079
1200
  {
1201
+ lexer.cmdarg.push false
1080
1202
  result = self.lexer.lineno
1081
- # TODO:
1082
- # $<val>1 = cmdarg_stack;
1083
- # CMDARG_SET(0);
1084
1203
  }
1085
1204
  bodystmt k_end
1086
1205
  {
1087
- # TODO: CMDARG_SET($<val>1);
1088
- unless val[2] then
1089
- result = s(:nil)
1090
- else
1091
- result = s(:begin, val[2])
1092
- end
1093
-
1094
- result.line = val[1]
1206
+ lexer.cmdarg.pop
1207
+ result = new_begin val
1095
1208
  }
1096
- | tLPAREN_ARG rparen
1209
+ | tLPAREN_ARG
1097
1210
  {
1098
- # TODO: lex_state = EXPR_ENDARG in between
1099
- debug20 13, val, result
1211
+ lexer.lex_state = EXPR_ENDARG
1212
+ result = lexer.lineno
1100
1213
  }
1101
- | tLPAREN_ARG
1214
+ rparen
1102
1215
  {
1103
- result = lexer.cmdarg.store false
1104
- # result = self.lexer.cmdarg.stack.dup
1105
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1216
+ _, line, _ = val
1217
+ result = s(:begin).line line
1106
1218
  }
1219
+ | tLPAREN_ARG
1107
1220
  stmt
1108
1221
  {
1109
1222
  lexer.lex_state = EXPR_ENDARG
1110
1223
  }
1111
1224
  rparen
1112
1225
  {
1113
- _, cmdarg, stmt, _, _, = val
1114
- warning "(...) interpreted as grouped expression"
1115
- lexer.cmdarg.restore cmdarg
1226
+ _, stmt, _, _, = val
1227
+ # warning "(...) interpreted as grouped expression"
1116
1228
  result = stmt
1117
1229
  }
1118
1230
  | tLPAREN compstmt tRPAREN
1119
1231
  {
1120
- result = val[1] || s(:nil)
1232
+ _, stmt, _ = val
1233
+ result = stmt
1234
+ result ||= s(:nil).line lexer.lineno
1121
1235
  result.paren = true
1122
1236
  }
1123
1237
  | primary_value tCOLON2 tCONSTANT
1124
1238
  {
1125
- result = s(:colon2, val[0], val[2].to_sym)
1239
+ expr, _, id = val
1240
+
1241
+ result = s(:colon2, expr, id.to_sym).line expr.line
1126
1242
  }
1127
1243
  | tCOLON3 tCONSTANT
1128
1244
  {
1129
- result = s(:colon3, val[1].to_sym)
1245
+ _, id = val
1246
+
1247
+ result = s(:colon3, id.to_sym).line lexer.lineno
1130
1248
  }
1131
- | tLBRACK aref_args tRBRACK
1249
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1132
1250
  {
1133
- result = val[1] || s(:array)
1251
+ _, line, args, _ = val
1252
+ result = args || s(:array)
1134
1253
  result.sexp_type = :array # aref_args is :args
1254
+ result.line line
1135
1255
  }
1136
1256
  | tLBRACE
1137
1257
  {
@@ -1143,7 +1263,8 @@ rule
1143
1263
  }
1144
1264
  | k_return
1145
1265
  {
1146
- result = s(:return)
1266
+ (_, line), = val
1267
+ result = s(:return).line line
1147
1268
  }
1148
1269
  | kYIELD tLPAREN2 call_args rparen
1149
1270
  {
@@ -1159,11 +1280,14 @@ rule
1159
1280
  }
1160
1281
  | kDEFINED opt_nl tLPAREN2 expr rparen
1161
1282
  {
1162
- result = s(:defined, val[3])
1283
+ (_, line), _, _, arg, _ = val
1284
+
1285
+ result = s(:defined, arg).line line
1163
1286
  }
1164
1287
  | kNOT tLPAREN2 expr rparen
1165
1288
  {
1166
- result = s(:call, val[2], :"!")
1289
+ _, _, lhs, _ = val
1290
+ result = new_call lhs, :"!"
1167
1291
  }
1168
1292
  | kNOT tLPAREN2 rparen
1169
1293
  {
@@ -1171,11 +1295,11 @@ rule
1171
1295
  }
1172
1296
  | fcall brace_block
1173
1297
  {
1174
- oper, iter = val[0], val[1]
1175
- call = oper # FIX
1298
+ call, iter = val
1299
+
1176
1300
  iter.insert 1, call
1177
1301
  result = iter
1178
- call.line = iter.line
1302
+ # FIX: probably not: call.line = iter.line
1179
1303
  }
1180
1304
  | method_call
1181
1305
  | method_call brace_block
@@ -1283,66 +1407,82 @@ rule
1283
1407
  }
1284
1408
  | k_def fname
1285
1409
  {
1286
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1410
+ result = self.in_def
1287
1411
 
1288
- self.comments.push self.lexer.comments
1289
- self.in_def = true
1412
+ self.in_def = true # group = local_push
1290
1413
  self.env.extend
1291
- # TODO: local->cmdargs = cmdarg_stack;
1292
- # TODO: port local_push_gen and local_pop_gen
1293
- lexer.cmdarg.stack.replace [false]
1414
+ lexer.cmdarg.push false
1415
+ lexer.cond.push false
1416
+
1417
+ self.comments.push self.lexer.comments
1294
1418
  }
1295
- f_arglist bodystmt k_end
1419
+ f_arglist bodystmt { result = lexer.lineno } k_end
1296
1420
  {
1297
- in_def, cmdarg = val[2]
1421
+ in_def = val[2]
1298
1422
 
1299
1423
  result = new_defn val
1300
1424
 
1301
- lexer.cmdarg.stack.replace cmdarg
1425
+ lexer.cond.pop # group = local_pop
1426
+ lexer.cmdarg.pop
1302
1427
  self.env.unextend
1303
1428
  self.in_def = in_def
1429
+
1304
1430
  self.lexer.comments # we don't care about comments in the body
1305
1431
  }
1306
1432
  | k_def singleton dot_or_colon
1307
1433
  {
1308
- self.comments.push self.lexer.comments
1309
1434
  lexer.lex_state = EXPR_FNAME
1310
1435
  }
1311
1436
  fname
1312
1437
  {
1313
- self.in_single += 1
1438
+ result = [self.in_def, lexer.lineno]
1439
+
1440
+ self.in_single += 1 # TODO: remove?
1441
+
1442
+ self.in_def = true # local_push
1314
1443
  self.env.extend
1315
- lexer.lex_state = EXPR_ENDFN # force for args
1316
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1317
- lexer.cmdarg.stack.replace [false]
1444
+ lexer.cmdarg.push false
1445
+ lexer.cond.push false
1446
+
1447
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1448
+ self.comments.push self.lexer.comments
1318
1449
  }
1319
1450
  f_arglist bodystmt k_end
1320
1451
  {
1321
- line, cmdarg = val[5]
1322
- result = new_defs val
1323
- result[3].line line
1452
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1324
1453
 
1325
- lexer.cmdarg.stack.replace cmdarg
1454
+ result = new_defs val
1326
1455
 
1456
+ lexer.cond.pop # group = local_pop
1457
+ lexer.cmdarg.pop
1327
1458
  self.env.unextend
1459
+ self.in_def = in_def
1460
+
1328
1461
  self.in_single -= 1
1462
+
1463
+ # TODO: restore cur_arg ? what's cur_arg?
1464
+
1329
1465
  self.lexer.comments # we don't care about comments in the body
1330
1466
  }
1331
1467
  | kBREAK
1332
1468
  {
1333
- result = s(:break)
1469
+ (_, line), = val
1470
+ result = s(:break).line line
1334
1471
  }
1335
1472
  | kNEXT
1336
1473
  {
1337
- result = s(:next)
1474
+ (_, line), = val
1475
+ result = s(:next).line line
1338
1476
  }
1339
1477
  | kREDO
1340
1478
  {
1341
- result = s(:redo)
1479
+ (_, line), = val
1480
+ result = s(:redo).line line
1342
1481
  }
1343
1482
  | kRETRY
1344
1483
  {
1345
- result = s(:retry)
1484
+ (_, line), = val
1485
+ result = s(:retry).line line
1346
1486
  }
1347
1487
 
1348
1488
  primary_value: primary
@@ -1381,7 +1521,9 @@ rule
1381
1521
  if_tail: opt_else
1382
1522
  | k_elsif expr_value then compstmt if_tail
1383
1523
  {
1384
- result = s(:if, val[1], val[3], val[4])
1524
+ (_, line), c, _, t, rest = val
1525
+
1526
+ result = s(:if, c, t, rest).line line
1385
1527
  }
1386
1528
 
1387
1529
  opt_else: none
@@ -1404,7 +1546,9 @@ rule
1404
1546
 
1405
1547
  f_marg_list: f_marg
1406
1548
  {
1407
- result = s(:array, val[0])
1549
+ sym, = val
1550
+
1551
+ result = s(:array, sym).line lexer.lineno
1408
1552
  }
1409
1553
  | f_marg_list tCOMMA f_marg
1410
1554
  {
@@ -1478,7 +1622,9 @@ rule
1478
1622
  }
1479
1623
  | f_block_arg
1480
1624
  {
1481
- result = call_args val
1625
+ line = lexer.lineno
1626
+ result = call_args val # TODO: push line down
1627
+ result.line line
1482
1628
  }
1483
1629
 
1484
1630
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1509,7 +1655,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1509
1655
  }
1510
1656
  | f_arg tCOMMA
1511
1657
  {
1512
- result = args val
1658
+ result = args(val) << nil
1513
1659
  }
1514
1660
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1515
1661
  {
@@ -1561,7 +1707,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1561
1707
  }
1562
1708
  | tOROP
1563
1709
  {
1564
- result = s(:args)
1710
+ result = s(:args).line lexer.lineno
1565
1711
  }
1566
1712
  | tPIPE block_param opt_bv_decl tPIPE
1567
1713
  {
@@ -1586,34 +1732,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1586
1732
 
1587
1733
  bvar: tIDENTIFIER
1588
1734
  {
1589
- result = s(:shadow, val[0].to_sym)
1735
+ id, = val
1736
+ line = lexer.lineno
1737
+ result = s(:shadow, id.to_sym).line line
1590
1738
  }
1591
1739
  | f_bad_arg
1592
1740
 
1593
1741
  lambda: {
1594
1742
  self.env.extend :dynamic
1595
- result = self.lexer.lineno
1596
-
1597
- result = lexer.lpar_beg
1743
+ result = [lexer.lineno, lexer.lpar_beg]
1598
1744
  lexer.paren_nest += 1
1599
1745
  lexer.lpar_beg = lexer.paren_nest
1600
1746
  }
1601
1747
  f_larglist
1602
1748
  {
1603
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1749
+ lexer.cmdarg.push false
1604
1750
  }
1605
1751
  lambda_body
1606
1752
  {
1607
- lpar, args, (cmdarg, lineno), body = val
1753
+ (line, lpar), args, _cmdarg, body = val
1608
1754
  lexer.lpar_beg = lpar
1609
1755
 
1610
- lexer.cmdarg.restore cmdarg
1611
- lexer.cmdarg.lexpop
1756
+ lexer.cmdarg.pop
1612
1757
 
1613
- call = new_call nil, :lambda
1758
+ call = s(:lambda).line line
1614
1759
  result = new_iter call, args, body
1615
- result.line = lineno
1616
- self.env.unextend
1760
+ result.line = line
1761
+ self.env.unextend # TODO: dynapush & dynapop
1617
1762
  }
1618
1763
 
1619
1764
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1637,8 +1782,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1637
1782
 
1638
1783
  do_block: k_do_block do_body kEND
1639
1784
  {
1640
- # TODO: maybe fix lineno to kDO's lineno?
1641
- result = val[1]
1785
+ (_, line), iter, _ = val
1786
+ result = iter.line line
1642
1787
  }
1643
1788
 
1644
1789
  block_call: command do_block
@@ -1652,8 +1797,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1652
1797
 
1653
1798
  val = invert_block_call val if inverted? val
1654
1799
 
1655
- result = val[1]
1656
- result.insert 1, val[0]
1800
+ cmd, blk = val
1801
+
1802
+ result = blk
1803
+ result.insert 1, cmd
1657
1804
  }
1658
1805
  | block_call call_op2 operation2 opt_paren_args
1659
1806
  {
@@ -1684,8 +1831,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1684
1831
  }
1685
1832
  paren_args
1686
1833
  {
1687
- args = self.call_args val[2..-1]
1688
- result = val[0].concat args.sexp_body
1834
+ call, lineno, args = val
1835
+
1836
+ result = call.concat args.sexp_body if args
1837
+ result.line lineno
1689
1838
  }
1690
1839
  | primary_value call_op operation2 opt_paren_args
1691
1840
  {
@@ -1713,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1713
1862
  }
1714
1863
  | kSUPER
1715
1864
  {
1716
- result = s(:zsuper)
1865
+ result = s(:zsuper).line lexer.lineno
1717
1866
  }
1718
1867
  | primary_value tLBRACK2 opt_call_args rbracket
1719
1868
  {
@@ -1762,7 +1911,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1762
1911
  }
1763
1912
 
1764
1913
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1765
- { result = lexer.cmdarg.store(false) }
1914
+ { lexer.cmdarg.push false }
1766
1915
  opt_block_param
1767
1916
  #if V >= 25
1768
1917
  bodystmt
@@ -1770,11 +1919,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1770
1919
  compstmt
1771
1920
  #endif
1772
1921
  {
1773
- line, cmdarg, param, cmpstmt = val
1922
+ line, _cmdarg, param, cmpstmt = val
1774
1923
 
1775
1924
  result = new_do_body param, cmpstmt, line
1925
+ lexer.cmdarg.pop
1776
1926
  self.env.unextend
1777
- lexer.cmdarg.restore cmdarg
1778
1927
  }
1779
1928
 
1780
1929
  case_body: k_when
@@ -1795,7 +1944,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1795
1944
  (_, line), klasses, var, _, body, rest = val
1796
1945
 
1797
1946
  klasses ||= s(:array)
1798
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1947
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1799
1948
  klasses.line line
1800
1949
 
1801
1950
  result = new_resbody(klasses, body)
@@ -1808,7 +1957,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1808
1957
 
1809
1958
  exc_list: arg_value
1810
1959
  {
1811
- result = s(:array, val[0])
1960
+ arg, = val
1961
+ result = s(:array, arg).line arg.line
1812
1962
  }
1813
1963
  | mrhs
1814
1964
  | none
@@ -1821,26 +1971,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1821
1971
 
1822
1972
  opt_ensure: k_ensure compstmt
1823
1973
  {
1824
- _, body = val
1974
+ (_, line), body = val
1825
1975
 
1826
- result = body || s(:nil)
1976
+ result = body || s(:nil).line(line)
1827
1977
  }
1828
1978
  | none
1829
1979
 
1830
1980
  literal: numeric
1831
1981
  {
1982
+ line = lexer.lineno
1832
1983
  result = s(:lit, val[0])
1984
+ result.line = line
1833
1985
  }
1834
1986
  | symbol
1835
1987
  {
1988
+ line = lexer.lineno
1836
1989
  result = s(:lit, val[0])
1990
+ result.line = line
1837
1991
  }
1838
1992
  | dsym
1839
1993
 
1840
1994
  strings: string
1841
1995
  {
1842
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1843
- result = val[0]
1996
+ str, = val
1997
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1998
+ result = str
1844
1999
  }
1845
2000
 
1846
2001
  string: tCHAR
@@ -1855,7 +2010,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
2010
 
1856
2011
  string1: tSTRING_BEG string_contents tSTRING_END
1857
2012
  {
1858
- result = val[1]
2013
+ _, str, (_, func) = val
2014
+
2015
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2016
+
2017
+ result = str
1859
2018
  }
1860
2019
  | tSTRING
1861
2020
  {
@@ -1864,7 +2023,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
2023
 
1865
2024
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1866
2025
  {
1867
- result = new_xstring val[1]
2026
+ result = new_xstring val
2027
+ # TODO: dedent?!?! SERIOUSLY?!?
1868
2028
  }
1869
2029
 
1870
2030
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1874,7 +2034,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1874
2034
 
1875
2035
  words: tWORDS_BEG tSPACE tSTRING_END
1876
2036
  {
1877
- result = s(:array)
2037
+ result = s(:array).line lexer.lineno
1878
2038
  }
1879
2039
  | tWORDS_BEG word_list tSTRING_END
1880
2040
  {
@@ -1898,25 +2058,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
2058
 
1899
2059
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1900
2060
  {
1901
- result = s(:array)
2061
+ result = s(:array).line lexer.lineno
1902
2062
  }
1903
- | tSYMBOLS_BEG symbol_list tSTRING_END
2063
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1904
2064
  {
1905
- result = val[1]
2065
+ _, line, list, _, = val
2066
+ list.line = line
2067
+ result = list
1906
2068
  }
1907
2069
 
1908
2070
  symbol_list: none
1909
2071
  {
1910
- result = new_symbol_list
2072
+ result = new_symbol_list.line lexer.lineno
1911
2073
  }
1912
2074
  | symbol_list word tSPACE
1913
2075
  {
1914
- result = val[0].dup << new_symbol_list_entry(val)
2076
+ list, * = val
2077
+ result = list.dup << new_symbol_list_entry(val)
1915
2078
  }
1916
2079
 
1917
2080
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1918
2081
  {
1919
- result = s(:array)
2082
+ result = s(:array).line lexer.lineno
1920
2083
  }
1921
2084
  | tQWORDS_BEG qword_list tSTRING_END
1922
2085
  {
@@ -1925,7 +2088,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1925
2088
 
1926
2089
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1927
2090
  {
1928
- result = s(:array)
2091
+ result = s(:array).line lexer.lineno # FIX
1929
2092
  }
1930
2093
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1931
2094
  {
@@ -1952,11 +2115,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1952
2115
 
1953
2116
  string_contents: none
1954
2117
  {
1955
- result = s(:str, "")
2118
+ result = s(:str, "").line lexer.lineno
1956
2119
  }
1957
2120
  | string_contents string_content
1958
2121
  {
1959
- result = literal_concat(val[0], val[1])
2122
+ v1, v2 = val
2123
+ result = literal_concat v1, v2
1960
2124
  }
1961
2125
 
1962
2126
  xstring_contents: none
@@ -1965,7 +2129,8 @@ xstring_contents: none
1965
2129
  }
1966
2130
  | xstring_contents string_content
1967
2131
  {
1968
- result = literal_concat(val[0], val[1])
2132
+ v1, v2 = val
2133
+ result = literal_concat v1, v2
1969
2134
  }
1970
2135
 
1971
2136
  regexp_contents: none
@@ -1974,7 +2139,8 @@ regexp_contents: none
1974
2139
  }
1975
2140
  | regexp_contents string_content
1976
2141
  {
1977
- result = literal_concat(val[0], val[1])
2142
+ v1, v2 = val
2143
+ result = literal_concat v1, v2
1978
2144
  }
1979
2145
 
1980
2146
  string_content: tSTRING_CONTENT
@@ -1990,19 +2156,22 @@ regexp_contents: none
1990
2156
  }
1991
2157
  string_dvar
1992
2158
  {
1993
- lexer.lex_strterm = val[1]
1994
- result = s(:evstr, val[2])
2159
+ _, strterm, str = val
2160
+ lexer.lex_strterm = strterm
2161
+ result = s(:evstr, str).line str.line
1995
2162
  }
1996
2163
  | tSTRING_DBEG
1997
2164
  {
1998
2165
  result = [lexer.lex_strterm,
1999
2166
  lexer.brace_nest,
2000
2167
  lexer.string_nest, # TODO: remove
2001
- lexer.cond.store,
2002
- lexer.cmdarg.store,
2003
2168
  lexer.lex_state,
2169
+ lexer.lineno,
2004
2170
  ]
2005
2171
 
2172
+ lexer.cmdarg.push false
2173
+ lexer.cond.push false
2174
+
2006
2175
  lexer.lex_strterm = nil
2007
2176
  lexer.brace_nest = 0
2008
2177
  lexer.string_nest = 0
@@ -2014,14 +2183,15 @@ regexp_contents: none
2014
2183
  {
2015
2184
  _, memo, stmt, _ = val
2016
2185
 
2017
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2186
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2187
+ # TODO: heredoc_indent
2018
2188
 
2019
2189
  lexer.lex_strterm = lex_strterm
2020
2190
  lexer.brace_nest = brace_nest
2021
2191
  lexer.string_nest = string_nest
2022
2192
 
2023
- lexer.cond.restore oldcond
2024
- lexer.cmdarg.restore oldcmdarg
2193
+ lexer.cmdarg.pop
2194
+ lexer.cond.pop
2025
2195
 
2026
2196
  lexer.lex_state = oldlex_state
2027
2197
 
@@ -2031,19 +2201,19 @@ regexp_contents: none
2031
2201
  when :str, :dstr, :evstr then
2032
2202
  result = stmt
2033
2203
  else
2034
- result = s(:evstr, stmt)
2204
+ result = s(:evstr, stmt).line line
2035
2205
  end
2036
2206
  when nil then
2037
- result = s(:evstr)
2207
+ result = s(:evstr).line line
2038
2208
  else
2039
2209
  debug20 25
2040
2210
  raise "unknown string body: #{stmt.inspect}"
2041
2211
  end
2042
2212
  }
2043
2213
 
2044
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
2045
- | tIVAR { result = s(:ivar, val[0].to_sym) }
2046
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2214
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2215
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2216
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2047
2217
  | backref
2048
2218
 
2049
2219
  symbol: tSYMBEG sym
@@ -2060,18 +2230,19 @@ regexp_contents: none
2060
2230
 
2061
2231
  dsym: tSYMBEG xstring_contents tSTRING_END
2062
2232
  {
2233
+ _, result, _ = val
2234
+
2063
2235
  lexer.lex_state = EXPR_END
2064
- result = val[1]
2065
2236
 
2066
- result ||= s(:str, "")
2237
+ result ||= s(:str, "").line lexer.lineno
2067
2238
 
2068
2239
  case result.sexp_type
2069
2240
  when :dstr then
2070
2241
  result.sexp_type = :dsym
2071
2242
  when :str then
2072
- result = s(:lit, result.last.to_sym)
2243
+ result = s(:lit, result.last.to_sym).line result.line
2073
2244
  when :evstr then
2074
- result = s(:dsym, "", result)
2245
+ result = s(:dsym, "", result).line result.line
2075
2246
  else
2076
2247
  debug20 26, val, result
2077
2248
  end
@@ -2108,19 +2279,20 @@ regexp_contents: none
2108
2279
  | tCONSTANT
2109
2280
  | tCVAR
2110
2281
 
2111
- keyword_variable: kNIL { result = s(:nil) }
2112
- | kSELF { result = s(:self) }
2113
- | kTRUE { result = s(:true) }
2114
- | kFALSE { result = s(:false) }
2115
- | k__FILE__ { result = s(:str, self.file) }
2116
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2282
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2283
+ | kSELF { result = s(:self).line lexer.lineno }
2284
+ | kTRUE { result = s(:true).line lexer.lineno }
2285
+ | kFALSE { result = s(:false).line lexer.lineno }
2286
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2287
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2117
2288
  | k__ENCODING__
2118
2289
  {
2290
+ l = lexer.lineno
2119
2291
  result =
2120
2292
  if defined? Encoding then
2121
- s(:colon2, s(:const, :Encoding), :UTF_8)
2293
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2122
2294
  else
2123
- s(:str, "Unsupported!")
2295
+ s(:str, "Unsupported!").line l
2124
2296
  end
2125
2297
  }
2126
2298
 
@@ -2145,8 +2317,8 @@ keyword_variable: kNIL { result = s(:nil) }
2145
2317
  debug20 29, val, result
2146
2318
  }
2147
2319
 
2148
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2149
- | tBACK_REF { result = s(:back_ref, val[0]) }
2320
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2321
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2150
2322
 
2151
2323
  superclass: tLT
2152
2324
  {
@@ -2311,12 +2483,13 @@ keyword_variable: kNIL { result = s(:nil) }
2311
2483
 
2312
2484
  f_arg: f_arg_item
2313
2485
  {
2314
- case val[0]
2486
+ arg, = val
2487
+
2488
+ case arg
2315
2489
  when Symbol then
2316
- result = s(:args)
2317
- result << val[0]
2490
+ result = s(:args, arg).line lexer.lineno
2318
2491
  when Sexp then
2319
- result = val[0]
2492
+ result = arg
2320
2493
  else
2321
2494
  debug20 32
2322
2495
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2329,7 +2502,7 @@ keyword_variable: kNIL { result = s(:nil) }
2329
2502
  if list.sexp_type == :args then
2330
2503
  result = list
2331
2504
  else
2332
- result = s(:args, list)
2505
+ result = s(:args, list).line list.line
2333
2506
  end
2334
2507
 
2335
2508
  result << item
@@ -2343,21 +2516,24 @@ keyword_variable: kNIL { result = s(:nil) }
2343
2516
  f_kw: f_label arg_value
2344
2517
  #endif
2345
2518
  {
2346
- # TODO: call_args
2347
- label, _ = val[0] # TODO: fix lineno?
2519
+ # TODO: new_kw_arg
2520
+ (label, line), arg = val
2521
+
2348
2522
  identifier = label.to_sym
2349
2523
  self.env[identifier] = :lvar
2350
2524
 
2351
- result = s(:array, s(:kwarg, identifier, val[1]))
2525
+ kwarg = s(:kwarg, identifier, arg).line line
2526
+ result = s(:array, kwarg).line line
2352
2527
  }
2353
2528
  #if V >= 21
2354
2529
  | f_label
2355
2530
  {
2356
- label, _ = val[0] # TODO: fix lineno?
2357
- identifier = label.to_sym
2358
- self.env[identifier] = :lvar
2531
+ (label, line), = val
2359
2532
 
2360
- result = s(:array, s(:kwarg, identifier))
2533
+ id = label.to_sym
2534
+ self.env[id] = :lvar
2535
+
2536
+ result = s(:array, s(:kwarg, id).line(line)).line line
2361
2537
  }
2362
2538
  #endif
2363
2539
 
@@ -2367,21 +2543,22 @@ keyword_variable: kNIL { result = s(:nil) }
2367
2543
  f_block_kw: f_label primary_value
2368
2544
  #endif
2369
2545
  {
2370
- # TODO: call_args
2371
- label, _ = val[0] # TODO: fix lineno?
2372
- identifier = label.to_sym
2373
- self.env[identifier] = :lvar
2546
+ # TODO: new_kw_arg
2547
+ (label, line), expr = val
2548
+ id = label.to_sym
2549
+ self.env[id] = :lvar
2374
2550
 
2375
- result = s(:array, s(:kwarg, identifier, val[1]))
2551
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2376
2552
  }
2377
2553
  #if V >= 21
2378
2554
  | f_label
2379
2555
  {
2380
- label, _ = val[0] # TODO: fix lineno?
2381
- identifier = label.to_sym
2382
- self.env[identifier] = :lvar
2556
+ # TODO: new_kw_arg
2557
+ (label, line), = val
2558
+ id = label.to_sym
2559
+ self.env[id] = :lvar
2383
2560
 
2384
- result = s(:array, s(:kwarg, identifier))
2561
+ result = s(:array, s(:kwarg, id).line(line)).line line
2385
2562
  }
2386
2563
  #endif
2387
2564
 
@@ -2437,17 +2614,20 @@ keyword_variable: kNIL { result = s(:nil) }
2437
2614
 
2438
2615
  f_block_optarg: f_block_opt
2439
2616
  {
2440
- result = s(:block, val[0])
2617
+ optblk, = val
2618
+ result = s(:block, optblk).line optblk.line
2441
2619
  }
2442
2620
  | f_block_optarg tCOMMA f_block_opt
2443
2621
  {
2444
- result = val[0]
2445
- result << val[2]
2622
+ optarg, _, optblk = val
2623
+ result = optarg
2624
+ result << optblk
2446
2625
  }
2447
2626
 
2448
2627
  f_optarg: f_opt
2449
2628
  {
2450
- result = s(:block, val[0])
2629
+ opt, = val
2630
+ result = s(:block, opt).line opt.line
2451
2631
  }
2452
2632
  | f_optarg tCOMMA f_opt
2453
2633
  {
@@ -2501,14 +2681,11 @@ keyword_variable: kNIL { result = s(:nil) }
2501
2681
  result.sexp_type == :lit
2502
2682
  }
2503
2683
 
2504
- assoc_list: none # [!nil]
2684
+ assoc_list: none
2505
2685
  {
2506
- result = s(:array)
2507
- }
2508
- | assocs trailer # [!nil]
2509
- {
2510
- result = val[0]
2686
+ result = s(:array).line lexer.lineno
2511
2687
  }
2688
+ | assocs trailer
2512
2689
 
2513
2690
  assocs: assoc
2514
2691
  | assocs tCOMMA assoc
@@ -2522,24 +2699,29 @@ keyword_variable: kNIL { result = s(:nil) }
2522
2699
 
2523
2700
  assoc: arg_value tASSOC arg_value
2524
2701
  {
2525
- result = s(:array, val[0], val[2])
2702
+ v1, _, v2 = val
2703
+ result = s(:array, v1, v2).line v1.line
2526
2704
  }
2527
2705
  | tLABEL arg_value
2528
2706
  {
2529
- (label, _), arg = val
2530
- result = s(:array, s(:lit, label.to_sym), arg)
2707
+ (label, line), arg = val
2708
+
2709
+ lit = s(:lit, label.to_sym).line line
2710
+ result = s(:array, lit, arg).line line
2531
2711
  }
2532
2712
  #if V >= 22
2533
2713
  | tSTRING_BEG string_contents tLABEL_END arg_value
2534
2714
  {
2535
2715
  _, sym, _, value = val
2536
2716
  sym.sexp_type = :dsym
2537
- result = s(:array, sym, value)
2717
+ result = s(:array, sym, value).line sym.line
2538
2718
  }
2539
2719
  #endif
2540
2720
  | tDSTAR arg_value
2541
2721
  {
2542
- result = s(:array, s(:kwsplat, val[1]))
2722
+ _, arg = val
2723
+ line = arg.line
2724
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2543
2725
  }
2544
2726
 
2545
2727
  operation: tIDENTIFIER | tCONSTANT | tFID