Skip to content

Commit 2b9a731

Browse files
committed
VHDL scanner by Andreas Schwarz
1 parent 3effca8 commit 2b9a731

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

lib/coderay/scanners/vhdl.rb

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
module CodeRay
2+
module Scanners
3+
4+
# by Andreas Schwarz
5+
class VHDL < Scanner
6+
7+
register_for :vhdl
8+
9+
RESERVED_WORDS = [
10+
'access','after','alias','all','assert','architecture','begin',
11+
'block','body','buffer','bus','case','component','configuration','constant',
12+
'disconnect','downto','else','elsif','end','entity','exit','file','for',
13+
'function','generate','generic','group','guarded','if','impure','in',
14+
'inertial','inout','is','label','library','linkage','literal','loop',
15+
'map','new','next','null','of','on','open','others','out','package',
16+
'port','postponed','procedure','process','pure','range','record','register',
17+
'reject','report','return','select','severity','signal','shared','subtype',
18+
'then','to','transport','type','unaffected','units','until','use','variable',
19+
'wait','when','while','with','note','warning','error','failure','and',
20+
'or','xor','not','nor',
21+
'array'
22+
]
23+
24+
PREDEFINED_TYPES = [
25+
'bit','bit_vector','character','boolean','integer','real','time','string',
26+
'severity_level','positive','natural','signed','unsigned','line','text',
27+
'std_logic','std_logic_vector','std_ulogic','std_ulogic_vector','qsim_state',
28+
'qsim_state_vector','qsim_12state','qsim_12state_vector','qsim_strength',
29+
'mux_bit','mux_vector','reg_bit','reg_vector','wor_bit','wor_vector'
30+
]
31+
32+
PREDEFINED_CONSTANTS = [
33+
34+
]
35+
36+
IDENT_KIND = CaseIgnoringWordList.new(:ident).
37+
add(RESERVED_WORDS, :reserved).
38+
add(PREDEFINED_TYPES, :pre_type).
39+
add(PREDEFINED_CONSTANTS, :pre_constant)
40+
41+
ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
42+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x
43+
44+
def scan_tokens tokens, options
45+
46+
state = :initial
47+
48+
until eos?
49+
50+
kind = nil
51+
match = nil
52+
53+
case state
54+
55+
when :initial
56+
57+
if scan(/ \s+ | \\\n /x)
58+
kind = :space
59+
60+
elsif scan(/-- .*/x)
61+
kind = :comment
62+
63+
elsif scan(/ [-+*\/=<>?:;,!&^|()\[\]{}~%]+ | \.(?!\d) /x)
64+
kind = :operator
65+
66+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
67+
kind = IDENT_KIND[match.downcase]
68+
69+
elsif match = scan(/[a-z]?"/i)
70+
tokens << [:open, :string]
71+
state = :string
72+
kind = :delimiter
73+
74+
elsif scan(/ L?' (?: [^\'\n\\] | \\ #{ESCAPE} )? '? /ox)
75+
kind = :char
76+
77+
elsif scan(/(?:\d+)(?![.eEfF])/)
78+
kind = :integer
79+
80+
elsif scan(/\d[fF]?|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/)
81+
kind = :float
82+
83+
else
84+
getch
85+
kind = :error
86+
87+
end
88+
89+
when :string
90+
if scan(/[^\\\n"]+/)
91+
kind = :content
92+
elsif scan(/"/)
93+
tokens << ['"', :delimiter]
94+
tokens << [:close, :string]
95+
state = :initial
96+
next
97+
elsif scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
98+
kind = :char
99+
elsif scan(/ \\ | $ /x)
100+
tokens << [:close, :string]
101+
kind = :error
102+
state = :initial
103+
else
104+
raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
105+
end
106+
107+
else
108+
raise_inspect 'Unknown state', tokens
109+
110+
end
111+
112+
match ||= matched
113+
if $DEBUG and not kind
114+
raise_inspect 'Error token %p in line %d' %
115+
[[match, kind], line], tokens
116+
end
117+
raise_inspect 'Empty token', tokens unless match
118+
119+
tokens << [match, kind]
120+
121+
end
122+
123+
if state == :string
124+
tokens << [:close, :string]
125+
end
126+
127+
tokens
128+
end
129+
130+
end
131+
132+
end
133+
end

0 commit comments

Comments
 (0)