-
Notifications
You must be signed in to change notification settings - Fork 0
/
tokenizer.rb
50 lines (48 loc) · 1.34 KB
/
tokenizer.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
require 'strscan'
class Tokenizer
def tokenize(str, eof = true)
ss = StringScanner.new(str)
tokens = []
until ss.empty?
case
when ss.scan(/\s/)
# do nothing
when ss.scan(/\d+/)
tokens << [:int, ss.matched]
when ss.scan(/\d+\.\d+/)
tokens << [:float, ss.matched]
when ss.scan(/return/)
tokens << [:return]
when ss.scan(/if/)
tokens << [:if]
when ss.scan(/else/)
tokens << [:else]
when ss.scan(/for/)
tokens << [:for]
when ss.scan(/while/)
tokens << [:while]
when ss.scan(/\w+/)
tokens << [:iden, ss.matched]
when ss.scan(/(\+\+)|(\-\-)/)
tokens << [:postfix_operator, ss.matched]
when ss.scan(/[\(\)\{\},;]/)
tokens << [ss.matched]
when ss.scan(/(\+=)|(\-=)|(\*=)|(\/=)/)
tokens << [:assignment_operator, ss.matched]
when ss.scan(/[\+\-]/)
tokens << [:additive_operator, ss.matched]
when ss.scan(/[\*\/]/)
tokens << [:multiplicative_operator, ss.matched]
when ss.scan(/(==)|(!=)|(<=)|(>=)|>|</)
tokens << [:relational_operator, ss.matched]
when ss.scan(/=/)
tokens << [:assignment_operator, ss.matched]
else
p ss
raise "unknown token"
end
end
tokens << [:eof] if eof
tokens
end
end