-
Notifications
You must be signed in to change notification settings - Fork 0
/
mrcl_lexer.rb
57 lines (48 loc) · 1.17 KB
/
mrcl_lexer.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
51
52
53
54
55
56
57
require_relative "common"
KEYWORDS = [
"func", "set", "var", "call_set", "call", "return", "case", "when", "while",
"_cmt", "_debug"
]
def tokenize(src)
tokens = []
pos = 0
while pos < src.size
rest = src[pos .. -1]
case rest
when /\A([ \n]+)/
str = $1
pos += str.size
when %r{\A(//.*)$}
str = $1
pos += str.size
when /\A"(.*)"/
str = $1
tokens << Token.new(:str, str)
pos += str.size + 2
when /\A(-?[0-9]+)/
str = $1
tokens << Token.new(:int, str.to_i)
pos += str.size
when /\A(==|!=|[(){}=;+*,])/
str = $1
tokens << Token.new(:sym, str)
pos += str.size
when /\A([a-z_][a-z0-9_]*)/ # 単純化のためキーワードと識別子で同じパターンを使っています
str = $1
kind = KEYWORDS.include?(str) ? :kw : :ident
tokens << Token.new(kind, str)
pos += str.size
else
raise panic("Unsupported pattern", rest[0...100])
end
end
tokens
end
# --------------------------------
if $PROGRAM_NAME == __FILE__
in_file = ARGV[0]
tokens = tokenize(File.read(in_file))
tokens.each do |token|
puts token.to_line()
end
end