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