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