Line data Source code
1 : #include "../../../../inc/parsingAnalysis/algorithm/topDown.h"
2 :
3 : namespace nicole {
4 :
5 : const std::expected<std::shared_ptr<AST>, Error>
6 0 : TopDown::parseFactor() const noexcept {
7 0 : const auto firsToken{tkStream_.current()};
8 0 : const std::string raw{tkStream_.current()->raw()};
9 0 : const std::string loc{tkStream_.current()->locInfo()};
10 0 : switch (tkStream_.current()->type()) {
11 :
12 0 : case TokenType::THIS: {
13 0 : if (!tkStream_.eat()) {
14 0 : break;
15 0 : }
16 0 : return Builder::createThis(SourceLocation{*firsToken, *tkStream_.lastRead()});
17 0 : }
18 :
19 0 : case TokenType::TRUE: {
20 0 : if (!tkStream_.eat()) {
21 0 : break;
22 0 : }
23 0 : return Builder::createBool(SourceLocation{*firsToken, *tkStream_.lastRead()}, true);
24 0 : }
25 :
26 0 : case TokenType::FALSE: {
27 0 : if (!tkStream_.eat()) {
28 0 : break;
29 0 : }
30 0 : return Builder::createBool(SourceLocation{*firsToken, *tkStream_.lastRead()},false);
31 0 : }
32 :
33 0 : case TokenType::NUMBER_INT: {
34 0 : const int value{std::stoi(raw)};
35 0 : if (!tkStream_.eat()) {
36 0 : break;
37 0 : }
38 0 : return Builder::createInt(SourceLocation{*firsToken, *tkStream_.lastRead()},value);
39 0 : }
40 :
41 0 : case TokenType::NUMBER_DOUBLE: {
42 0 : const double value{std::stod(raw)};
43 0 : if (!tkStream_.eat()) {
44 0 : break;
45 0 : }
46 0 : return Builder::createDouble(SourceLocation{*firsToken, *tkStream_.lastRead()},value);
47 0 : }
48 :
49 0 : case TokenType::NUMBER_FLOAT: {
50 0 : const float value{std::stof(raw.substr(1))};
51 0 : if (!tkStream_.eat()) {
52 0 : break;
53 0 : }
54 0 : return Builder::createFloat(SourceLocation{*firsToken, *tkStream_.lastRead()},value);
55 0 : }
56 :
57 0 : case TokenType::STRING: {
58 0 : const std::string value{raw};
59 0 : if (!tkStream_.eat()) {
60 0 : break;
61 0 : }
62 0 : return Builder::createString(SourceLocation{*firsToken, *tkStream_.lastRead()},value);
63 0 : }
64 :
65 0 : case TokenType::CHAR: {
66 0 : const std::string value{raw};
67 0 : if (!tkStream_.eat()) {
68 0 : break;
69 0 : }
70 0 : return Builder::createChar(SourceLocation{*firsToken, *tkStream_.lastRead()},value);
71 0 : }
72 :
73 0 : case TokenType::NULLPTR: {
74 0 : if (!tkStream_.eat()) {
75 0 : break;
76 0 : }
77 0 : return Builder::createNull(SourceLocation{*firsToken, *tkStream_.lastRead()});
78 0 : }
79 :
80 0 : case TokenType::ID: {
81 0 : if (tkStream_.lookAhead(1)->type() == TokenType::DOTDOT) {
82 0 : return parseEnumAccess();
83 0 : }
84 0 : return parseChainedExpression();
85 0 : }
86 :
87 0 : case TokenType::LC: {
88 0 : return parseVector();
89 0 : }
90 :
91 0 : case TokenType::LP: {
92 0 : if (!tkStream_.eat()) {
93 0 : break;
94 0 : }
95 0 : if (tkStream_.current()->type() == TokenType::RP) {
96 0 : return createError(ERROR_TYPE::SINTAX, "empty expression at " + loc);
97 0 : }
98 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
99 0 : if (!expression || !*expression) {
100 0 : return createError(expression
101 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
102 0 : : expression.error());
103 0 : }
104 0 : if (tkStream_.current()->type() != TokenType::RP) {
105 0 : return createError(ERROR_TYPE::SINTAX,
106 0 : "missing right parenthesis at " +
107 0 : tkStream_.current()->locInfo());
108 0 : }
109 0 : if (!tkStream_.eat()) {
110 0 : break;
111 0 : }
112 0 : return expression;
113 0 : }
114 :
115 0 : case TokenType::OPERATOR_SUB: {
116 0 : const Token token{*tkStream_.current()};
117 0 : if (!tkStream_.eat()) {
118 0 : break;
119 0 : }
120 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
121 0 : if (!expression || !*expression) {
122 0 : return createError(expression
123 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
124 0 : : expression.error());
125 0 : }
126 0 : return Builder::createUnary(SourceLocation{*firsToken, *tkStream_.lastRead()},token, *expression);
127 0 : }
128 :
129 0 : case TokenType::OPERATOR_NOT: {
130 0 : const Token token{*tkStream_.current()};
131 0 : if (!tkStream_.eat()) {
132 0 : break;
133 0 : }
134 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
135 0 : if (!expression || !*expression) {
136 0 : return createError(expression
137 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
138 0 : : expression.error());
139 0 : }
140 0 : return Builder::createUnary(SourceLocation{*firsToken, *tkStream_.lastRead()},token, *expression);
141 0 : }
142 :
143 0 : case TokenType::DECREMENT: {
144 0 : const Token token{*tkStream_.current()};
145 0 : if (!tkStream_.eat()) {
146 0 : break;
147 0 : }
148 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
149 0 : if (!expression || !*expression) {
150 0 : return createError(expression
151 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
152 0 : : expression.error());
153 0 : }
154 0 : return Builder::createUnary(SourceLocation{*firsToken, *tkStream_.lastRead()},token, *expression);
155 0 : }
156 :
157 0 : case TokenType::INCREMENT: {
158 0 : const Token token{*tkStream_.current()};
159 0 : if (!tkStream_.eat()) {
160 0 : break;
161 0 : }
162 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
163 0 : if (!expression || !*expression) {
164 0 : return createError(expression
165 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
166 0 : : expression.error());
167 0 : }
168 0 : return Builder::createUnary(SourceLocation{*firsToken, *tkStream_.lastRead()},token, *expression);
169 0 : }
170 :
171 0 : case TokenType::NEW: {
172 0 : const Token token{*tkStream_.current()};
173 0 : if (!tkStream_.eat()) {
174 0 : break;
175 0 : }
176 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
177 0 : if (!expression || !*expression) {
178 0 : return createError(expression
179 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
180 0 : : expression.error());
181 0 : }
182 0 : return Builder::createNew(SourceLocation{*firsToken, *tkStream_.lastRead()},*expression);
183 0 : }
184 :
185 0 : case TokenType::OPERATOR_MULT: {
186 0 : if (!tkStream_.eat()) {
187 0 : break;
188 0 : }
189 0 : const std::expected<std::shared_ptr<AST>, Error> expression{parseOr()};
190 0 : if (!expression || !*expression) {
191 0 : return createError(expression
192 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
193 0 : : expression.error());
194 0 : }
195 0 : return Builder::createDeref(SourceLocation{*firsToken, *tkStream_.lastRead()},*expression);
196 0 : }
197 :
198 0 : default:
199 : // error
200 0 : return createError(ERROR_TYPE::SINTAX,
201 0 : "token " + raw + " is in a wrong position at " + loc);
202 0 : }
203 0 : return createError(ERROR_TYPE::SINTAX, "failed to eat " + raw + " at " + loc);
204 0 : }
205 :
206 : const std::expected<std::shared_ptr<AST_VECTOR>, Error>
207 0 : TopDown::parseVector() const noexcept {
208 0 : const auto firsToken{tkStream_.current()};
209 0 : const std::expected<std::vector<std::shared_ptr<AST>>, Error> arguemnts{
210 0 : parseArguments({TokenType::LC, TokenType::RC}, true)};
211 0 : if (!arguemnts) {
212 0 : return createError(arguemnts.error());
213 0 : }
214 0 : return Builder::createVector(SourceLocation{*firsToken, *tkStream_.lastRead()},*arguemnts);
215 0 : }
216 :
217 : const std::expected<std::vector<std::shared_ptr<AST>>, Error>
218 : TopDown::parseArguments(std::pair<TokenType, TokenType> delimiters,
219 0 : const bool canBeEmpty) const noexcept {
220 0 : if (tkStream_.current()->type() != delimiters.first) {
221 0 : return createError(ERROR_TYPE::SINTAX,
222 0 : "missing " + tokenTypeToString(delimiters.first) +
223 0 : " at " + tkStream_.current()->locInfo());
224 0 : }
225 0 : if (auto res = tryEat(); !res) {
226 0 : return createError(res.error());
227 0 : }
228 0 : if (tkStream_.current()->type() == delimiters.second and !canBeEmpty) {
229 0 : return createError(ERROR_TYPE::SINTAX,
230 0 : "empty expression at " + tkStream_.current()->locInfo());
231 0 : }
232 0 : std::vector<std::shared_ptr<AST>> params{};
233 0 : while (tkStream_.currentPos() < tkStream_.size() and
234 0 : tkStream_.current()->type() != delimiters.second) {
235 0 : const std::expected<std::shared_ptr<AST>, Error> param{parseTernary()};
236 0 : if (!param || !*param) {
237 0 : return createError(param ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
238 0 : : param.error());
239 0 : }
240 0 : params.push_back(*param);
241 0 : if (tkStream_.current()->type() == TokenType::COMMA) {
242 0 : if (auto res = tryEat(); !res) {
243 0 : return createError(res.error());
244 0 : }
245 0 : continue;
246 0 : } else if (tkStream_.current()->type() != delimiters.second) {
247 0 : return createError(ERROR_TYPE::SINTAX,
248 0 : "missing " + tokenTypeToString(delimiters.first) +
249 0 : " at " + tkStream_.current()->locInfo());
250 0 : }
251 0 : break;
252 0 : }
253 0 : if (tkStream_.current()->type() != delimiters.second) {
254 0 : return createError(ERROR_TYPE::SINTAX,
255 0 : "missing " + tokenTypeToString(delimiters.first) +
256 0 : " at " + tkStream_.current()->locInfo());
257 0 : }
258 0 : if (auto res = tryEat(); !res) {
259 0 : return createError(res.error());
260 0 : }
261 0 : return params;
262 0 : }
263 :
264 : } // namespace nicole
|