-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLexer.cs
96 lines (82 loc) · 2.37 KB
/
Lexer.cs
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using SimpleInterpreter.Types;
namespace SimpleInterpreter.Lexer;
public class Lexer(string source)
{
private readonly string source = source;
private int start = 0, end = 0, line = 1;
private readonly Dictionary<string, TokenType> opsType = new() {
{ "+", TokenType.PLUS },
{ "-", TokenType.MINUS },
{ "*", TokenType.STAR },
{ "/", TokenType.SLASH },
{ "(", TokenType.LEFT_PARENT },
{ ")", TokenType.RIGHT_PARENT },
{ ";", TokenType.SEMICOLON }
};
private bool isAtEnd() => end >= source.Length;
private char peek()
{
if (!isAtEnd())
{
return source[end];
}
return '\0';
}
private void advance()
{
if (peek() == '\n')
{
line++;
}
end++;
}
private char take()
{
var c = peek();
advance();
return c;
}
private Token? prase()
{
var c = take();
switch (c)
{
case char space when char.IsWhiteSpace(space):
return null;
case char op when op == '+' || op == '-' || op == '*' || op == '/' || op == '(' || op == ')' || op == ';':
return new Token(opsType[op.ToString()], op.ToString(), null, line);
case char number when char.IsDigit(number):
while (!isAtEnd() && char.IsDigit(peek()))
{
advance();
}
if (!isAtEnd() && peek() == '.')
{
advance();
while (!isAtEnd() && char.IsDigit(peek()))
{
advance();
}
}
string lexeme = source[start..end];
return new Token(TokenType.NUMBER, lexeme, float.Parse(lexeme), line);
default:
throw new ArgumentException($"{line}:{c} is an illegal symbol");
}
}
public IEnumerable<Token> scan()
{
var tokens = Enumerable.Empty<Token>();
while (!isAtEnd())
{
var token = prase();
if (token is not null)
{
tokens = tokens.Append(token);
}
start = end;
}
tokens = tokens.Append(new Token(TokenType.EOF, "", null, line));
return tokens;
}
}