-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMathLexer.cs
More file actions
100 lines (79 loc) · 2.51 KB
/
MathLexer.cs
File metadata and controls
100 lines (79 loc) · 2.51 KB
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
97
98
99
100
using System.Text;
namespace MathExpressionParser;
internal class MathLexer(string text) {
public readonly string Text = text;
public int Position;
public char Peek(int offset = 0) {
return Text[Position + offset];
}
public void Advance(int amt = 1) {
Position += amt;
}
public bool Finished() {
return Position >= Text.Length;
}
public Token ReadNumber() {
var builder = new StringBuilder();
char ch;
while (!Finished() && char.IsAsciiDigit(ch = Peek())) {
builder.Append(ch);
Advance();
}
return new Token(TokenType.Number, decimal.Parse(builder.ToString()));
}
public Token ReadIdentifier() {
var builder = new StringBuilder();
builder.Append(Peek());
Advance();
char ch;
while (!Finished() && char.IsAsciiLetterOrDigit(ch = Peek())) {
builder.Append(ch);
Advance();
}
return new Token(TokenType.Identifier, builder.ToString());
}
public Token? ReadNextToken() {
char ch = Peek();
if (char.IsWhiteSpace(ch)) {
Advance();
return null;
}
if (char.IsAsciiLetter(ch)) {
return ReadIdentifier();
}
if (char.IsAsciiDigit(ch)) {
return ReadNumber();
}
Advance();
return ch switch {
'(' => new Token(TokenType.OpenPar),
')' => new Token(TokenType.ClosePar),
'+' => new Token(TokenType.Plus),
'-' => new Token(TokenType.Minus),
'*' => new Token(TokenType.Star),
'/' => new Token(TokenType.Slash),
'^' => new Token(TokenType.Caret),
',' => new Token(TokenType.Comma),
_ => throw new MathParseException($"Unexpected character '{ch}'")
};
}
public List<Token> Lex() {
List<Token> tokens = [];
while (!Finished()) {
var token = ReadNextToken();
if (token != null)
tokens.Add(token);
}
tokens.Add(new Token(TokenType.Eof));
return tokens;
}
public static void PrintTokens(List<Token> tokens) {
foreach (var token in tokens) {
Console.Write(token.Type);
if (token.Value != null) {
Console.Write($": {token.Value}");
}
Console.WriteLine();
}
}
}