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