Line data Source code
1 : #include "../../../../inc/parsingAnalysis/algorithm/topDown.h"
2 :
3 : namespace nicole {
4 :
5 : const std::expected<std::shared_ptr<AST_IF>, Error>
6 0 : TopDown::parseIf() const noexcept {
7 0 : const auto firsToken{tkStream_.current()};
8 0 : if (auto res = tryEat(); !res) {
9 0 : return createError(res.error());
10 0 : }
11 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
12 0 : parseCondition(false)};
13 0 : if (!condition || !*condition) {
14 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
15 0 : : condition.error());
16 0 : }
17 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> bodyIf{parseBody()};
18 0 : if (!bodyIf || !*bodyIf) {
19 0 : return createError(bodyIf ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
20 0 : : bodyIf.error());
21 0 : }
22 0 : std::vector<std::shared_ptr<AST_ELSE_IF>> elseIfs{};
23 0 : while (tkStream_.currentPos() < tkStream_.size() and
24 0 : tkStream_.current()->type() == TokenType::ELSE and
25 0 : tkStream_.lookAhead(1)->type() == TokenType::IF) {
26 0 : const std::expected<std::shared_ptr<AST_ELSE_IF>, Error> elseIf{
27 0 : parseElseIf()};
28 0 : if (!elseIf || !*elseIf) {
29 0 : return createError(elseIf ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
30 0 : : elseIf.error());
31 0 : }
32 0 : elseIfs.push_back(*elseIf);
33 0 : }
34 0 : if (tkStream_.current()->type() != TokenType::ELSE) {
35 0 : return Builder::createIf(SourceLocation{*firsToken, *tkStream_.lastRead()},
36 0 : *condition, *bodyIf, elseIfs, nullptr);
37 0 : }
38 0 : if (auto res = tryEat(); !res) {
39 0 : return createError(res.error());
40 0 : }
41 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> bodyElse{parseBody()};
42 0 : if (!bodyElse || !*bodyElse) {
43 0 : return createError(bodyElse ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
44 0 : : bodyElse.error());
45 0 : }
46 0 : return Builder::createIf(SourceLocation{*firsToken, *tkStream_.lastRead()},
47 0 : *condition, *bodyIf, elseIfs, *bodyElse);
48 0 : }
49 :
50 : const std::expected<std::shared_ptr<AST_ELSE_IF>, Error>
51 0 : TopDown::parseElseIf() const noexcept {
52 0 : const auto firsToken{tkStream_.current()};
53 0 : if (auto res = tryEat(); !res) {
54 0 : return createError(res.error());
55 0 : }
56 0 : if (auto res = tryEat(); !res) {
57 0 : return createError(res.error());
58 0 : }
59 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
60 0 : parseCondition(false)};
61 0 : if (!condition || !*condition) {
62 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
63 0 : : condition.error());
64 0 : }
65 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
66 0 : if (!body || !*body) {
67 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
68 0 : : body.error());
69 0 : }
70 0 : return Builder::createElseIf(
71 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *condition, *body);
72 0 : }
73 :
74 : const std::expected<std::shared_ptr<AST_SWITCH>, Error>
75 0 : TopDown::parseSwitch() const noexcept {
76 0 : const auto firsToken{tkStream_.current()};
77 0 : if (auto res = tryEat(); !res) {
78 0 : return createError(res.error());
79 0 : }
80 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
81 0 : parseCondition(false)};
82 0 : if (!condition || !*condition) {
83 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
84 0 : : condition.error());
85 0 : }
86 0 : if (tkStream_.current()->type() != TokenType::LB) {
87 0 : return createError(ERROR_TYPE::SINTAX,
88 0 : "missing left bracket of switch at " +
89 0 : tkStream_.current()->locInfo());
90 0 : }
91 0 : if (auto res = tryEat(); !res) {
92 0 : return createError(res.error());
93 0 : }
94 0 : std::vector<std::shared_ptr<AST_CASE>> cases{};
95 0 : while (tkStream_.currentPos() < tkStream_.size() and
96 0 : tkStream_.current()->type() == TokenType::CASE) {
97 0 : const std::expected<std::shared_ptr<AST_CASE>, Error> switchCase{
98 0 : parseCase()};
99 0 : if (!switchCase || !*switchCase) {
100 0 : return createError(switchCase
101 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
102 0 : : switchCase.error());
103 0 : }
104 0 : cases.push_back(*switchCase);
105 0 : }
106 0 : if (!cases.size() and tkStream_.current()->type() == TokenType::RB) {
107 0 : return createError(ERROR_TYPE::SINTAX,
108 0 : "missing at least one case or default at " +
109 0 : tkStream_.current()->locInfo());
110 0 : }
111 0 : if (tkStream_.current()->type() == TokenType::RB) {
112 0 : if (auto res = tryEat(); !res) {
113 0 : return createError(res.error());
114 0 : }
115 0 : return Builder::createSwitch(
116 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *condition, cases,
117 0 : nullptr);
118 0 : }
119 0 : if (tkStream_.current()->type() != TokenType::DEFAULT) {
120 0 : return createError(ERROR_TYPE::SINTAX,
121 0 : "missing default case of switch at " +
122 0 : tkStream_.current()->locInfo());
123 0 : }
124 0 : const std::expected<std::shared_ptr<AST_DEFAULT>, Error> defaultCase{
125 0 : parseDefault()};
126 0 : if (!defaultCase || !*defaultCase) {
127 0 : return createError(defaultCase
128 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
129 0 : : defaultCase.error());
130 0 : }
131 0 : if (tkStream_.current()->type() != TokenType::RB) {
132 0 : return createError(ERROR_TYPE::SINTAX,
133 0 : "missing right bracket of switch at " +
134 0 : tkStream_.current()->locInfo());
135 0 : }
136 0 : if (auto res = tryEat(); !res) {
137 0 : return createError(res.error());
138 0 : }
139 0 : return Builder::createSwitch(
140 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *condition, cases,
141 0 : *defaultCase);
142 0 : }
143 :
144 : const std::expected<std::shared_ptr<AST_CASE>, Error>
145 0 : TopDown::parseCase() const noexcept {
146 0 : const auto firsToken{tkStream_.current()};
147 0 : if (auto res = tryEat(); !res) {
148 0 : return createError(res.error());
149 0 : }
150 0 : const std::expected<std::shared_ptr<AST>, Error> condition{parseOr()};
151 0 : if (!condition || !*condition) {
152 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
153 0 : : condition.error());
154 0 : }
155 0 : if (tkStream_.current()->type() != TokenType::DOTDOT) {
156 0 : return createError(ERROR_TYPE::SINTAX, "missing : of case at " +
157 0 : tkStream_.current()->locInfo());
158 0 : }
159 0 : if (auto res = tryEat(); !res) {
160 0 : return createError(res.error());
161 0 : }
162 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
163 0 : if (!body || !*body) {
164 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
165 0 : : body.error());
166 0 : }
167 0 : return Builder::createCase(SourceLocation{*firsToken, *tkStream_.lastRead()},
168 0 : *condition, *body);
169 0 : }
170 :
171 : const std::expected<std::shared_ptr<AST_DEFAULT>, Error>
172 0 : TopDown::parseDefault() const noexcept {
173 0 : const auto firsToken{tkStream_.current()};
174 0 : if (auto res = tryEat(); !res) {
175 0 : return createError(res.error());
176 0 : }
177 0 : const std::expected<std::shared_ptr<AST_BODY>, Error> body{parseBody()};
178 0 : if (!body || !*body) {
179 0 : return createError(body ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
180 0 : : body.error());
181 0 : }
182 0 : return Builder::createDefault(
183 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *body);
184 0 : }
185 :
186 : const std::expected<std::shared_ptr<AST>, Error>
187 0 : TopDown::parseTernary() const noexcept {
188 0 : const auto firsToken{tkStream_.current()};
189 : // to avoid ambigious situations like (something) being treated like ternary
190 0 : if (tkStream_.current()->type() == TokenType::LP and
191 0 : tkStream_.isTokenAheadBeforeSemicolon(TokenType::TERNARY)) {
192 0 : const std::expected<std::shared_ptr<AST_CONDITION>, Error> condition{
193 0 : parseCondition(false)};
194 0 : if (!condition || !*condition) {
195 0 : return createError(condition
196 0 : ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
197 0 : : condition.error());
198 0 : }
199 0 : if (tkStream_.current()->type() != TokenType::TERNARY) {
200 0 : return createError(ERROR_TYPE::SINTAX,
201 0 : "missing ? of ternary operator at " +
202 0 : tkStream_.current()->locInfo());
203 0 : }
204 0 : if (auto res = tryEat(); !res) {
205 0 : return createError(res.error());
206 0 : }
207 0 : const std::expected<std::shared_ptr<AST>, Error> first{parseOr()};
208 0 : if (!first || !*first) {
209 0 : return createError(first ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
210 0 : : first.error());
211 0 : }
212 0 : if (tkStream_.current()->type() != TokenType::DOTDOT) {
213 0 : return createError(ERROR_TYPE::SINTAX,
214 0 : "missing : of terna operator at " +
215 0 : tkStream_.current()->locInfo());
216 0 : }
217 0 : if (auto res = tryEat(); !res) {
218 0 : return createError(res.error());
219 0 : }
220 0 : const std::expected<std::shared_ptr<AST>, Error> second{parseOr()};
221 0 : if (!second || !*second) {
222 0 : return createError(second ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
223 0 : : second.error());
224 0 : }
225 0 : return Builder::createTernary(
226 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *condition, *first,
227 0 : *second);
228 0 : }
229 0 : return parseOr();
230 0 : }
231 :
232 : const std::expected<std::shared_ptr<AST_CONDITION>, Error>
233 0 : TopDown::parseCondition(const bool isInsideFor) const noexcept {
234 0 : const auto firsToken{tkStream_.current()};
235 0 : if (!isInsideFor) {
236 0 : if (tkStream_.current()->type() != TokenType::LP) {
237 0 : return createError(ERROR_TYPE::SINTAX,
238 0 : "missing left parenthesis at " +
239 0 : tkStream_.current()->locInfo());
240 0 : }
241 0 : if (auto res = tryEat(); !res) {
242 0 : return createError(res.error());
243 0 : }
244 0 : if (tkStream_.current()->type() == TokenType::RP) {
245 0 : return createError(ERROR_TYPE::SINTAX,
246 0 : "empty expression of condition at " +
247 0 : tkStream_.current()->locInfo());
248 0 : }
249 0 : }
250 0 : const std::expected<std::shared_ptr<AST>, Error> condition{parseTernary()};
251 0 : if (!condition || !*condition) {
252 0 : return createError(condition ? Error{ERROR_TYPE::NULL_NODE, "node is null"}
253 0 : : condition.error());
254 0 : }
255 0 : if (!isInsideFor) {
256 0 : if (tkStream_.current()->type() != TokenType::RP) {
257 0 : return createError(ERROR_TYPE::SINTAX,
258 0 : "missing right parenthesis of condition at " +
259 0 : tkStream_.current()->locInfo());
260 0 : }
261 0 : if (auto res = tryEat(); !res) {
262 0 : return createError(res.error());
263 0 : }
264 0 : }
265 0 : return Builder::createCondition(
266 0 : SourceLocation{*firsToken, *tkStream_.lastRead()}, *condition);
267 0 : }
268 :
269 : } // namespace nicole
|