Skip to content

Commit f688a6d

Browse files
committed
io scanner from redmine
1 parent 3effca8 commit f688a6d

File tree

1 file changed

+134
-0
lines changed
  • lib/coderay/scanners

1 file changed

+134
-0
lines changed

lib/coderay/scanners/io.rb

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
module CodeRay module Scanners
2+
3+
#A simple scanner for a simple language: Io
4+
5+
class Io < Scanner
6+
7+
register_for :io
8+
9+
RESERVED_WORDS = [ 'clone','init', 'method', 'list', 'vector', 'block', 'if','ifTrue','ifFalse','ifTrueIfFalse','then', 'for','loop',
10+
'reverseForeach','foreach','map','continue','break','while','do','return',
11+
'self','sender','target','proto','parent','protos']
12+
13+
PREDEFINED_TYPES = []
14+
15+
PREDEFINED_CONSTANTS = ['Object', 'Lobby',
16+
'TRUE','true','FALSE','false','NULL','null','Null','Nil','nil','YES','NO']
17+
18+
IDENT_KIND = WordList.new(:ident).
19+
add(RESERVED_WORDS, :reserved).
20+
add(PREDEFINED_TYPES, :pre_type).
21+
add(PREDEFINED_CONSTANTS, :pre_constant)
22+
23+
ESCAPE = / [rbfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
24+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
25+
26+
def scan_tokens tokens, options
27+
28+
state = :initial
29+
30+
until eos?
31+
32+
kind = :error
33+
match = nil
34+
35+
if state == :initial
36+
37+
if scan(/ \s+ | \\\n /x)
38+
kind = :space
39+
40+
elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
41+
kind = :comment
42+
43+
44+
elsif scan(/ [-+*\/\$\@=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
45+
kind = :operator
46+
47+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
48+
kind = IDENT_KIND[match]
49+
if kind == :ident and check(/:(?!:)/)
50+
match << scan(/:/)
51+
kind = :label
52+
end
53+
54+
elsif match = scan(/L?"/)
55+
tokens << [:open, :string]
56+
if match[0] == ?L
57+
tokens << ['L', :modifier]
58+
match = '"'
59+
end
60+
state = :string
61+
kind = :delimiter
62+
63+
elsif scan(/#\s*(\w*)/)
64+
kind = :preprocessor # FIXME multiline preprocs
65+
state = :include_expected if self[1] == 'include'
66+
67+
elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
68+
kind = :char
69+
70+
elsif scan(/0[xX][0-9A-Fa-f]+/)
71+
kind = :hex
72+
73+
elsif scan(/(?:0[0-7]+)(?![89.eEfF])/)
74+
kind = :oct
75+
76+
elsif scan(/(?:\d+)(?![.eEfF])/)
77+
kind = :integer
78+
79+
elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
80+
kind = :float
81+
82+
else
83+
getch
84+
end
85+
86+
elsif state == :string
87+
if scan(/[^\\"]+/)
88+
kind = :content
89+
elsif scan(/"/)
90+
tokens << ['"', :delimiter]
91+
tokens << [:close, :string]
92+
state = :initial
93+
next
94+
elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
95+
kind = :char
96+
elsif scan(/ \\ | $ /x)
97+
kind = :error
98+
state = :initial
99+
else
100+
raise "else case \" reached; %p not handled." % peek(1), tokens
101+
end
102+
103+
elsif state == :include_expected
104+
if scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
105+
kind = :include
106+
state = :initial
107+
108+
elsif match = scan(/\s+/)
109+
kind = :space
110+
state = :initial if match.index ?\n
111+
112+
else
113+
getch
114+
115+
end
116+
117+
else
118+
raise 'else-case reached', tokens
119+
120+
end
121+
122+
match ||= matched
123+
raise [match, kind], tokens if kind == :error
124+
125+
tokens << [match, kind]
126+
127+
end
128+
129+
tokens
130+
end
131+
132+
end
133+
134+
end end

0 commit comments

Comments
 (0)