blob: 2d6b992fd8d7c40123a6917f7bd1ceac75945a4c [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
34bool Parser::parseSymbol(AstNode *node)
35{
36 skip();
37
38 if (peek().isLetter())
39 {
40 *node = AstNode(get());
41 return true;
42 }
43
44 return false;
45}
46
47bool Parser::parseIdentifier(AstNode *node)
48{
49 skip();
50
51 QString buffer;
52
53 if (peek().isUpper())
54 {
55 while (peek().isLetter() || peek() == '-' || peek() == '_' || peek().isNumber())
56 {
57 buffer += get();
58 }
59
60 *node = AstNode(buffer);
61 return true;
62 }
63
64 return false;
65}
66
67bool Parser::parseNumber(AstNode *node)
68{
69 skip();
70
71 QString buffer;
72
73 if (peek().isDigit())
74 {
75 while (peek().isDigit())
76 buffer += get();
77
78 *node = AstNode(buffer.toInt());
79 return true;
80 }
81
82 return false;
83}
84
85bool Parser::parseVariable(AstNode *node)
86{
87 skip();
88
89 int pos = _pos;
90
91 if (peek() == 's' || peek() == 'e' || peek() == 't')
92 {
93 char type = get().toLatin1();
94
95 if (peek() == '.')
96 {
97 get();
98
99 AstNode identNode;
100
101 if (parseIdentifier(&identNode))
102 {
103 *node = AstNode(type, identNode.name());
104 return true;
105 }
106 }
107 }
108
109 _pos = pos;
110 return false;
111}
112
113bool Parser::parseOne(AstNode *node)
114{
115 return parseFunction(node) ||
116 parseVariable(node) ||
117 parseNumber(node) ||
118 parseIdentifier(node) ||
119 parseSymbol(node) ||
120 parseParens(node);
121}
122
123QList<AstNode> Parser::parseMany()
124{
125 QList<AstNode> nodes;
126 AstNode next;
127
128 while (parseOne(&next))
129 {
130 nodes.append(next);
131 }
132
133 return nodes;
134}
135
136bool Parser::parseParens(AstNode *node)
137{
138 skip();
139
140 int pos = _pos;
141
142 if (peek() != '(')
143 return false;
144
145 get();
146
147 QList<AstNode> many = parseMany();
148 *node = AstNode(many);
149
150 skip();
151 if (peek() != ')')
152 {
153 _pos = pos;
154 return false;
155 }
156
157 get();
158
159 return true;
160}
161
162bool Parser::parseFunction(AstNode *node)
163{
164 skip();
165
166 int pos = _pos;
167
168 if (peek() != '<')
169 return false;
170
171 get();
172
173 AstNode head;
174 if (!parseIdentifier(&head))
175 {
176 _pos = pos;
177 return false;
178 }
179
180 QList<AstNode> body = parseMany();
181 *node = AstNode(head.name(), body);
182
183 skip();
184 if (peek() != '>')
185 {
186 _pos = pos;
187 return false;
188 }
189
190 get();
191
192 return true;
193}