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
@@ -37,11 +37,32 @@ class SymbolTable
|
|
37
37
|
list or raise "unbalanced end block"
|
38
38
|
list.each_key {|sym|
|
39
39
|
@symbols[sym].pop
|
40
|
-
@symbols[sym].empty? and @symbols
|
40
|
+
@symbols[sym].empty? and @symbols.delete sym
|
41
41
|
}
|
42
42
|
assert @locals_lists.last
|
43
43
|
end
|
44
44
|
|
45
|
+
def deep_copy
|
46
|
+
result=SymbolTable.allocate
|
47
|
+
new_symbols={}
|
48
|
+
@symbols.each_pair{|str,stack|
|
49
|
+
new_symbols[str.clone]=stack.map{|elem| elem.clone rescue elem }
|
50
|
+
}
|
51
|
+
new_locals_lists=[]
|
52
|
+
@locals_lists.each{|hash|
|
53
|
+
new_locals_lists.push({})
|
54
|
+
hash.each_pair{|str,bool|
|
55
|
+
new_locals_lists.last[str.dup]=bool
|
56
|
+
}
|
57
|
+
}
|
58
|
+
new_locals_lists.push({}) if new_locals_lists.empty?
|
59
|
+
result.instance_eval{
|
60
|
+
@symbols=new_symbols
|
61
|
+
@locals_lists=new_locals_lists
|
62
|
+
}
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
45
66
|
def names
|
46
67
|
@symbols.keys
|
47
68
|
end
|
@@ -3,6 +3,23 @@ def x; yield end #this must be first!!!!
|
|
3
3
|
#modifying the list of known local variables. it may be omitted
|
4
4
|
#in cases where it is known that no local vars are defined.
|
5
5
|
|
6
|
+
module A 55 end
|
7
|
+
module Array([Array]).first::E; end
|
8
|
+
module Array ([Array]).first::E; end
|
9
|
+
module Array([Array]).first::E include M; end
|
10
|
+
module Array ([Array]).first::E include M; end
|
11
|
+
module Array([Array]).first::E include M end
|
12
|
+
module Array ([Array]).first::E include M end
|
13
|
+
x{a=Array; module a::Foo; 55 end}
|
14
|
+
x{a=Array; module a::Foo include a; 55 end}
|
15
|
+
x{a=Array; module a::Foo include a; a end}
|
16
|
+
module a.b.c.d.e.f::Quux; YYY=534 end
|
17
|
+
module[Array][0]::Foo; Bazz=556 end
|
18
|
+
|
19
|
+
module(@a)::Foo; Bar=111 end
|
20
|
+
|
21
|
+
module@x::Foo; Bar=1 end
|
22
|
+
|
6
23
|
module A::B; end
|
7
24
|
|
8
25
|
p a rescue b
|
@@ -499,6 +516,9 @@ def ~@; :foo end
|
|
499
516
|
undef ~@
|
500
517
|
alias ~@ non
|
501
518
|
alias non ~@
|
519
|
+
undef :~@
|
520
|
+
alias :~@ non
|
521
|
+
alias non :~@
|
502
522
|
p :~@
|
503
523
|
a.~@
|
504
524
|
a::~@
|
@@ -0,0 +1,146 @@
|
|
1
|
+
module Ruby1_9OneLiners
|
2
|
+
EXPECT_NO_METHODS=[ #no errors either
|
3
|
+
'->a; h do 123 end',
|
4
|
+
'->{}',
|
5
|
+
'-> {}',
|
6
|
+
'->;{}',
|
7
|
+
'->(;){}',
|
8
|
+
'->a{}',
|
9
|
+
'->a {}',
|
10
|
+
'->a;{}',
|
11
|
+
'->(a;){}',
|
12
|
+
'->a,b{}',
|
13
|
+
'->a,b;{}',
|
14
|
+
'->a,b;c{}',
|
15
|
+
'->(a,b;){}',
|
16
|
+
'->(a,b;c){}',
|
17
|
+
'$f.($x,$y)',
|
18
|
+
'$f::($x,$y)',
|
19
|
+
'__ENCODING__',
|
20
|
+
'__ENCODING__ +"foo"',
|
21
|
+
'module __ENCODING__::A; end',
|
22
|
+
'/(?<foo>bar)/ =~ "baz"; foo +1',
|
23
|
+
"/(?'foo'bar)/ =~ 'baz'; foo +1",
|
24
|
+
'/\\\\(?<foo>bar)/ =~ "baz"; foo +1',
|
25
|
+
"/\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
26
|
+
'/\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
|
27
|
+
"/\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
28
|
+
'/\\\\c(?<foo>bar)/ =~ "baz"; foo +1',
|
29
|
+
"/\\\\c(?'foo'bar)/ =~ 'baz'; foo +1",
|
30
|
+
'/\\C-\\(?<foo>bar)/ =~ "baz"; foo +1',
|
31
|
+
"/\\C-\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
32
|
+
'/\\\\C-(?<foo>bar)/ =~ "baz"; foo +1',
|
33
|
+
"/\\\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
|
34
|
+
'/\\(?#(?<foo>bar))/ =~ "baz"; foo +1',
|
35
|
+
"/\\(?#(?'foo'bar))/ =~ 'baz'; foo +1",
|
36
|
+
'/\\[(?<foo>bar)]/ =~ "baz"; foo +1',
|
37
|
+
"/\\[(?'foo'bar)]/ =~ 'baz'; foo +1",
|
38
|
+
|
39
|
+
'/z(?<foo>bar)/ =~ "baz"; foo +1',
|
40
|
+
"/z(?'foo'bar)/ =~ 'baz'; foo +1",
|
41
|
+
'/z\\\\(?<foo>bar)/ =~ "baz"; foo +1',
|
42
|
+
"/z\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
43
|
+
'/z\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
|
44
|
+
"/z\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
45
|
+
'/z\\\\c(?<foo>bar)/ =~ "baz"; foo +1',
|
46
|
+
"/z\\\\c(?'foo'bar)/ =~ 'baz'; foo +1",
|
47
|
+
'/z\\C-\\(?<foo>bar)/ =~ "baz"; foo +1',
|
48
|
+
"/z\\C-\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
49
|
+
'/z\\\\C-(?<foo>bar)/ =~ "baz"; foo +1',
|
50
|
+
"/z\\\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
|
51
|
+
'/z\\(?#(?<foo>bar))/ =~ "baz"; foo +1',
|
52
|
+
"/z\\(?#(?'foo'bar))/ =~ 'baz'; foo +1",
|
53
|
+
'/z\\[(?<foo>bar)]/ =~ "baz"; foo +1',
|
54
|
+
"/z\\[(?'foo'bar)]/ =~ 'baz'; foo +1",
|
55
|
+
]
|
56
|
+
|
57
|
+
EXPECT_1_METHOD=[
|
58
|
+
'def self.foo; 1 end',
|
59
|
+
'->{ foo=1 }; foo',
|
60
|
+
'->do foo=1 end; foo',
|
61
|
+
'def __FILE__.foo; 1 end',
|
62
|
+
'def __LINE__.foo; 1 end',
|
63
|
+
'def a(b,*c,d) 1 end',
|
64
|
+
'def a(*c,d) 1 end',
|
65
|
+
'def Z::a(b,*c,d) 1 end',
|
66
|
+
'def Z::a(*c,d) 1 end',
|
67
|
+
'a{|b,*c,d| 1 }',
|
68
|
+
'a{|*c,d| 1 }',
|
69
|
+
'def a(b,(x,y),d) 1 end',
|
70
|
+
'def a((x,y),d) 1 end',
|
71
|
+
'def Z::a(b,(x,y),d) 1 end',
|
72
|
+
'def Z::a((x,y),d) 1 end',
|
73
|
+
'a{|b,(x,y),d| 1 }',
|
74
|
+
'a{|(x,y),d| 1 }',
|
75
|
+
'def a(b,(x,*y),d) 1 end',
|
76
|
+
'def a((x,*y),d) 1 end',
|
77
|
+
'def Z::a(b,(x,*y),d) 1 end',
|
78
|
+
'def Z::a((x,*y),d) 1 end',
|
79
|
+
'a{|b,(x,*y),d| 1 }',
|
80
|
+
'a{|(x,*y),d| 1 }',
|
81
|
+
'def a(b,(x,(y,z)),d) 1 end',
|
82
|
+
'def a((x,(y,z)),d) 1 end',
|
83
|
+
'def Z::a(b,(x,(y,z)),d) 1 end',
|
84
|
+
'def Z::a((x,(y,z)),d) 1 end',
|
85
|
+
'a{|b,(x,(y,z)),d| 1 }',
|
86
|
+
'a{|(x,(y,z)),d| 1 }',
|
87
|
+
'module __ENCODING__::A include B; end',
|
88
|
+
'def __ENCODING__; 342 end',
|
89
|
+
'def __ENCODING__.foo; 1 end',
|
90
|
+
'def Z::__ENCODING__; 342 end',
|
91
|
+
#'def Z::__ENCODING__.foo; 1 end', #oops, 2 methods here
|
92
|
+
'/\\(?<foo>bar)/ =~ "baz"; foo +1',
|
93
|
+
"/\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
94
|
+
'/\\c(?<foo>bar)/ =~ "baz"; foo +1',
|
95
|
+
"/\\c(?'foo'bar)/ =~ 'baz'; foo +1",
|
96
|
+
'/\\C-(?<foo>bar)/ =~ "baz"; foo +1',
|
97
|
+
"/\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
|
98
|
+
'/\\M-(?<foo>bar)/ =~ "baz"; foo +1',
|
99
|
+
"/\\M-(?'foo'bar)/ =~ 'baz'; foo +1",
|
100
|
+
'/\\\\\\(?<foo>bar)/ =~ "baz"; foo +1',
|
101
|
+
"/\\\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
102
|
+
'/\\\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
|
103
|
+
"/\\\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
104
|
+
'/(?#(?<foo>bar))/ =~ "baz"; foo +1',
|
105
|
+
"/(?#(?'foo'bar))/ =~ 'baz'; foo +1",
|
106
|
+
'/[(?<foo>bar)]/ =~ "baz"; foo +1',
|
107
|
+
"/[(?'foo'bar)]/ =~ 'baz'; foo +1",
|
108
|
+
'/[qwe&&[^ty](?<foo>bar)]/ =~ "baz"; foo +1',
|
109
|
+
"/[qwe&&[^ty](?'foo'bar)]/ =~ 'baz'; foo +1",
|
110
|
+
'/[qwe&&[^(?<foo>bar)]]/ =~ "baz"; foo +1',
|
111
|
+
"/[qwe&&[^(?'foo'bar)]]/ =~ 'baz'; foo +1",
|
112
|
+
'/[qwe&&[^ty&&[^uip]](?<foo>bar)]/ =~ "baz"; foo +1',
|
113
|
+
"/[qwe&&[^ty&&[^uip]](?'foo'bar)]/ =~ 'baz'; foo +1",
|
114
|
+
'/[qwe&&[^ty&&[^uip](?<foo>bar)]]/ =~ "baz"; foo +1',
|
115
|
+
"/[qwe&&[^ty&&[^uip](?'foo'bar)]]/ =~ 'baz'; foo +1",
|
116
|
+
'/[qwe&&[^ty&&[^uip(?<foo>bar)]]]/ =~ "baz"; foo +1',
|
117
|
+
"/[qwe&&[^ty&&[^uip(?'foo'bar)]]]/ =~ 'baz'; foo +1",
|
118
|
+
|
119
|
+
'/z\\(?<foo>bar)/ =~ "baz"; foo +1',
|
120
|
+
"/z\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
121
|
+
'/z\\c(?<foo>bar)/ =~ "baz"; foo +1',
|
122
|
+
"/z\\c(?'foo'bar)/ =~ 'baz'; foo +1",
|
123
|
+
'/z\\C-(?<foo>bar)/ =~ "baz"; foo +1',
|
124
|
+
"/z\\C-(?'foo'bar)/ =~ 'baz'; foo +1",
|
125
|
+
'/z\\M-(?<foo>bar)/ =~ "baz"; foo +1',
|
126
|
+
"/z\\M-(?'foo'bar)/ =~ 'baz'; foo +1",
|
127
|
+
'/z\\\\\\(?<foo>bar)/ =~ "baz"; foo +1',
|
128
|
+
"/z\\\\\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
129
|
+
'/z\\\\c\\(?<foo>bar)/ =~ "baz"; foo +1',
|
130
|
+
"/z\\\\c\\(?'foo'bar)/ =~ 'baz'; foo +1",
|
131
|
+
'/z(?#(?<foo>bar))/ =~ "baz"; foo +1',
|
132
|
+
"/z(?#(?'foo'bar))/ =~ 'baz'; foo +1",
|
133
|
+
'/z[(?<foo>bar)]/ =~ "baz"; foo +1',
|
134
|
+
"/z[(?'foo'bar)]/ =~ 'baz'; foo +1",
|
135
|
+
'/z[qwe&&[^ty](?<foo>bar)]/ =~ "baz"; foo +1',
|
136
|
+
"/z[qwe&&[^ty](?'foo'bar)]/ =~ 'baz'; foo +1",
|
137
|
+
'/z[qwe&&[^(?<foo>bar)]]/ =~ "baz"; foo +1',
|
138
|
+
"/z[qwe&&[^(?'foo'bar)]]/ =~ 'baz'; foo +1",
|
139
|
+
'/z[qwe&&[^ty&&[^uip]](?<foo>bar)]/ =~ "baz"; foo +1',
|
140
|
+
"/z[qwe&&[^ty&&[^uip]](?'foo'bar)]/ =~ 'baz'; foo +1",
|
141
|
+
'/z[qwe&&[^ty&&[^uip](?<foo>bar)]]/ =~ "baz"; foo +1',
|
142
|
+
"/z[qwe&&[^ty&&[^uip](?'foo'bar)]]/ =~ 'baz'; foo +1",
|
143
|
+
'/z[qwe&&[^ty&&[^uip(?<foo>bar)]]]/ =~ "baz"; foo +1',
|
144
|
+
"/z[qwe&&[^ty&&[^uip(?'foo'bar)]]]/ =~ 'baz'; foo +1",
|
145
|
+
]
|
146
|
+
end
|
@@ -8,9 +8,13 @@ module TestCases
|
|
8
8
|
ILLEGAL_STANZAS=IO.read(rldir+'/rubylexer/test/illegal_stanzas.rb').split("\n\n").grep(/./).reverse
|
9
9
|
|
10
10
|
datadir=$:.find{|dir| File.exist? dir+'/../test/data/p.rb' }
|
11
|
-
FILENAMES=Dir[datadir+'/../test/data
|
11
|
+
FILENAMES=Dir[datadir+'/../test/data/*.rb'].reject{|fn| File.directory? fn}
|
12
12
|
FILES=FILENAMES.map{|fn| File.read fn }
|
13
13
|
|
14
|
+
ILLEGAL_FILENAMES=(Dir[datadir+'/../test/data/*']-Dir[datadir+'/../test/data/*.rb'])
|
15
|
+
ILLEGAL_FILENAMES.reject!{|fn| File.directory? fn}
|
16
|
+
ILLEGAL_FILES=ILLEGAL_FILENAMES.map{|fn| File.read fn }
|
17
|
+
|
14
18
|
TESTCASES=ONELINERS+STANZAS+FILES
|
15
|
-
ILLEGAL_TESTCASES=ILLEGAL_ONELINERS+ILLEGAL_STANZAS
|
19
|
+
ILLEGAL_TESTCASES=ILLEGAL_ONELINERS+ILLEGAL_STANZAS+ILLEGAL_FILES
|
16
20
|
end
|
data/lib/rubylexer/token.rb
CHANGED
@@ -63,17 +63,24 @@ class KeywordToken < WToken #also some operators
|
|
63
63
|
@callsite if defined? @callsite
|
64
64
|
end
|
65
65
|
|
66
|
+
attr_accessor :value
|
66
67
|
|
67
68
|
#-----------------------------------
|
68
69
|
def set_infix!
|
69
70
|
@infix=true
|
70
71
|
end
|
71
72
|
|
73
|
+
#-----------------------------------
|
74
|
+
def unary= flag
|
75
|
+
@infix=!flag
|
76
|
+
end
|
77
|
+
|
72
78
|
#-----------------------------------
|
73
79
|
def infix?
|
74
80
|
@infix ||= nil
|
75
81
|
end
|
76
82
|
def prefix?; !infix? end
|
83
|
+
alias unary prefix?
|
77
84
|
|
78
85
|
#-----------------------------------
|
79
86
|
def has_end!
|
@@ -103,9 +110,16 @@ end
|
|
103
110
|
#-------------------------
|
104
111
|
class OperatorToken < WToken
|
105
112
|
attr_accessor :unary
|
113
|
+
attr_writer :as
|
106
114
|
alias prefix? unary
|
107
115
|
def infix?; !prefix? end
|
108
116
|
|
117
|
+
def as
|
118
|
+
return @as if defined? @as
|
119
|
+
if tag and ident[/^[,*&]$/]
|
120
|
+
tag.to_s+ident
|
121
|
+
end
|
122
|
+
end
|
109
123
|
end
|
110
124
|
|
111
125
|
|
@@ -212,6 +226,8 @@ class StringToken < Token
|
|
212
226
|
|
213
227
|
attr_accessor :open #exact sequence of chars used to start the str
|
214
228
|
attr_accessor :close #exact seq of (1) char to stop the str
|
229
|
+
|
230
|
+
attr_accessor :lvars #names used in named backrefs if this is a regex
|
215
231
|
|
216
232
|
def with_line(line)
|
217
233
|
@line=line
|
@@ -255,16 +271,16 @@ class StringToken < Token
|
|
255
271
|
ender=close
|
256
272
|
elems.each{|e|
|
257
273
|
case e
|
258
|
-
when String
|
274
|
+
when String; result<<e
|
259
275
|
# strfrag=translate_escapes strfrag if RubyLexer::FASTER_STRING_ESCAPES
|
260
276
|
# result << send(transname,strfrag,starter,ender)
|
261
|
-
when VarNameToken
|
277
|
+
when VarNameToken;
|
262
278
|
if /^[$@]/===e.to_s
|
263
279
|
result << '#' + e.to_s
|
264
280
|
else
|
265
281
|
result << "\#{#{e}}"
|
266
282
|
end
|
267
|
-
when RubyCode
|
283
|
+
when RubyCode; result << '#' + e.to_s
|
268
284
|
else fail
|
269
285
|
end
|
270
286
|
}
|
@@ -429,7 +445,7 @@ class HerePlaceholderToken < WToken
|
|
429
445
|
|
430
446
|
#@termex=/^#{'[\s\v]*' if dash}#{Regexp.escape ender}$/
|
431
447
|
@termex=Regexp.new \
|
432
|
-
["^", ('[\s\v]*' if dash), Regexp.escape(ender), "$"].
|
448
|
+
["^", ('[\s\v]*' if dash), Regexp.escape(ender), "$"].join
|
433
449
|
@bodyclass=HereBodyToken
|
434
450
|
end
|
435
451
|
|
@@ -442,7 +458,7 @@ class HerePlaceholderToken < WToken
|
|
442
458
|
else
|
443
459
|
@ender
|
444
460
|
end
|
445
|
-
return ["<<",@dash,@quote_real&&@quote,result,@quote_real&&@quote].
|
461
|
+
return ["<<",@dash,@quote_real&&@quote,result,@quote_real&&@quote].join
|
446
462
|
# else
|
447
463
|
# assert !unsafe_to_use
|
448
464
|
# return @string.to_s
|
@@ -557,7 +573,7 @@ EndDefHeaderToken=EndHeaderToken
|
|
557
573
|
|
558
574
|
#-------------------------
|
559
575
|
class EscNlToken < IgnoreToken
|
560
|
-
def initialize(
|
576
|
+
def initialize(ident,offset,filename=nil,linenum=nil)
|
561
577
|
super(ident,offset)
|
562
578
|
#@char='\\'
|
563
579
|
@filename=filename
|
@@ -87,9 +87,9 @@ end
|
|
87
87
|
end end
|
88
88
|
class ZwToken; def ws_munge(tp)
|
89
89
|
case tp.showzw
|
90
|
-
when 2
|
91
|
-
when 1
|
92
|
-
when 0
|
90
|
+
when 2; explicit_form_all
|
91
|
+
when 1; explicit_form
|
92
|
+
when 0; nil
|
93
93
|
else raise 'unknown showzw'
|
94
94
|
end
|
95
95
|
end end
|
@@ -117,7 +117,7 @@ class KeepWsTokenPrinter
|
|
117
117
|
def pprint(tok,output=$stdout)
|
118
118
|
@accum<<aprint(tok).to_s
|
119
119
|
if (@accum.size>ACCUMSIZE and NewlineToken===tok) or EoiToken===tok
|
120
|
-
output.print(@accum)
|
120
|
+
output.print(@accum.join)
|
121
121
|
@accum=[]
|
122
122
|
end
|
123
123
|
end
|
@@ -139,10 +139,10 @@ class KeepWsTokenPrinter
|
|
139
139
|
result=
|
140
140
|
case tok
|
141
141
|
when ZwToken,EoiToken,NoWsToken, HereBodyToken, NewlineToken,
|
142
|
-
ImplicitParamListStartToken,ImplicitParamListEndToken
|
142
|
+
ImplicitParamListStartToken,ImplicitParamListEndToken;
|
143
143
|
tok
|
144
144
|
else
|
145
|
-
|
145
|
+
@sep.dup<<tok.to_s
|
146
146
|
end unless NoWsToken===lasttok
|
147
147
|
|
148
148
|
if str_needs_escnls
|
data/lib/rubylexer/version.rb
CHANGED
data/rubylexer.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require "#{File.dirname(__FILE__)}/lib/rubylexer/version"
|
4
|
+
RubyLexer::Description=open("README.txt"){|f| f.read[/^==+ ?description[^\n]*?\n *\n?(.*?\n *\n.*?)\n *\n/im,1] }
|
5
|
+
RubyLexer::Latest_changes="###"+open("History.txt"){|f| f.read[/\A===(.*?)(?====)/m,1] }
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "rubylexer"
|
9
|
+
s.version = RubyLexer::VERSION
|
10
|
+
s.date = Time.now.strftime("%Y-%m-%d")
|
11
|
+
s.authors = ["Caleb Clausen"]
|
12
|
+
s.email = %q{caleb (at) inforadical (dot) net}
|
13
|
+
s.summary = "RubyLexer is a lexer library for Ruby, written in Ruby."
|
14
|
+
s.description = RubyLexer::Description
|
15
|
+
s.homepage = %{http://github.com/coatl/rubylexer}
|
16
|
+
s.rubyforge_project = %q{rubylexer}
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split
|
19
|
+
s.test_files = %w[test/test_all.rb]
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.extra_rdoc_files = ["README.txt", "COPYING"]
|
22
|
+
s.has_rdoc = true
|
23
|
+
s.rdoc_options = %w[--main README.txt]
|
24
|
+
|
25
|
+
s.rubygems_version = %q{1.3.0}
|
26
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
27
|
+
|
28
|
+
if s.respond_to? :specification_version then
|
29
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
30
|
+
s.specification_version = 2
|
31
|
+
|
32
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
33
|
+
s.add_runtime_dependency("sequence", [">= 0.2.3"])
|
34
|
+
else
|
35
|
+
s.add_dependency("sequence", [">= 0.2.3"])
|
36
|
+
end
|
37
|
+
else
|
38
|
+
s.add_dependency("sequence", [">= 0.2.3"])
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rubylexer'
|
3
|
+
require 'term/ansicolor'
|
4
|
+
|
5
|
+
|
6
|
+
def coloruby file,fd=open(file)
|
7
|
+
lexer=RubyLexer.new(file,fd)
|
8
|
+
begin
|
9
|
+
token=lexer.get1token
|
10
|
+
print token.colorize
|
11
|
+
end until RubyLexer::EoiToken===token
|
12
|
+
ensure
|
13
|
+
print Term::ANSIColor.reset
|
14
|
+
end
|
15
|
+
|
16
|
+
class RubyLexer
|
17
|
+
class Token
|
18
|
+
include Term::ANSIColor
|
19
|
+
|
20
|
+
def colorize
|
21
|
+
color+ident.to_s
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class VarNameToken
|
26
|
+
alias color blue
|
27
|
+
end
|
28
|
+
|
29
|
+
class MethNameToken
|
30
|
+
alias color green
|
31
|
+
end
|
32
|
+
|
33
|
+
class OperatorToken
|
34
|
+
alias color cyan
|
35
|
+
end
|
36
|
+
|
37
|
+
class KeywordToken
|
38
|
+
def colorize
|
39
|
+
if /[^a-z]/i===ident
|
40
|
+
yellow+ident
|
41
|
+
else
|
42
|
+
red+ident
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class WsToken
|
48
|
+
def colorize
|
49
|
+
black+ident
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class NewlineToken
|
54
|
+
alias color black
|
55
|
+
end
|
56
|
+
|
57
|
+
class ZwToken
|
58
|
+
def colorize; '' end
|
59
|
+
end
|
60
|
+
|
61
|
+
class FileAndLineToken
|
62
|
+
def colorize; '' end
|
63
|
+
end
|
64
|
+
|
65
|
+
class ImplicitParamListStartToken
|
66
|
+
def colorize; '' end
|
67
|
+
end
|
68
|
+
|
69
|
+
class ImplicitParamListEndToken
|
70
|
+
def colorize; '' end
|
71
|
+
end
|
72
|
+
|
73
|
+
class IgnoreToken
|
74
|
+
def colorize
|
75
|
+
dark+green+ident+reset
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
class EscNlToken
|
80
|
+
def colorize
|
81
|
+
yellow+ident
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
class NumberToken
|
86
|
+
def colorize
|
87
|
+
dark+blue+ident+reset
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class SymbolToken
|
92
|
+
def colorize
|
93
|
+
if StringToken===ident
|
94
|
+
dark+blue+':'+ident.colorize+reset
|
95
|
+
else
|
96
|
+
dark+blue+ident+reset
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
class StringToken
|
102
|
+
def colorize
|
103
|
+
magenta+open+
|
104
|
+
elems.map{|elem|
|
105
|
+
if String===elem
|
106
|
+
magenta+elem
|
107
|
+
else
|
108
|
+
yellow+'#'+elem.colorize
|
109
|
+
end
|
110
|
+
}.join+
|
111
|
+
magenta+close
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
class RubyCode
|
116
|
+
def colorize
|
117
|
+
ident.map{|tok| tok.colorize }.join
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class HerePlaceholderToken
|
122
|
+
def colorize
|
123
|
+
"#{blue}<<#{'-' if @dash}#{ender}"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
class HereBodyToken
|
128
|
+
def colorize
|
129
|
+
headtok.string.colorize
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class EoiToken
|
134
|
+
def colorize
|
135
|
+
return '' #gyaah, @offset has off by one errors
|
136
|
+
data=begin
|
137
|
+
@file.pos=@offset-1
|
138
|
+
@file.read
|
139
|
+
rescue
|
140
|
+
@file[@offset-1..-1]
|
141
|
+
end
|
142
|
+
dark+green+data+reset
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
if __FILE__==$0
|
148
|
+
if ARGV.first=='-e'
|
149
|
+
coloruby ARGV[1],ARGV[1]
|
150
|
+
else
|
151
|
+
coloruby ARGV.first
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|