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