ruby_parser 3.12.0 → 3.18.1

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