rubylexer 0.7.6 → 0.7.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +4 -0
- data/History.txt +54 -7
- data/Makefile +43 -0
- data/lib/.document +3 -0
- data/lib/rubylexer.rb +286 -154
- data/lib/rubylexer/.document +9 -0
- data/lib/rubylexer/charhandler.rb +25 -19
- data/lib/rubylexer/context.rb +17 -4
- data/lib/rubylexer/rubycode.rb +1 -1
- data/lib/rubylexer/rulexer.rb +120 -95
- data/lib/rubylexer/symboltable.rb +22 -1
- data/lib/rubylexer/test/oneliners.rb +20 -0
- data/lib/rubylexer/test/oneliners_1.9.rb +146 -0
- data/lib/rubylexer/test/testcases.rb +6 -2
- data/lib/rubylexer/token.rb +22 -6
- data/lib/rubylexer/tokenprinter.rb +6 -6
- data/lib/rubylexer/version.rb +1 -1
- data/rubylexer.gemspec +40 -0
- data/test/code/coloruby.rb +154 -0
- data/test/code/dumptokens.rb +10 -5
- data/test/code/regression.rb +31 -17
- data/test/code/rubylexervsruby.rb +1 -1
- data/test/code/test_1.9.rb +31 -0
- data/test/code/tokentest.rb +6 -6
- data/test/data/{hdr_dos2.rb → hdr_dos2.rb.broken} +0 -0
- data/test/data/{heremonsters.rb.broken → heremonsters_broken.rb} +0 -0
- data/test/data/{heremonsters_dos.rb.broken → heremonsters_dos_broken.rb} +0 -0
- data/test/test_all.rb +2 -0
- metadata +94 -98
- data/Rakefile +0 -37
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
rubylexer - a ruby lexer written in ruby
|
3
3
|
Copyright (C) 2004,2005,2008 Caleb Clausen
|
4
4
|
|
@@ -22,23 +22,29 @@ class RubyLexer
|
|
22
22
|
#------------------------------------
|
23
23
|
class CharHandler
|
24
24
|
#-----------------------------------
|
25
|
-
|
25
|
+
if ?A.is_a? String #ruby >= 1.9
|
26
|
+
CHARSETSPECIALS=/[\[\]\\\-]/
|
27
|
+
else
|
28
|
+
CHARSETSPECIALS=CharSet[?[ ,?] ,?\\ ,?-]
|
29
|
+
end
|
26
30
|
def initialize(receiver,default,hash)
|
27
31
|
@default=default
|
28
32
|
@receiver=receiver
|
29
|
-
#
|
30
|
-
|
33
|
+
if ?A.is_a? String #ruby >= 1.9
|
34
|
+
@table={}
|
35
|
+
else
|
36
|
+
@table=Array.new(0)
|
37
|
+
end
|
31
38
|
@matcher='^[^'
|
32
39
|
|
33
40
|
hash.each_pair {|pattern,action|
|
34
41
|
case pattern
|
35
42
|
when Range
|
36
43
|
pattern.each { |c|
|
37
|
-
c.kind_of? String and c=c[0] #cvt to integer #still needed?
|
38
44
|
self[c]=action
|
39
45
|
}
|
40
46
|
when String
|
41
|
-
pattern
|
47
|
+
CharHandler.each_char(pattern) {|b| self[b]=action }
|
42
48
|
when Fixnum
|
43
49
|
self[pattern]=action
|
44
50
|
else
|
@@ -47,15 +53,26 @@ class CharHandler
|
|
47
53
|
}
|
48
54
|
|
49
55
|
@matcher += ']$'
|
50
|
-
@matcher=Regexp.new(@matcher)
|
56
|
+
@matcher=Regexp.new(@matcher,0,'n')
|
51
57
|
|
52
58
|
freeze
|
53
59
|
end
|
54
60
|
|
61
|
+
#-----------------------------------
|
62
|
+
if String===?a
|
63
|
+
def self.each_char(str,&block)
|
64
|
+
str.each_char(&block)
|
65
|
+
end
|
66
|
+
else
|
67
|
+
def self.each_char(str,&block)
|
68
|
+
str.each_byte(&block)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
55
72
|
#-----------------------------------
|
56
73
|
def []=(b,action) #for use in initialize only
|
57
74
|
assert b >= ?\x00
|
58
|
-
assert b <= ?\
|
75
|
+
assert b <= ?\x7F
|
59
76
|
assert !frozen?
|
60
77
|
|
61
78
|
@table[b]=action
|
@@ -69,17 +86,6 @@ class CharHandler
|
|
69
86
|
@receiver.send((@table[b] or @default), b.chr, *args)
|
70
87
|
end
|
71
88
|
|
72
|
-
#-----------------------------------
|
73
|
-
def eat_file(file,blocksize,*args)
|
74
|
-
begin
|
75
|
-
chars=file.read(blocksize)
|
76
|
-
md=@matcher.match(chars)
|
77
|
-
mychar=md[0][0]
|
78
|
-
#get file back in the right pos
|
79
|
-
file.pos+=md.offset(0)[0] - chars.length
|
80
|
-
@receiver.send(@default,md[0])
|
81
|
-
end until go(mychar,*args)
|
82
|
-
end
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
data/lib/rubylexer/context.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
=begin
|
1
|
+
=begin
|
2
2
|
rubylexer - a ruby lexer written in ruby
|
3
3
|
Copyright (C) 2008 Caleb Clausen
|
4
4
|
|
@@ -74,6 +74,7 @@ module NestedContexts
|
|
74
74
|
super('{','}',linenum)
|
75
75
|
end
|
76
76
|
attr_accessor :wanting_stabby_block_body
|
77
|
+
#attr_writer :starter,:ender
|
77
78
|
end
|
78
79
|
|
79
80
|
class BeginEndContext < NestedContext
|
@@ -118,6 +119,9 @@ module NestedContexts
|
|
118
119
|
class UnparenedParamListLhsContext < ImplicitLhsContext
|
119
120
|
def starter; huh end #" " ???
|
120
121
|
def ender; huh end #; or \n when from method def, { or do when from stabby block
|
122
|
+
def endtoken offset
|
123
|
+
KwParamListEndToken.new offset
|
124
|
+
end
|
121
125
|
end
|
122
126
|
|
123
127
|
class ImplicitContext < ListContext
|
@@ -129,6 +133,9 @@ module NestedContexts
|
|
129
133
|
end
|
130
134
|
def lhs; false end
|
131
135
|
def wantarrow; true end
|
136
|
+
def endtoken offset
|
137
|
+
ImplicitParamListEndToken.new offset
|
138
|
+
end
|
132
139
|
end
|
133
140
|
|
134
141
|
class KWParamListContextNoParen < ParamListContextNoParen
|
@@ -159,6 +166,9 @@ module NestedContexts
|
|
159
166
|
def multi_assign?
|
160
167
|
@multi if defined? @multi
|
161
168
|
end
|
169
|
+
def endtoken offset
|
170
|
+
AssignmentRhsEndToken.new offset
|
171
|
+
end
|
162
172
|
end
|
163
173
|
|
164
174
|
class WantsEndContext < NestedContext
|
@@ -201,6 +211,9 @@ module NestedContexts
|
|
201
211
|
end
|
202
212
|
|
203
213
|
attr :in_body
|
214
|
+
|
215
|
+
attr_writer :has_parens
|
216
|
+
def has_parens?; @has_parens end
|
204
217
|
end
|
205
218
|
|
206
219
|
class StringContext < NestedContext #not used yet
|
@@ -283,13 +296,13 @@ module NestedContexts
|
|
283
296
|
stack=lxr.parsestack
|
284
297
|
assert msg!=:for
|
285
298
|
case msg
|
286
|
-
when :for
|
299
|
+
when :for; WantsEndContext===stack.last or raise 'syntax error: for not expected at this time'
|
287
300
|
#local var defined in this state
|
288
301
|
#never actually used?
|
289
|
-
when :in
|
302
|
+
when :in; self.equal? stack.pop or raise 'syntax error: in not expected at this time'
|
290
303
|
stack.push ExpectDoOrNlContext.new("for",/(do|;|:|\n)/,@linenum)
|
291
304
|
#pop self off owning context stack and push ExpectDoOrNlContext
|
292
|
-
when :comma, :splat
|
305
|
+
when :comma, :splat; return
|
293
306
|
else super
|
294
307
|
end
|
295
308
|
LEGAL_SUCCESSORS[@state].include? msg or raise "for syntax error: #{msg} unexpected in #@state"
|
data/lib/rubylexer/rubycode.rb
CHANGED
data/lib/rubylexer/rulexer.rb
CHANGED
@@ -38,17 +38,10 @@ require 'sequence/file'
|
|
38
38
|
require 'sequence/list'
|
39
39
|
#-----------------------------------
|
40
40
|
assert !defined? ::RubyLexer
|
41
|
-
$RuLexer=Class.new{}
|
42
|
-
class RubyLexer < $RuLexer
|
43
|
-
RuLexer=$RuLexer
|
44
|
-
end
|
45
|
-
$RuLexer=nil
|
46
|
-
#------------------------------------
|
47
41
|
class RubyLexer
|
48
42
|
FASTER_STRING_ESCAPES=true
|
49
43
|
warn "FASTER_STRING_ESCAPES is off" unless FASTER_STRING_ESCAPES
|
50
44
|
AUTO_UNESCAPE_STRINGS=false
|
51
|
-
class RuLexer
|
52
45
|
WHSP=" \t\r\v\f"
|
53
46
|
WHSPLF=WHSP+"\n"
|
54
47
|
#maybe \r should be in WHSPLF instead
|
@@ -75,11 +68,13 @@ class RubyLexer
|
|
75
68
|
@moretokens=[ RubyLexer::FileAndLineToken.new(@filename, @linenum, input_position) ]
|
76
69
|
@endsets={}
|
77
70
|
end
|
71
|
+
alias rulexer_initialize initialize
|
78
72
|
|
79
73
|
#-----------------------------------
|
80
74
|
def endoffile_detected s=''
|
81
75
|
EoiToken.new(s,@original_file, input_position-s.size)
|
82
76
|
end
|
77
|
+
alias rulexer_endoffile_detected endoffile_detected
|
83
78
|
|
84
79
|
#-----------------------------------
|
85
80
|
def get1token
|
@@ -92,6 +87,7 @@ class RubyLexer
|
|
92
87
|
|
93
88
|
@toptable.go( nextchar )
|
94
89
|
end
|
90
|
+
alias rulexer_get1token get1token
|
95
91
|
|
96
92
|
#-----------------------------------
|
97
93
|
def no_more?
|
@@ -143,40 +139,41 @@ private
|
|
143
139
|
if @rubyversion>=1.9
|
144
140
|
named_brs=[]
|
145
141
|
if result.elems.size==1 and String===result.elems.first
|
142
|
+
elem=result.elems.first
|
146
143
|
index=0
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
when "(?<"; huh
|
144
|
+
while index=elem.index(/(#{EVEN_BS_S})( \(\?[<'] | \(\?\# | \[ )/xo,index)
|
145
|
+
index+=$1.size
|
146
|
+
case $2
|
147
|
+
when "(?<"
|
152
148
|
index=elem.index(/\G...(#{LCLETTER}#{LETTER_DIGIT}+)>/o,index)
|
153
|
-
|
154
|
-
index
|
149
|
+
break lexerror(result, "malformed named backreference") unless index
|
150
|
+
index+=$&.size
|
155
151
|
named_brs<<$1
|
156
|
-
when "(?'"
|
152
|
+
when "(?'"
|
157
153
|
index=elem.index(/\G...(#{LCLETTER}#{LETTER_DIGIT}+)'/o,index)
|
158
|
-
|
159
|
-
index
|
154
|
+
break lexerror(result, "malformed named backreference") unless index
|
155
|
+
index+=$&.size
|
160
156
|
named_brs<<$1
|
161
|
-
when "(?#"
|
157
|
+
when "(?#"
|
162
158
|
index+=3
|
163
|
-
index=elem.index(/#{EVEN_BS_S}\)
|
164
|
-
|
165
|
-
index
|
166
|
-
when "["
|
159
|
+
index=elem.index(/#{EVEN_BS_S}\)/o,index)
|
160
|
+
break lexerror(result, "unterminated regexp comment") unless index
|
161
|
+
index+=$&.size
|
162
|
+
when "["
|
167
163
|
index+=1
|
168
164
|
paren_ctr=1
|
169
165
|
loop do
|
170
166
|
index=elem.index(/#{EVEN_BS_S}(&&\[\^|\])/o,index)
|
171
|
-
|
167
|
+
break lexerror(result, "unterminated character class") unless index
|
172
168
|
index+=$&.size
|
173
|
-
|
174
|
-
paren_ctr+=1
|
175
|
-
else
|
169
|
+
if $1==']'
|
176
170
|
paren_ctr-=1
|
177
171
|
break if paren_ctr==0
|
172
|
+
else
|
173
|
+
paren_ctr+=1
|
178
174
|
end
|
179
175
|
end
|
176
|
+
break unless index
|
180
177
|
|
181
178
|
end
|
182
179
|
end
|
@@ -190,6 +187,7 @@ private
|
|
190
187
|
|
191
188
|
#-----------------------------------
|
192
189
|
def single_char_token(str) getchar end
|
190
|
+
alias rulexer_single_char_token single_char_token
|
193
191
|
|
194
192
|
#-----------------------------------
|
195
193
|
def illegal_char(ch)
|
@@ -239,12 +237,12 @@ else
|
|
239
237
|
end
|
240
238
|
result=send(strlex, beg, type, close=(PAIRS[beg] or beg))
|
241
239
|
case ch
|
242
|
-
when /^[Wwr]
|
240
|
+
when /^[Wwr]$/
|
243
241
|
str=result
|
244
242
|
result=RenderExactlyStringToken.new(type).append_token(result)
|
245
243
|
result.open=str.open; result.close=str.close
|
246
244
|
result.line=@linenum
|
247
|
-
when 's'
|
245
|
+
when 's'
|
248
246
|
result.open=open+beg
|
249
247
|
result.close=close
|
250
248
|
result=SymbolToken.new result,nil,"%s"
|
@@ -274,12 +272,12 @@ end
|
|
274
272
|
#-----------------------------------
|
275
273
|
INTERIOR_REX_CACHE={}
|
276
274
|
EVEN_BS_S=/
|
277
|
-
(
|
275
|
+
(?:\G|
|
278
276
|
[^\\c-]|
|
279
|
-
(
|
280
|
-
(
|
277
|
+
(?:\G|[^\\])(?:c|[CM]-)|
|
278
|
+
(?:\G|[^CM])-
|
281
279
|
)
|
282
|
-
(
|
280
|
+
(?:\\(?:c|[CM]-)?){2}*
|
283
281
|
/x
|
284
282
|
ILLEGAL_ESCAPED=/#{EVEN_BS_S}(\\([CM][^-]|x[^a-fA-F0-9]))/o #whaddaya do with this?
|
285
283
|
def all_quote(nester, type, delimiter, bs_handler=nil)
|
@@ -298,12 +296,12 @@ if FASTER_STRING_ESCAPES
|
|
298
296
|
single_quotish=true
|
299
297
|
special=/\\./m
|
300
298
|
else
|
301
|
-
crunch
|
299
|
+
crunch=/\#(?=[^{$@])/
|
302
300
|
escaped=/\\(?>[^xcCM0-7]|(?>c|[CM].)(?>[^\\]|(?=\\))|(?>x.[0-9a-fA-F]?)|(?>[0-7]{1,3}))/m
|
303
301
|
special=
|
304
302
|
case delimiter
|
305
|
-
when '\\'
|
306
|
-
when '#'
|
303
|
+
when '\\'; crunch
|
304
|
+
when '#'; escaped
|
307
305
|
else /#{escaped}|#{crunch}/o
|
308
306
|
end
|
309
307
|
special_char<< maybe_crunch="#"
|
@@ -318,8 +316,8 @@ if FASTER_STRING_ESCAPES
|
|
318
316
|
str=StringToken.new type
|
319
317
|
str.bs_handler ||= case type
|
320
318
|
when '/' then :regex_esc_seq
|
321
|
-
when '{' then :Wquote_esc_seq
|
322
|
-
when '"','`',':' then :dquote_esc_seq
|
319
|
+
when '{' then @rubyversion>=1.9 ? :Wquote19_esc_seq : :Wquote_esc_seq
|
320
|
+
when '"','`',':' then @rubyversion>=1.9 ? :dquote19_esc_seq : :dquote_esc_seq
|
323
321
|
when "'" then :squote_esc_seq
|
324
322
|
when "[" then :wquote_esc_seq
|
325
323
|
else raise "unknown quote type: #{type}"
|
@@ -431,8 +429,8 @@ else
|
|
431
429
|
|
432
430
|
bs_handler ||= case type
|
433
431
|
when '/' then :regex_esc_seq
|
434
|
-
when '{' then :Wquote_esc_seq
|
435
|
-
when '"','`',':' then :dquote_esc_seq
|
432
|
+
when '{' then @rubyversion>=1.9 ? :Wquote19_esc_seq : :Wquote_esc_seq
|
433
|
+
when '"','`',':' then @rubyversion>=1.9 ? :dquote19_esc_seq : :dquote_esc_seq
|
436
434
|
when "'" then :squote_esc_seq
|
437
435
|
when "[" then :wquote_esc_seq
|
438
436
|
else raise "unknown quote type: #{type}"
|
@@ -525,16 +523,25 @@ end
|
|
525
523
|
k.tr(ESCAPECHRS,ESCAPESEQS)
|
526
524
|
when "M"
|
527
525
|
eat_next_if(?-) or raise 'bad \\M sequence'
|
528
|
-
|
526
|
+
ch=getchar_maybe_escape[0]
|
527
|
+
ch=ch.ord if ch.respond_to? :ord
|
528
|
+
ch>=0xFF and raise 'bad \\M sequence'
|
529
|
+
(ch | 0x80).chr
|
529
530
|
|
530
531
|
when "C"
|
531
532
|
eat_next_if(?-) or raise 'bad \\C sequence'
|
532
533
|
nextchar==?? and getchar and return "\177" #wtf?
|
533
|
-
|
534
|
+
ch=getchar_maybe_escape[0]
|
535
|
+
ch=ch.ord if ch.respond_to? :ord
|
536
|
+
ch>=0xFF and raise 'bad \\M sequence'
|
537
|
+
(ch & 0x9F).chr
|
534
538
|
|
535
539
|
when "c"
|
536
540
|
nextchar==?? and getchar and return "\177" #wtf?
|
537
|
-
|
541
|
+
ch=getchar_maybe_escape[0]
|
542
|
+
ch=ch.ord if ch.respond_to? :ord
|
543
|
+
ch>=0xFF and raise 'bad \\M sequence'
|
544
|
+
(ch & 0x9F).chr
|
538
545
|
|
539
546
|
when /^[0-7]$/
|
540
547
|
str=k
|
@@ -556,6 +563,33 @@ end
|
|
556
563
|
end
|
557
564
|
end
|
558
565
|
|
566
|
+
#-----------------------------------
|
567
|
+
def dquote19_esc_seq(ch,nester,delimiter)
|
568
|
+
assert ch == '\\'
|
569
|
+
case ch=getchar
|
570
|
+
when 'u'
|
571
|
+
case ch=getchar
|
572
|
+
when /[a-f0-9]/i
|
573
|
+
u=read(4)
|
574
|
+
raise "bad unicode escape" unless /[0-9a-f]{4}/i===u
|
575
|
+
[u.hex].pack "U"
|
576
|
+
when '{'
|
577
|
+
result=[]
|
578
|
+
until eat_next_if '}'
|
579
|
+
u=@file.scan(/\A[0-9a-f]{1,6}[ \t]?/i,7)
|
580
|
+
result<<u.hex
|
581
|
+
end
|
582
|
+
result=result.pack "U*"
|
583
|
+
else raise "bad unicode escape"
|
584
|
+
end
|
585
|
+
else
|
586
|
+
back1char
|
587
|
+
result=dquote_esc_seq('\\',nester,delimiter)
|
588
|
+
#/\s|\v/===result and result="\\"+result
|
589
|
+
result
|
590
|
+
end
|
591
|
+
end
|
592
|
+
|
559
593
|
#-----------------------------------
|
560
594
|
def regex_esc_seq(ch,nester,delimiter)
|
561
595
|
assert ch == '\\'
|
@@ -571,9 +605,9 @@ end
|
|
571
605
|
def Wquote_esc_seq(ch,nester,delimiter)
|
572
606
|
assert ch == '\\'
|
573
607
|
case ch=getchar
|
574
|
-
when "\n"
|
575
|
-
when nester,delimiter
|
576
|
-
when /[\s\v\\]
|
608
|
+
when "\n"; @linenum+=1; ch
|
609
|
+
when nester,delimiter; ch
|
610
|
+
when /[\s\v\\]/; ch
|
577
611
|
else
|
578
612
|
back1char
|
579
613
|
result=dquote_esc_seq('\\',nester,delimiter)
|
@@ -582,6 +616,21 @@ end
|
|
582
616
|
end
|
583
617
|
end
|
584
618
|
|
619
|
+
#-----------------------------------
|
620
|
+
def Wquote19_esc_seq(ch,nester,delimiter)
|
621
|
+
assert ch == '\\'
|
622
|
+
case ch=getchar
|
623
|
+
when "\n"; @linenum+=1; ch
|
624
|
+
when nester,delimiter; ch
|
625
|
+
when /[\s\v\\]/; ch
|
626
|
+
else
|
627
|
+
back1char
|
628
|
+
result=dquote19_esc_seq('\\',nester,delimiter)
|
629
|
+
#/\s|\v/===result and result="\\"+result
|
630
|
+
result
|
631
|
+
end
|
632
|
+
end
|
633
|
+
|
585
634
|
#-----------------------------------
|
586
635
|
def wquote_esc_seq(ch,nester,delimiter)
|
587
636
|
assert(ch=='\\')
|
@@ -592,10 +641,10 @@ end
|
|
592
641
|
#all \ sequences
|
593
642
|
#are unescaped; actual
|
594
643
|
#newlines are counted but not changed
|
595
|
-
when delimiter,nester,'\\'
|
596
|
-
# when delimiter,nester
|
597
|
-
when "\n"
|
598
|
-
when /[\s\v]
|
644
|
+
when delimiter,nester,'\\'; escchar
|
645
|
+
# when delimiter,nester; escchar
|
646
|
+
when "\n"; @linenum+=1; escchar
|
647
|
+
when /[\s\v]/; escchar
|
599
648
|
else "\\"+escchar
|
600
649
|
end
|
601
650
|
end
|
@@ -610,9 +659,9 @@ end
|
|
610
659
|
#all \ sequences
|
611
660
|
#are unescaped; actual
|
612
661
|
#newlines are counted but not changed
|
613
|
-
when delimiter,nester,'\\'
|
614
|
-
# when delimiter,nester
|
615
|
-
when "\n"
|
662
|
+
when delimiter,nester,'\\'; escchar
|
663
|
+
# when delimiter,nester; escchar
|
664
|
+
when "\n"; @linenum+=1; "\\"+escchar
|
616
665
|
else "\\"+escchar
|
617
666
|
end
|
618
667
|
end
|
@@ -627,9 +676,9 @@ end
|
|
627
676
|
#all \ sequences
|
628
677
|
#are unescaped; actual
|
629
678
|
#newlines are counted but not changed
|
630
|
-
when delimiter,nester
|
631
|
-
# when delimiter,nester
|
632
|
-
when "\n"
|
679
|
+
when delimiter,nester; escchar
|
680
|
+
# when delimiter,nester; escchar
|
681
|
+
when "\n"; @linenum+=1; "\\"+escchar
|
633
682
|
else "\\"+escchar
|
634
683
|
end
|
635
684
|
end
|
@@ -649,9 +698,11 @@ end
|
|
649
698
|
# alias squote_esc_seq wquote_esc_seq
|
650
699
|
|
651
700
|
module RecursiveRubyLexer
|
701
|
+
=begin
|
652
702
|
def initial_nonblock_levels
|
653
703
|
@localvars_stack.size==1 ? 2 : 1
|
654
704
|
end
|
705
|
+
=end
|
655
706
|
end
|
656
707
|
|
657
708
|
def initial_nonblock_levels; 1 end
|
@@ -663,8 +714,8 @@ end
|
|
663
714
|
|
664
715
|
def merge_levels levels, nil_empty_class
|
665
716
|
case (levels.size rescue 0)
|
666
|
-
when 0
|
667
|
-
when 1
|
717
|
+
when 0; {} unless nil_empty_class
|
718
|
+
when 1; levels.first.dup
|
668
719
|
else levels.inject{|a,b| a.merge b}
|
669
720
|
end
|
670
721
|
end
|
@@ -713,30 +764,7 @@ end
|
|
713
764
|
#pass current local vars into new parser
|
714
765
|
#must pass the lists of nonblock, parentblock and currentblock vars separately
|
715
766
|
#then a table increment after each
|
716
|
-
|
717
|
-
nonblocky.keys.each{|varname|
|
718
|
-
rl.localvars[varname]=true
|
719
|
-
}
|
720
|
-
rl.localvars.start_block
|
721
|
-
#incremental table, tells us what :local vars are defined in the str inclusion
|
722
|
-
|
723
|
-
if blocky
|
724
|
-
rl.localvars.start_block
|
725
|
-
blocky.keys.each{|varname|
|
726
|
-
rl.localvars[varname]=true
|
727
|
-
}
|
728
|
-
rl.localvars.start_block
|
729
|
-
#incremental table, tells us what :block vars are defined in the str inclusion
|
730
|
-
end
|
731
|
-
|
732
|
-
if current
|
733
|
-
rl.localvars.start_block
|
734
|
-
current.keys.each{|varname|
|
735
|
-
rl.localvars[varname]=true
|
736
|
-
}
|
737
|
-
rl.localvars.start_block
|
738
|
-
#incremental table, tells us what :current vars are defined in the str inclusion
|
739
|
-
end
|
767
|
+
rl.localvars_stack=@localvars_stack.map{|lvs| lvs.deep_copy}
|
740
768
|
|
741
769
|
rl.pending_here_bodies=@pending_here_bodies
|
742
770
|
|
@@ -790,19 +818,13 @@ end
|
|
790
818
|
# @pending_here_bodies=rl.pending_here_bodies
|
791
819
|
|
792
820
|
#local vars defined in inclusion get propagated to outer parser
|
793
|
-
|
794
|
-
newvars.each{|newvar| localvars[newvar]=true }
|
821
|
+
@localvars_stack=rl.localvars_stack
|
795
822
|
|
796
823
|
result=RubyCode.new(tokens,@filename,@linenum)
|
797
824
|
@linenum=rl.linenum
|
798
825
|
return result
|
799
826
|
end
|
800
827
|
|
801
|
-
#-----------------------------------
|
802
|
-
def here_spread_over_ruby_code(rl,tok)
|
803
|
-
lexerror tok, 'here body outside string inclusion'
|
804
|
-
end
|
805
|
-
|
806
828
|
|
807
829
|
#-----------------------------------
|
808
830
|
# BINCHARS=?0..?1
|
@@ -913,6 +935,7 @@ else
|
|
913
935
|
IgnoreToken.new(til_charset(/[\r\n]/))
|
914
936
|
end
|
915
937
|
end
|
938
|
+
alias rulexer_comment comment
|
916
939
|
|
917
940
|
#-----------------------------------
|
918
941
|
def whitespace(ch)
|
@@ -944,16 +967,17 @@ end
|
|
944
967
|
@moretokens << FileAndLineToken.new( @filename, @linenum, offset+1 )
|
945
968
|
return NewlineToken.new("\n",offset)
|
946
969
|
end
|
947
|
-
|
970
|
+
alias rulexer_newline newline
|
948
971
|
|
949
972
|
#-----------------------------------
|
950
973
|
def getchar_maybe_escape
|
951
974
|
eof? and raise "unterminated dq string"
|
952
|
-
c=getc
|
953
|
-
|
954
|
-
c == ?\\ and
|
955
|
-
(c = (dquote_esc_seq('\\')[-1] or ?\n))
|
975
|
+
c=getc.chr
|
956
976
|
|
977
|
+
if c == "\\"
|
978
|
+
c = @rubyversion >= 1.9 ? dquote19_esc_seq('\\') : dquote_esc_seq('\\')
|
979
|
+
c = "\n" if c.empty?
|
980
|
+
end
|
957
981
|
return c
|
958
982
|
end
|
959
983
|
|
@@ -962,6 +986,7 @@ protected
|
|
962
986
|
require 'forwardable'
|
963
987
|
extend Forwardable
|
964
988
|
def_delegators :@file, :readahead, :readback, :read, :eof?
|
989
|
+
alias rulexer_eof? eof?
|
965
990
|
|
966
991
|
def til_charset cs,len=16; @file.read_til_charset cs,len end
|
967
992
|
def getc; @file.read1 end
|
@@ -995,13 +1020,14 @@ protected
|
|
995
1020
|
|
996
1021
|
#-----------------------------------
|
997
1022
|
def input_position; @file.pos end
|
1023
|
+
alias rulexer_input_position input_position
|
998
1024
|
|
999
1025
|
#-----------------------------------
|
1000
1026
|
def input_position_set x; @file.pos=x end
|
1001
1027
|
|
1002
1028
|
#-----------------------------------
|
1003
1029
|
def self.save_offsets_in(*funcnames)
|
1004
|
-
eval funcnames.collect{|fn| <<-endeval }.
|
1030
|
+
eval funcnames.collect{|fn| <<-endeval }.join
|
1005
1031
|
class ::#{self}
|
1006
1032
|
alias #{fn}__no_offset #{fn} #rename old ver of fn
|
1007
1033
|
def #{fn}(*args) #create new version
|
@@ -1015,7 +1041,6 @@ protected
|
|
1015
1041
|
endeval
|
1016
1042
|
end
|
1017
1043
|
|
1018
|
-
end
|
1019
1044
|
|
1020
1045
|
end
|
1021
1046
|
|