blob: 145972fec732220c97992afd028c01a0aa175e86 [file] [log] [blame]
swissChilic71acc62021-12-07 08:03:37 -08001#include "Parser.h"
2
3#include <QDebug>
4
5Parser::Parser(QString input)
6{
7 _input = input;
8}
9
10QChar Parser::peek()
11{
12 if (atEnd())
13 return 0;
14
15 return _input[_pos];
16}
17
18QChar Parser::get()
19{
20 return _input[_pos++];
21}
22
23bool Parser::atEnd()
24{
25 return _pos >= _input.length();
26}
27
28void Parser::skip()
29{
30 while (peek().isSpace())
31 get();
32}
33
swissChili682e7bc2021-12-07 09:04:54 -080034template <typename T>
35bool Parser::parseSymbol(T *node)
swissChilic71acc62021-12-07 08:03:37 -080036{
37 skip();
38
39 if (peek().isLetter())
40 {
swissChili682e7bc2021-12-07 09:04:54 -080041 *node = T(get());
swissChilic71acc62021-12-07 08:03:37 -080042 return true;
43 }
44
45 return false;
46}
47
swissChili682e7bc2021-12-07 09:04:54 -080048template <typename T>
49bool Parser::parseIdentifier(T *node)
swissChilic71acc62021-12-07 08:03:37 -080050{
51 skip();
52
53 QString buffer;
54
55 if (peek().isUpper())
56 {
57 while (peek().isLetter() || peek() == '-' || peek() == '_' || peek().isNumber())
58 {
59 buffer += get();
60 }
61
swissChili682e7bc2021-12-07 09:04:54 -080062 *node = T(buffer);
swissChilic71acc62021-12-07 08:03:37 -080063 return true;
64 }
65
66 return false;
67}
68
swissChili682e7bc2021-12-07 09:04:54 -080069template <typename T>
70bool Parser::parseNumber(T *node)
swissChilic71acc62021-12-07 08:03:37 -080071{
72 skip();
73
74 QString buffer;
75
76 if (peek().isDigit())
77 {
78 while (peek().isDigit())
79 buffer += get();
80
swissChili1060c0e2021-12-09 09:46:42 -080081 *node = T::fromInteger(buffer.toInt());
swissChilic71acc62021-12-07 08:03:37 -080082 return true;
83 }
84
85 return false;
86}
87
swissChili682e7bc2021-12-07 09:04:54 -080088template <typename T>
89bool Parser::parseVariable(T *node)
swissChilic71acc62021-12-07 08:03:37 -080090{
91 skip();
92
93 int pos = _pos;
94
95 if (peek() == 's' || peek() == 'e' || peek() == 't')
96 {
97 char type = get().toLatin1();
98
99 if (peek() == '.')
100 {
101 get();
102
swissChili682e7bc2021-12-07 09:04:54 -0800103 T nameNode;
swissChilic71acc62021-12-07 08:03:37 -0800104
swissChili682e7bc2021-12-07 09:04:54 -0800105 if (parseIdentifier(&nameNode))
swissChilic71acc62021-12-07 08:03:37 -0800106 {
swissChili682e7bc2021-12-07 09:04:54 -0800107 *node = T(type, nameNode.name());
108 return true;
109 }
110 else if (parseSymbol(&nameNode))
111 {
112 *node = T(type, QString(nameNode.symbol()));
swissChilic71acc62021-12-07 08:03:37 -0800113 return true;
114 }
115 }
116 }
117
118 _pos = pos;
119 return false;
120}
121
swissChili682e7bc2021-12-07 09:04:54 -0800122template <typename T>
123QList<T> Parser::parseMany()
swissChilic71acc62021-12-07 08:03:37 -0800124{
swissChili682e7bc2021-12-07 09:04:54 -0800125 QList<T > nodes;
126 T next;
swissChilic71acc62021-12-07 08:03:37 -0800127
128 while (parseOne(&next))
129 {
130 nodes.append(next);
131 }
132
133 return nodes;
134}
135
swissChili682e7bc2021-12-07 09:04:54 -0800136template <typename T>
137bool Parser::parseParens(T *node)
swissChilic71acc62021-12-07 08:03:37 -0800138{
139 skip();
140
141 int pos = _pos;
142
143 if (peek() != '(')
144 return false;
145
146 get();
147
swissChili682e7bc2021-12-07 09:04:54 -0800148 QList<T> many = parseMany<T>();
149 *node = T(many);
swissChilic71acc62021-12-07 08:03:37 -0800150
151 skip();
152 if (peek() != ')')
153 {
154 _pos = pos;
155 return false;
156 }
157
158 get();
159
160 return true;
161}
162
163bool Parser::parseFunction(AstNode *node)
164{
165 skip();
166
167 int pos = _pos;
168
169 if (peek() != '<')
170 return false;
171
172 get();
173
174 AstNode head;
175 if (!parseIdentifier(&head))
176 {
177 _pos = pos;
178 return false;
179 }
180
swissChili682e7bc2021-12-07 09:04:54 -0800181 QList<AstNode> body = parseMany<AstNode>();
swissChilic71acc62021-12-07 08:03:37 -0800182 *node = AstNode(head.name(), body);
183
184 skip();
185 if (peek() != '>')
186 {
187 _pos = pos;
188 return false;
189 }
190
191 get();
192
193 return true;
194}
swissChili682e7bc2021-12-07 09:04:54 -0800195
196template <>
197bool Parser::parseOne<Token>(Token *node)
198{
199 return parseVariable(node) ||
200 parseNumber(node) ||
201 parseIdentifier(node) ||
202 parseSymbol(node) ||
203 parseParens(node);
204}
205
206template <>
207bool Parser::parseOne<AstNode>(AstNode *node)
208{
209 return parseFunction(node) ||
210 parseVariable(node) ||
211 parseNumber(node) ||
212 parseIdentifier(node) ||
213 parseSymbol(node) ||
214 parseParens(node);
215}
swissChili8a581c62021-12-07 13:29:21 -0800216
217bool Parser::parseSentence(Sentence *sentence)
218{
219 int pos = _pos;
220
221 QList<Token> pattern = parseMany<Token>();
222
223 skip();
224
225 if (get() != '=')
226 {
227 _pos = pos;
228 return false;
229 }
230
231 QList<AstNode> result = parseMany<AstNode>();
232
233 skip();
234
235 if (get() != ';')
236 {
237 _pos = pos;
238 return false;
239 }
240
241 *sentence = Sentence(pattern, result);
242 return true;
243}
244
245bool Parser::parseFunctionDefinition(Function *function)
246{
247 int pos = _pos;
248
249 Token identifier;
250 if (!parseIdentifier(&identifier))
251 {
252 _pos = pos;
253 return false;
254 }
255
256 QString name = identifier.name();
257 Function func(name);
258
259 skip();
260
261 if (get() != '{')
262 {
263 _pos = pos;
264 return false;
265 }
266
267 Sentence sentence;
268 while (parseSentence(&sentence))
269 {
270 func.addSentence(sentence);
271 skip();
272 }
273
274 if (get() != '}')
275 {
276 _pos = pos;
277 return false;
278 }
279
280 *function = func;
281 return true;
282}