This repository has been archived by the owner on Feb 6, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
lexer.cpp
105 lines (102 loc) · 2.61 KB
/
lexer.cpp
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
101
102
103
104
105
#include "lexer.h"
#include <stdexcept>
int transTable(char c, int st) {
switch (st) {
case 0:
if (c >= '0' && c <= '9')
return 1;
else if (c == '+' || c == '*' || c == '/' || c == '-' || c == '^')
return 6;
else if ((c >= 'a' && c <= 'z') || c == '_')
return 7;
else if (c == '(')
return 8;
else if (c == ')')
return 9;
else if (c == ',')
return 10;
else if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
return 0;
break;
case 1:
if (c >= '0' && c <= '9')
return 1;
else if (c == '.')
return 2;
else if (c == 'e' || c == 'E')
return 3;
break;
case 2:
if (c >= '0' && c <= '9')
return 2;
else if (c == 'e' || c == 'E')
return 3;
break;
case 3:
if (c >= '0' && c <= '9')
return 5;
else if (c == '+' || c == '-')
return 4;
break;
case 4:
if (c >= '0' && c <= '9')
return 5;
break;
case 5:
if (c >= '0' && c <= '9')
return 5;
break;
case 6:
break;
case 7:
if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_')
return 7;
break;
}
return -1;
}
Lexer::Lexer(const std::string &input) : input(input), curChIx(0) {}
Token Lexer::getNextToken() {
std::string buf;
std::size_t lastAccChIx = curChIx;
int curSt = 0;
Token resultToken{TokenType::Invalid};
while (curSt != -1) {
if (curSt == 1 || curSt == 2 || curSt == 5) {
resultToken.type = TokenType::Number;
resultToken.attribute = buf;
lastAccChIx = curChIx;
} else if (curSt == 6) {
resultToken.type = TokenType::Operator;
resultToken.attribute = buf;
lastAccChIx = curChIx;
} else if (curSt == 7) {
resultToken.type = TokenType::Id;
resultToken.attribute = buf;
lastAccChIx = curChIx;
} else if (curSt == 8) {
resultToken.type = TokenType::LParen;
resultToken.attribute = buf;
lastAccChIx = curChIx;
} else if (curSt == 9) {
resultToken.type = TokenType::RParen;
resultToken.attribute = buf;
lastAccChIx = curChIx;
} else if (curSt == 10) {
resultToken.type = TokenType::Comma;
resultToken.attribute = buf;
lastAccChIx = curChIx;
}
if (curChIx >= input.size())
break;
char curCh = input[curChIx];
curChIx += 1;
curSt = transTable(curCh, curSt);
if (curSt > 0) // пропуск пробельных символов
buf += curCh;
}
// if (resultToken.type == TokenType::Invalid)
// throw new std::runtime_error("Invalid token in input " + input);
curChIx = lastAccChIx;
return resultToken;
}