ruby_parser 3.12.0 → 3.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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