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