ruby_parser 2.0.5 → 3.0.0.a1
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.
- data/.autotest +4 -4
- data/.gemtest +0 -0
- data/History.txt +124 -0
- data/Manifest.txt +6 -1
- data/README.txt +7 -6
- data/Rakefile +74 -27
- data/bin/ruby_parse +9 -1
- data/bin/ruby_parse_extract_error +75 -0
- data/lib/ruby18_parser.rb +5737 -0
- data/lib/{ruby_parser.y → ruby18_parser.y} +197 -124
- data/lib/ruby19_parser.rb +6147 -0
- data/lib/ruby19_parser.y +2014 -0
- data/lib/ruby_lexer.rb +146 -47
- data/lib/ruby_parser.rb +3 -5544
- data/lib/ruby_parser_extras.rb +392 -244
- data/test/test_ruby_lexer.rb +99 -15
- data/test/test_ruby_parser.rb +395 -130
- data/test/test_ruby_parser_extras.rb +10 -6
- data.tar.gz.sig +0 -0
- metadata +45 -39
- metadata.gz.sig +3 -1
data/lib/ruby_parser_extras.rb
CHANGED
|
@@ -3,10 +3,15 @@ require 'racc/parser'
|
|
|
3
3
|
require 'sexp'
|
|
4
4
|
require 'strscan'
|
|
5
5
|
|
|
6
|
+
def d o
|
|
7
|
+
$stderr.puts o.inspect
|
|
8
|
+
end
|
|
9
|
+
|
|
6
10
|
# WHY do I have to do this?!?
|
|
7
11
|
class Regexp
|
|
8
|
-
unless defined? ONCE
|
|
9
|
-
|
|
12
|
+
ONCE = 0 unless defined? ONCE # FIX: remove this - it makes no sense
|
|
13
|
+
|
|
14
|
+
unless defined? ENC_NONE then
|
|
10
15
|
ENC_NONE = /x/n.options
|
|
11
16
|
ENC_EUC = /x/e.options
|
|
12
17
|
ENC_SJIS = /x/s.options
|
|
@@ -29,36 +34,31 @@ class RPStringScanner < StringScanner
|
|
|
29
34
|
# old_getch
|
|
30
35
|
# end
|
|
31
36
|
# end
|
|
32
|
-
|
|
33
37
|
def current_line # HAHA fuck you (HACK)
|
|
34
38
|
string[0..pos][/\A.*__LINE__/m].split(/\n/).size
|
|
35
39
|
end
|
|
36
40
|
|
|
41
|
+
def extra_lines_added
|
|
42
|
+
@extra_lines_added ||= 0
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def extra_lines_added= val
|
|
46
|
+
@extra_lines_added = val
|
|
47
|
+
end
|
|
48
|
+
|
|
37
49
|
def lineno
|
|
38
|
-
string[0...pos].count("\n") + 1
|
|
50
|
+
string[0...pos].count("\n") + 1 - extra_lines_added
|
|
39
51
|
end
|
|
40
52
|
|
|
41
53
|
# TODO: once we get rid of these, we can make things like
|
|
42
54
|
# TODO: current_line and lineno much more accurate and easy to do
|
|
43
|
-
def unread c # TODO: remove this entirely - we should not need it
|
|
44
|
-
return if c.nil? # UGH
|
|
45
|
-
warn({:unread => caller[0]}.inspect) if ENV['TALLY']
|
|
46
|
-
string[pos, 0] = c
|
|
47
|
-
end
|
|
48
55
|
|
|
49
56
|
def unread_many str # TODO: remove this entirely - we should not need it
|
|
50
57
|
warn({:unread_many => caller[0]}.inspect) if ENV['TALLY']
|
|
58
|
+
self.extra_lines_added += str.count("\n")
|
|
51
59
|
string[pos, 0] = str
|
|
52
60
|
end
|
|
53
61
|
|
|
54
|
-
def begin_of_line?
|
|
55
|
-
pos == 0 or string[pos-1] == ?\n
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def was_begin_of_line # TODO: kill me
|
|
59
|
-
pos <= 2 or string[pos-2] == ?\n
|
|
60
|
-
end
|
|
61
|
-
|
|
62
62
|
if ENV['DEBUG'] then
|
|
63
63
|
alias :old_getch :getch
|
|
64
64
|
def getch
|
|
@@ -70,7 +70,7 @@ class RPStringScanner < StringScanner
|
|
|
70
70
|
alias :old_scan :scan
|
|
71
71
|
def scan re
|
|
72
72
|
s = old_scan re
|
|
73
|
-
|
|
73
|
+
d :scan => [s, caller.first] if s
|
|
74
74
|
s
|
|
75
75
|
end
|
|
76
76
|
end
|
|
@@ -114,21 +114,12 @@ class RPStringScanner < StringScanner
|
|
|
114
114
|
# end
|
|
115
115
|
end
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
VERSION = '
|
|
117
|
+
module RubyParserStuff
|
|
118
|
+
VERSION = '3.0.0.a1' unless constants.include? "VERSION" # SIGH
|
|
119
119
|
|
|
120
120
|
attr_accessor :lexer, :in_def, :in_single, :file
|
|
121
121
|
attr_reader :env, :comments
|
|
122
122
|
|
|
123
|
-
def append_to_block head, tail # FIX: wtf is this?!? switch to block_append
|
|
124
|
-
return head if tail.nil?
|
|
125
|
-
return tail if head.nil?
|
|
126
|
-
|
|
127
|
-
head = s(:block, head) unless head.node_type == :block
|
|
128
|
-
head << tail
|
|
129
|
-
head
|
|
130
|
-
end
|
|
131
|
-
|
|
132
123
|
def arg_add(node1, node2) # TODO: nuke
|
|
133
124
|
return s(:arglist, node2) unless node1
|
|
134
125
|
|
|
@@ -150,7 +141,32 @@ class RubyParser < Racc::Parser
|
|
|
150
141
|
node1
|
|
151
142
|
end
|
|
152
143
|
|
|
153
|
-
def
|
|
144
|
+
def block_var ary, splat, block
|
|
145
|
+
ary ||= s(:array)
|
|
146
|
+
|
|
147
|
+
if splat then
|
|
148
|
+
if splat == s(:splat) then
|
|
149
|
+
ary << splat
|
|
150
|
+
else
|
|
151
|
+
ary << s(:splat, splat)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if block then
|
|
156
|
+
block[-1] = :"&#{block[-1]}"
|
|
157
|
+
ary << block
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
result = if ary.length > 2 or ary.splat then
|
|
161
|
+
s(:masgn, ary)
|
|
162
|
+
else
|
|
163
|
+
ary.last
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
result
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def args arg, optarg, rest_arg, block_arg, post_arg = nil
|
|
154
170
|
arg ||= s(:args)
|
|
155
171
|
|
|
156
172
|
result = arg
|
|
@@ -162,15 +178,53 @@ class RubyParser < Racc::Parser
|
|
|
162
178
|
end
|
|
163
179
|
|
|
164
180
|
result << rest_arg if rest_arg
|
|
181
|
+
|
|
165
182
|
result << :"&#{block_arg.last}" if block_arg
|
|
166
183
|
result << optarg if optarg # TODO? huh - processed above as well
|
|
184
|
+
post_arg[1..-1].each {|pa| result << pa } if post_arg
|
|
185
|
+
|
|
186
|
+
result
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def args19 vals # TODO: migrate to args once 1.8 tests pass as well
|
|
190
|
+
result = s(:args)
|
|
191
|
+
block = nil
|
|
192
|
+
|
|
193
|
+
vals.each do |val|
|
|
194
|
+
case val
|
|
195
|
+
when Sexp then
|
|
196
|
+
case val.first
|
|
197
|
+
when :args then
|
|
198
|
+
val[1..-1].each do |name|
|
|
199
|
+
result << name
|
|
200
|
+
end
|
|
201
|
+
when :block_arg then
|
|
202
|
+
result << :"&#{val.last}"
|
|
203
|
+
when :block then
|
|
204
|
+
block = val
|
|
205
|
+
val[1..-1].each do |lasgn| # FIX clean sexp iter
|
|
206
|
+
raise "wtf? #{val.inspect}" unless lasgn[0] == :lasgn
|
|
207
|
+
result << lasgn[1]
|
|
208
|
+
end
|
|
209
|
+
else
|
|
210
|
+
raise "unhandled sexp: #{val.inspect}"
|
|
211
|
+
end
|
|
212
|
+
when Symbol then
|
|
213
|
+
result << val
|
|
214
|
+
when ",", nil then
|
|
215
|
+
# ignore
|
|
216
|
+
else
|
|
217
|
+
raise "unhandled val: #{val.inspect} in #{vals.inspect}"
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
result << block if block
|
|
167
222
|
|
|
168
223
|
result
|
|
169
224
|
end
|
|
170
225
|
|
|
171
226
|
def aryset receiver, index
|
|
172
|
-
|
|
173
|
-
s(:attrasgn, receiver, :"[]=", index)
|
|
227
|
+
s(:attrasgn, receiver, :"[]=", *index[1..-1])
|
|
174
228
|
end
|
|
175
229
|
|
|
176
230
|
def assignable(lhs, value = nil)
|
|
@@ -217,9 +271,9 @@ class RubyParser < Racc::Parser
|
|
|
217
271
|
return result
|
|
218
272
|
end
|
|
219
273
|
|
|
220
|
-
def block_append(head, tail
|
|
221
|
-
return head
|
|
222
|
-
return tail
|
|
274
|
+
def block_append(head, tail)
|
|
275
|
+
return head if tail.nil?
|
|
276
|
+
return tail if head.nil?
|
|
223
277
|
|
|
224
278
|
case head[0]
|
|
225
279
|
when :lit, :str then
|
|
@@ -229,16 +283,10 @@ class RubyParser < Racc::Parser
|
|
|
229
283
|
line = [head.line, tail.line].compact.min
|
|
230
284
|
|
|
231
285
|
head = remove_begin(head)
|
|
232
|
-
head = s(:block, head) unless head
|
|
233
|
-
|
|
234
|
-
if strip_tail_block and Sexp === tail and tail[0] == :block then
|
|
235
|
-
head.push(*tail.values)
|
|
236
|
-
else
|
|
237
|
-
head << tail
|
|
238
|
-
end
|
|
286
|
+
head = s(:block, head) unless head.node_type == :block
|
|
239
287
|
|
|
240
288
|
head.line = line
|
|
241
|
-
head
|
|
289
|
+
head << tail
|
|
242
290
|
end
|
|
243
291
|
|
|
244
292
|
def cond node
|
|
@@ -295,20 +343,11 @@ class RubyParser < Racc::Parser
|
|
|
295
343
|
end
|
|
296
344
|
end
|
|
297
345
|
|
|
298
|
-
return
|
|
346
|
+
return new_call(lhs, :"=~", argl(rhs)).line(lhs.line)
|
|
299
347
|
end
|
|
300
348
|
|
|
301
349
|
def gettable(id)
|
|
302
|
-
|
|
303
|
-
id = id.to_sym if Sexp === id # HACK
|
|
304
|
-
id = id.to_sym if String === id # HACK
|
|
305
|
-
|
|
306
|
-
return s(:self) if id == :self
|
|
307
|
-
return s(:nil) if id == :nil
|
|
308
|
-
return s(:true) if id == :true
|
|
309
|
-
return s(:false) if id == :false
|
|
310
|
-
return s(:str, self.file) if id == :"__FILE__"
|
|
311
|
-
return s(:lit, lexer.src.current_line) if id == :"__LINE__"
|
|
350
|
+
id = id.to_sym if String === id
|
|
312
351
|
|
|
313
352
|
result = case id.to_s
|
|
314
353
|
when /^@@/ then
|
|
@@ -323,25 +362,38 @@ class RubyParser < Racc::Parser
|
|
|
323
362
|
type = env[id]
|
|
324
363
|
if type then
|
|
325
364
|
s(type, id)
|
|
326
|
-
elsif env.dynamic? and :dvar == env[id] then
|
|
327
|
-
s(:lvar, id)
|
|
328
365
|
else
|
|
329
|
-
|
|
366
|
+
new_call(nil, id)
|
|
330
367
|
end
|
|
331
368
|
end
|
|
332
369
|
|
|
333
|
-
|
|
370
|
+
raise "identifier #{id.inspect} is not valid" unless result
|
|
334
371
|
|
|
335
|
-
|
|
372
|
+
result
|
|
336
373
|
end
|
|
337
374
|
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
375
|
+
##
|
|
376
|
+
# Canonicalize conditionals. Eg:
|
|
377
|
+
#
|
|
378
|
+
# not x ? a : b
|
|
379
|
+
#
|
|
380
|
+
# becomes:
|
|
381
|
+
#
|
|
382
|
+
# x ? b : a
|
|
383
|
+
|
|
384
|
+
attr_accessor :canonicalize_conditions
|
|
385
|
+
|
|
386
|
+
def initialize(options = {})
|
|
387
|
+
super()
|
|
388
|
+
|
|
389
|
+
v = self.class.name[/1[89]/]
|
|
390
|
+
self.lexer = RubyLexer.new v && v.to_i
|
|
341
391
|
self.lexer.parser = self
|
|
342
392
|
@env = Environment.new
|
|
343
393
|
@comments = []
|
|
344
394
|
|
|
395
|
+
@canonicalize_conditions = true
|
|
396
|
+
|
|
345
397
|
self.reset
|
|
346
398
|
end
|
|
347
399
|
|
|
@@ -456,14 +508,37 @@ class RubyParser < Racc::Parser
|
|
|
456
508
|
return result
|
|
457
509
|
end
|
|
458
510
|
|
|
511
|
+
def argl x
|
|
512
|
+
x = s(:arglist, x) if x and x[0] != :arglist
|
|
513
|
+
x
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def backref_assign_error ref
|
|
517
|
+
# TODO: need a test for this... obviously
|
|
518
|
+
case ref.first
|
|
519
|
+
when :nth_ref then
|
|
520
|
+
raise SyntaxError, "Can't set variable %p" % ref.last
|
|
521
|
+
when :back_ref then
|
|
522
|
+
raise SyntaxError, "Can't set back reference %p" % ref.last
|
|
523
|
+
else
|
|
524
|
+
raise "Unknown backref type: #{ref.inspect}"
|
|
525
|
+
end
|
|
526
|
+
end
|
|
527
|
+
|
|
459
528
|
def new_call recv, meth, args = nil
|
|
460
529
|
result = s(:call, recv, meth)
|
|
461
530
|
result.line = recv.line if recv
|
|
462
531
|
|
|
532
|
+
# TODO: need a test with f(&b) to produce block_pass
|
|
533
|
+
# TODO: need a test with f(&b) { } to produce warning
|
|
534
|
+
|
|
463
535
|
args ||= s(:arglist)
|
|
464
536
|
args[0] = :arglist if args.first == :array
|
|
465
537
|
args = s(:arglist, args) unless args.first == :arglist
|
|
466
|
-
|
|
538
|
+
|
|
539
|
+
# HACK quick hack to make this work quickly... easy to clean up above
|
|
540
|
+
result.concat args[1..-1]
|
|
541
|
+
|
|
467
542
|
result
|
|
468
543
|
end
|
|
469
544
|
|
|
@@ -476,6 +551,11 @@ class RubyParser < Racc::Parser
|
|
|
476
551
|
body = body.delete_at 3
|
|
477
552
|
end
|
|
478
553
|
|
|
554
|
+
result[2..-1].each do |node|
|
|
555
|
+
block = node.block(:delete)
|
|
556
|
+
node.concat block[1..-1] if block
|
|
557
|
+
end
|
|
558
|
+
|
|
479
559
|
# else
|
|
480
560
|
body = nil if body == s(:block)
|
|
481
561
|
result << body
|
|
@@ -486,8 +566,17 @@ class RubyParser < Racc::Parser
|
|
|
486
566
|
|
|
487
567
|
def new_class val
|
|
488
568
|
line, path, superclass, body = val[1], val[2], val[3], val[5]
|
|
489
|
-
|
|
490
|
-
result = s(:class, path, superclass
|
|
569
|
+
|
|
570
|
+
result = s(:class, path, superclass)
|
|
571
|
+
|
|
572
|
+
if body then
|
|
573
|
+
if body.first == :block then
|
|
574
|
+
result.push(*body[1..-1])
|
|
575
|
+
else
|
|
576
|
+
result.push body
|
|
577
|
+
end
|
|
578
|
+
end
|
|
579
|
+
|
|
491
580
|
result.line = line
|
|
492
581
|
result.comments = self.comments.pop
|
|
493
582
|
result
|
|
@@ -500,15 +589,20 @@ class RubyParser < Racc::Parser
|
|
|
500
589
|
end
|
|
501
590
|
|
|
502
591
|
def new_defn val
|
|
503
|
-
(
|
|
592
|
+
(_, line), name, args, body = val[0], val[1], val[3], val[4]
|
|
504
593
|
body ||= s(:nil)
|
|
505
594
|
|
|
506
|
-
|
|
507
|
-
|
|
595
|
+
result = s(:defn, name.to_sym, args)
|
|
596
|
+
|
|
597
|
+
if body then
|
|
598
|
+
if body.first == :block then
|
|
599
|
+
result.push(*body[1..-1])
|
|
600
|
+
else
|
|
601
|
+
result.push body
|
|
602
|
+
end
|
|
603
|
+
end
|
|
508
604
|
|
|
509
|
-
result = s(:defn, name.to_sym, args, s(:scope, body))
|
|
510
605
|
result.line = line
|
|
511
|
-
result.line -= 1 if bol
|
|
512
606
|
result.comments = self.comments.pop
|
|
513
607
|
result
|
|
514
608
|
end
|
|
@@ -516,10 +610,16 @@ class RubyParser < Racc::Parser
|
|
|
516
610
|
def new_defs val
|
|
517
611
|
recv, name, args, body = val[1], val[4], val[6], val[7]
|
|
518
612
|
|
|
519
|
-
|
|
520
|
-
|
|
613
|
+
result = s(:defs, recv, name.to_sym, args)
|
|
614
|
+
|
|
615
|
+
if body then
|
|
616
|
+
if body.first == :block then
|
|
617
|
+
result.push(*body[1..-1])
|
|
618
|
+
else
|
|
619
|
+
result.push body
|
|
620
|
+
end
|
|
621
|
+
end
|
|
521
622
|
|
|
522
|
-
result = s(:defs, recv, name.to_sym, args, s(:scope, body))
|
|
523
623
|
result.line = recv.line
|
|
524
624
|
result.comments = self.comments.pop
|
|
525
625
|
result
|
|
@@ -534,7 +634,7 @@ class RubyParser < Racc::Parser
|
|
|
534
634
|
def new_if c, t, f
|
|
535
635
|
l = [c.line, t && t.line, f && f.line].compact.min
|
|
536
636
|
c = cond c
|
|
537
|
-
c, t, f = c.last, f, t if c[0] == :not
|
|
637
|
+
c, t, f = c.last, f, t if c[0] == :not and canonicalize_conditions
|
|
538
638
|
s(:if, c, t, f).line(l)
|
|
539
639
|
end
|
|
540
640
|
|
|
@@ -559,7 +659,7 @@ class RubyParser < Racc::Parser
|
|
|
559
659
|
def new_module val
|
|
560
660
|
line, path, body = val[1], val[2], val[4]
|
|
561
661
|
body = s(:scope, body).compact
|
|
562
|
-
result = s(:module, path, body)
|
|
662
|
+
result = s(:module, path, *body[1..-1])
|
|
563
663
|
result.line = line
|
|
564
664
|
result.comments = self.comments.pop
|
|
565
665
|
result
|
|
@@ -578,8 +678,7 @@ class RubyParser < Racc::Parser
|
|
|
578
678
|
s(:op_asgn_and, self.gettable(name), lhs)
|
|
579
679
|
else
|
|
580
680
|
# TODO: why [2] ?
|
|
581
|
-
lhs[2] = new_call(self.gettable(name), asgn_op,
|
|
582
|
-
s(:arglist, arg))
|
|
681
|
+
lhs[2] = new_call(self.gettable(name), asgn_op, argl(arg))
|
|
583
682
|
lhs
|
|
584
683
|
end
|
|
585
684
|
result.line = lhs.line
|
|
@@ -631,10 +730,28 @@ class RubyParser < Racc::Parser
|
|
|
631
730
|
node
|
|
632
731
|
end
|
|
633
732
|
|
|
733
|
+
def new_resbody cond, body
|
|
734
|
+
if body && body.first == :block then
|
|
735
|
+
body.shift # remove block and splat it in directly
|
|
736
|
+
else
|
|
737
|
+
body = [body]
|
|
738
|
+
end
|
|
739
|
+
s(:resbody, cond, *body)
|
|
740
|
+
end
|
|
741
|
+
|
|
634
742
|
def new_sclass val
|
|
635
743
|
recv, in_def, in_single, body = val[3], val[4], val[6], val[7]
|
|
636
|
-
|
|
637
|
-
result = s(:sclass, recv
|
|
744
|
+
|
|
745
|
+
result = s(:sclass, recv)
|
|
746
|
+
|
|
747
|
+
if body then
|
|
748
|
+
if body.first == :block then
|
|
749
|
+
result.push(*body[1..-1])
|
|
750
|
+
else
|
|
751
|
+
result.push body
|
|
752
|
+
end
|
|
753
|
+
end
|
|
754
|
+
|
|
638
755
|
result.line = val[2]
|
|
639
756
|
self.in_def = in_def
|
|
640
757
|
self.in_single = in_single
|
|
@@ -659,25 +776,34 @@ class RubyParser < Racc::Parser
|
|
|
659
776
|
end
|
|
660
777
|
|
|
661
778
|
def new_until block, expr, pre
|
|
662
|
-
|
|
663
|
-
new_while block, expr, pre
|
|
779
|
+
new_until_or_while :until, block, expr, pre
|
|
664
780
|
end
|
|
665
781
|
|
|
666
|
-
def
|
|
782
|
+
def new_until_or_while type, block, expr, pre
|
|
783
|
+
other = type == :until ? :while : :until
|
|
667
784
|
line = [block && block.line, expr.line].compact.min
|
|
668
785
|
block, pre = block.last, false if block && block[0] == :begin
|
|
669
786
|
|
|
670
787
|
expr = cond expr
|
|
671
|
-
|
|
672
|
-
|
|
788
|
+
|
|
789
|
+
result = unless expr.first == :not and canonicalize_conditions then
|
|
790
|
+
s(type, expr, block, pre)
|
|
673
791
|
else
|
|
674
|
-
s(
|
|
792
|
+
s(other, expr.last, block, pre)
|
|
675
793
|
end
|
|
676
794
|
|
|
677
795
|
result.line = line
|
|
678
796
|
result
|
|
679
797
|
end
|
|
680
798
|
|
|
799
|
+
def new_when cond, body
|
|
800
|
+
s(:when, cond, body)
|
|
801
|
+
end
|
|
802
|
+
|
|
803
|
+
def new_while block, expr, pre
|
|
804
|
+
new_until_or_while :while, block, expr, pre
|
|
805
|
+
end
|
|
806
|
+
|
|
681
807
|
def new_xstring str
|
|
682
808
|
if str then
|
|
683
809
|
case str[0]
|
|
@@ -722,12 +848,11 @@ class RubyParser < Racc::Parser
|
|
|
722
848
|
rhs = value_expr rhs
|
|
723
849
|
|
|
724
850
|
case lhs[0]
|
|
725
|
-
when :gasgn, :iasgn, :lasgn, :
|
|
726
|
-
:masgn, :cdecl, :cvdecl, :cvasgn then
|
|
851
|
+
when :gasgn, :iasgn, :lasgn, :masgn, :cdecl, :cvdecl, :cvasgn then
|
|
727
852
|
lhs << rhs
|
|
728
853
|
when :attrasgn, :call then
|
|
729
854
|
args = lhs.pop unless Symbol === lhs.last
|
|
730
|
-
lhs
|
|
855
|
+
lhs.concat arg_add(args, rhs)[1..-1]
|
|
731
856
|
when :const then
|
|
732
857
|
lhs[0] = :cdecl
|
|
733
858
|
lhs << rhs
|
|
@@ -742,7 +867,7 @@ class RubyParser < Racc::Parser
|
|
|
742
867
|
raise "bad val: #{str.inspect}" unless String === str
|
|
743
868
|
|
|
744
869
|
self.file = file
|
|
745
|
-
self.lexer.src = str
|
|
870
|
+
self.lexer.src = str.dup
|
|
746
871
|
|
|
747
872
|
@yydebug = ENV.has_key? 'DEBUG'
|
|
748
873
|
|
|
@@ -808,192 +933,207 @@ class RubyParser < Racc::Parser
|
|
|
808
933
|
# do nothing for now
|
|
809
934
|
end
|
|
810
935
|
|
|
811
|
-
alias :old_yyerror :yyerror
|
|
812
936
|
def yyerror msg
|
|
813
937
|
# for now do nothing with the msg
|
|
814
|
-
|
|
938
|
+
super
|
|
815
939
|
end
|
|
816
|
-
end
|
|
817
940
|
|
|
818
|
-
class Keyword
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
941
|
+
class Keyword
|
|
942
|
+
class KWtable
|
|
943
|
+
attr_accessor :name, :state, :id0, :id1
|
|
944
|
+
def initialize(name, id=[], state=nil)
|
|
945
|
+
@name = name
|
|
946
|
+
@id0, @id1 = id
|
|
947
|
+
@state = state
|
|
948
|
+
end
|
|
825
949
|
end
|
|
826
|
-
end
|
|
827
950
|
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
951
|
+
##
|
|
952
|
+
# :stopdoc:
|
|
953
|
+
#
|
|
954
|
+
# :expr_beg = ignore newline, +/- is a sign.
|
|
955
|
+
# :expr_end = newline significant, +/- is a operator.
|
|
956
|
+
# :expr_arg = newline significant, +/- is a operator.
|
|
957
|
+
# :expr_cmdarg = newline significant, +/- is a operator.
|
|
958
|
+
# :expr_endarg = newline significant, +/- is a operator.
|
|
959
|
+
# :expr_mid = newline significant, +/- is a operator.
|
|
960
|
+
# :expr_fname = ignore newline, no reserved words.
|
|
961
|
+
# :expr_dot = right after . or ::, no reserved words.
|
|
962
|
+
# :expr_class = immediate after class, no here document.
|
|
963
|
+
|
|
964
|
+
wordlist = [
|
|
965
|
+
["end", [:kEND, :kEND ], :expr_end ],
|
|
966
|
+
["else", [:kELSE, :kELSE ], :expr_beg ],
|
|
967
|
+
["case", [:kCASE, :kCASE ], :expr_beg ],
|
|
968
|
+
["ensure", [:kENSURE, :kENSURE ], :expr_beg ],
|
|
969
|
+
["module", [:kMODULE, :kMODULE ], :expr_beg ],
|
|
970
|
+
["elsif", [:kELSIF, :kELSIF ], :expr_beg ],
|
|
971
|
+
["def", [:kDEF, :kDEF ], :expr_fname ],
|
|
972
|
+
["rescue", [:kRESCUE, :kRESCUE_MOD ], :expr_mid ],
|
|
973
|
+
["not", [:kNOT, :kNOT ], :expr_beg ],
|
|
974
|
+
["then", [:kTHEN, :kTHEN ], :expr_beg ],
|
|
975
|
+
["yield", [:kYIELD, :kYIELD ], :expr_arg ],
|
|
976
|
+
["for", [:kFOR, :kFOR ], :expr_beg ],
|
|
977
|
+
["self", [:kSELF, :kSELF ], :expr_end ],
|
|
978
|
+
["false", [:kFALSE, :kFALSE ], :expr_end ],
|
|
979
|
+
["retry", [:kRETRY, :kRETRY ], :expr_end ],
|
|
980
|
+
["return", [:kRETURN, :kRETURN ], :expr_mid ],
|
|
981
|
+
["true", [:kTRUE, :kTRUE ], :expr_end ],
|
|
982
|
+
["if", [:kIF, :kIF_MOD ], :expr_beg ],
|
|
983
|
+
["defined?", [:kDEFINED, :kDEFINED ], :expr_arg ],
|
|
984
|
+
["super", [:kSUPER, :kSUPER ], :expr_arg ],
|
|
985
|
+
["undef", [:kUNDEF, :kUNDEF ], :expr_fname ],
|
|
986
|
+
["break", [:kBREAK, :kBREAK ], :expr_mid ],
|
|
987
|
+
["in", [:kIN, :kIN ], :expr_beg ],
|
|
988
|
+
["do", [:kDO, :kDO ], :expr_beg ],
|
|
989
|
+
["nil", [:kNIL, :kNIL ], :expr_end ],
|
|
990
|
+
["until", [:kUNTIL, :kUNTIL_MOD ], :expr_beg ],
|
|
991
|
+
["unless", [:kUNLESS, :kUNLESS_MOD ], :expr_beg ],
|
|
992
|
+
["or", [:kOR, :kOR ], :expr_beg ],
|
|
993
|
+
["next", [:kNEXT, :kNEXT ], :expr_mid ],
|
|
994
|
+
["when", [:kWHEN, :kWHEN ], :expr_beg ],
|
|
995
|
+
["redo", [:kREDO, :kREDO ], :expr_end ],
|
|
996
|
+
["and", [:kAND, :kAND ], :expr_beg ],
|
|
997
|
+
["begin", [:kBEGIN, :kBEGIN ], :expr_beg ],
|
|
998
|
+
["__LINE__", [:k__LINE__, :k__LINE__ ], :expr_end ],
|
|
999
|
+
["class", [:kCLASS, :kCLASS ], :expr_class ],
|
|
1000
|
+
["__FILE__", [:k__FILE__, :k__FILE__ ], :expr_end ],
|
|
1001
|
+
["END", [:klEND, :klEND ], :expr_end ],
|
|
1002
|
+
["BEGIN", [:klBEGIN, :klBEGIN ], :expr_end ],
|
|
1003
|
+
["while", [:kWHILE, :kWHILE_MOD ], :expr_beg ],
|
|
1004
|
+
["alias", [:kALIAS, :kALIAS ], :expr_fname ],
|
|
1005
|
+
].map { |args| KWtable.new(*args) }
|
|
1006
|
+
|
|
1007
|
+
# :startdoc:
|
|
1008
|
+
|
|
1009
|
+
WORDLIST = Hash[*wordlist.map { |o| [o.name, o] }.flatten] unless
|
|
1010
|
+
defined? WORDLIST
|
|
1011
|
+
|
|
1012
|
+
def self.keyword str
|
|
1013
|
+
WORDLIST[str]
|
|
1014
|
+
end
|
|
891
1015
|
end
|
|
892
|
-
end
|
|
893
1016
|
|
|
894
|
-
class Environment
|
|
895
|
-
|
|
1017
|
+
class Environment
|
|
1018
|
+
attr_reader :env, :dyn
|
|
896
1019
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1020
|
+
def [] k
|
|
1021
|
+
self.all[k]
|
|
1022
|
+
end
|
|
900
1023
|
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
1024
|
+
def []= k, v
|
|
1025
|
+
raise "no" if v == true
|
|
1026
|
+
self.current[k] = v
|
|
1027
|
+
end
|
|
905
1028
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1029
|
+
def all
|
|
1030
|
+
idx = @dyn.index(false) || 0
|
|
1031
|
+
@env[0..idx].reverse.inject { |env, scope| env.merge scope }
|
|
1032
|
+
end
|
|
910
1033
|
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1034
|
+
def current
|
|
1035
|
+
@env.first
|
|
1036
|
+
end
|
|
914
1037
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
1038
|
+
def dynamic
|
|
1039
|
+
idx = @dyn.index false
|
|
1040
|
+
@env[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
|
|
1041
|
+
end
|
|
919
1042
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
1043
|
+
def dynamic?
|
|
1044
|
+
@dyn[0] != false
|
|
1045
|
+
end
|
|
923
1046
|
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1047
|
+
def extend dyn = false
|
|
1048
|
+
@dyn.unshift dyn
|
|
1049
|
+
@env.unshift({})
|
|
1050
|
+
@use.unshift({})
|
|
1051
|
+
end
|
|
929
1052
|
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
1053
|
+
def initialize dyn = false
|
|
1054
|
+
@dyn = []
|
|
1055
|
+
@env = []
|
|
1056
|
+
@use = []
|
|
1057
|
+
self.reset
|
|
1058
|
+
end
|
|
936
1059
|
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1060
|
+
def reset
|
|
1061
|
+
@dyn.clear
|
|
1062
|
+
@env.clear
|
|
1063
|
+
@use.clear
|
|
1064
|
+
self.extend
|
|
1065
|
+
end
|
|
943
1066
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
1067
|
+
def unextend
|
|
1068
|
+
@dyn.shift
|
|
1069
|
+
@env.shift
|
|
1070
|
+
@use.shift
|
|
1071
|
+
raise "You went too far unextending env" if @env.empty?
|
|
1072
|
+
end
|
|
950
1073
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1074
|
+
def use id
|
|
1075
|
+
@env.each_with_index do |env, i|
|
|
1076
|
+
if env[id] then
|
|
1077
|
+
@use[i][id] = true
|
|
1078
|
+
end
|
|
955
1079
|
end
|
|
956
1080
|
end
|
|
957
|
-
end
|
|
958
1081
|
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
1082
|
+
def used? id
|
|
1083
|
+
idx = @dyn.index false # REFACTOR
|
|
1084
|
+
u = @use[0...idx].reverse.inject { |env, scope| env.merge scope } || {}
|
|
1085
|
+
u[id]
|
|
1086
|
+
end
|
|
963
1087
|
end
|
|
964
|
-
end
|
|
965
1088
|
|
|
966
|
-
class StackState
|
|
967
|
-
|
|
1089
|
+
class StackState
|
|
1090
|
+
attr_reader :stack
|
|
968
1091
|
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1092
|
+
def initialize(name)
|
|
1093
|
+
@name = name
|
|
1094
|
+
@stack = [false]
|
|
1095
|
+
end
|
|
973
1096
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1097
|
+
def inspect
|
|
1098
|
+
"StackState(#{@name}, #{@stack.inspect})"
|
|
1099
|
+
end
|
|
977
1100
|
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1101
|
+
def is_in_state
|
|
1102
|
+
@stack.last
|
|
1103
|
+
end
|
|
981
1104
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1105
|
+
def lexpop
|
|
1106
|
+
raise if @stack.size == 0
|
|
1107
|
+
a = @stack.pop
|
|
1108
|
+
b = @stack.pop
|
|
1109
|
+
@stack.push(a || b)
|
|
1110
|
+
end
|
|
1111
|
+
|
|
1112
|
+
def pop
|
|
1113
|
+
r = @stack.pop
|
|
1114
|
+
@stack.push false if @stack.size == 0
|
|
1115
|
+
r
|
|
1116
|
+
end
|
|
988
1117
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
r
|
|
1118
|
+
def push val
|
|
1119
|
+
@stack.push val
|
|
1120
|
+
end
|
|
993
1121
|
end
|
|
1122
|
+
end
|
|
994
1123
|
|
|
995
|
-
|
|
996
|
-
|
|
1124
|
+
class Ruby19Parser < Racc::Parser
|
|
1125
|
+
include RubyParserStuff
|
|
1126
|
+
end
|
|
1127
|
+
|
|
1128
|
+
class Ruby18Parser < Racc::Parser
|
|
1129
|
+
include RubyParserStuff
|
|
1130
|
+
end
|
|
1131
|
+
|
|
1132
|
+
class RubyParser < Ruby18Parser
|
|
1133
|
+
def initialize
|
|
1134
|
+
super
|
|
1135
|
+
warn "WA\RNING: Deprecated: RubyParser. Use Ruby18Parser or Ruby19Parser"
|
|
1136
|
+
warn " from #{caller.first}"
|
|
997
1137
|
end
|
|
998
1138
|
end
|
|
999
1139
|
|
|
@@ -1022,6 +1162,14 @@ class Sexp
|
|
|
1022
1162
|
self.value.to_sym
|
|
1023
1163
|
end
|
|
1024
1164
|
|
|
1165
|
+
def add x
|
|
1166
|
+
raise "no" # TODO: need a test to trigger this
|
|
1167
|
+
end
|
|
1168
|
+
|
|
1169
|
+
def add_all x
|
|
1170
|
+
raise "no" # TODO: need a test to trigger this
|
|
1171
|
+
end
|
|
1172
|
+
|
|
1025
1173
|
alias :node_type :sexp_type
|
|
1026
1174
|
alias :values :sexp_body # TODO: retire
|
|
1027
1175
|
end
|