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