11#include " parser.hpp"
2+ #include < stdexcept>
23
34using namespace calculator ::internal;
5+ using shared::token_tt;
46
5- shared:: base_expr_t parse ( const std::vector<shared:: token_t >& tokens)
7+ namespace calculator
68{
9+ namespace internal
10+ {
11+ std::optional<shared::token_t > parser_t::eat_token ()
12+ {
13+ if (current_index < tokens.size ())
14+ return this ->tokens [this ->current_index ++];
715
16+ return std::nullopt ;
17+ }
18+
19+ std::optional<shared::token_t > parser_t::peak_token ()
20+ {
21+ if (current_index < tokens.size ())
22+ return this ->tokens [this ->current_index ];
23+
24+ return std::nullopt ;
25+ }
26+
27+ std::shared_ptr<shared::base_expr_t > parser_t::parse_primary ()
28+ {
29+ if (auto token = this ->eat_token ())
30+ {
31+ switch (token->value )
32+ {
33+ case token_tt::NUMBER :
34+ {
35+ std::shared_ptr<shared::number_expr_t > number = std::make_shared<shared::number_expr_t >(token->number );
36+ return std::move (number);
37+ break ;
38+ }
39+ default :
40+ token->output ();
41+ throw std::runtime_error (" Received invalid token!" );
42+ break ;
43+ }
44+ }
45+ else
46+ throw std::runtime_error (" Expected primary token!" );
47+ }
48+
49+ std::shared_ptr<shared::base_expr_t > parser_t::parse_paren ()
50+ {
51+ std::shared_ptr<shared::base_expr_t > rtn_expr;
52+
53+ if (auto next_token = this ->peak_token ())
54+ {
55+ if (next_token->value == token_tt::OPEN_PAREN )
56+ {
57+ this ->eat_token ();
58+ rtn_expr = this ->parse ();
59+ next_token = this ->peak_token ();
60+ if (next_token && next_token->value == token_tt::CLOSE_PAREN )
61+ this ->eat_token ();
62+ else
63+ {
64+ throw std::runtime_error (" Closing parenthesis expected!" );
65+ }
66+ }
67+ }
68+
69+ if (rtn_expr.get () == nullptr )
70+ rtn_expr = parse_primary ();
71+
72+ return rtn_expr;
73+ }
74+
75+ std::shared_ptr<shared::base_expr_t > parser_t::parse_unary ()
76+ {
77+ std::shared_ptr<shared::base_expr_t > rtn_expr;
78+
79+ if (auto next_token = this ->peak_token ())
80+ {
81+ if (next_token->value == token_tt::SUB )
82+ {
83+ this ->eat_token ();
84+ std::shared_ptr<shared::base_expr_t > left_expr = parse_paren ();
85+ rtn_expr = std::make_unique<shared::unary_expr_t >(std::move (left_expr));
86+ }
87+ }
88+
89+ if (rtn_expr.get () == nullptr )
90+ rtn_expr = parse_paren ();
91+
92+ return rtn_expr;
93+ }
94+
95+ std::shared_ptr<shared::base_expr_t > parser_t::parse_powmod ()
96+ {
97+ std::shared_ptr<shared::base_expr_t > rtn_expr;
98+ std::shared_ptr<shared::base_expr_t > left_expr = parse_unary ();
99+
100+ if (auto next_token = this ->peak_token ())
101+ {
102+ while (next_token)
103+ {
104+ if (next_token->value == token_tt::MOD || next_token->value == token_tt::POW )
105+ {
106+ shared::token_t current = *this ->eat_token ();
107+ left_expr = std::make_unique<shared::binary_expr_t >(std::move (left_expr), this ->parse_powmod (), current.value );
108+ rtn_expr = left_expr;
109+ }
110+ else
111+ break ;
112+
113+ next_token = this ->peak_token ();
114+ }
115+ }
116+
117+ if (rtn_expr.get () == nullptr )
118+ rtn_expr = left_expr;
119+
120+ return rtn_expr;
121+ }
122+
123+ std::shared_ptr<shared::base_expr_t > parser_t::parse_muldiv ()
124+ {
125+ std::shared_ptr<shared::base_expr_t > rtn_expr;
126+ std::shared_ptr<shared::base_expr_t > left_expr = parse_powmod ();
127+
128+ if (auto next_token = this ->peak_token ())
129+ {
130+ while (next_token)
131+ {
132+ if (next_token->value == token_tt::MUL || next_token->value == token_tt::DIV )
133+ {
134+ shared::token_t current = *this ->eat_token ();
135+ left_expr = std::make_unique<shared::binary_expr_t >(std::move (left_expr), this ->parse_muldiv (), current.value );
136+ rtn_expr = left_expr;
137+ }
138+ else
139+ break ;
140+
141+ next_token = this ->peak_token ();
142+ }
143+ }
144+
145+ if (rtn_expr.get () == nullptr )
146+ rtn_expr = left_expr;
147+
148+ return rtn_expr;
149+ }
150+
151+ std::shared_ptr<shared::base_expr_t > parser_t::parse_addsub ()
152+ {
153+ std::shared_ptr<shared::base_expr_t > rtn_expr;
154+ std::shared_ptr<shared::base_expr_t > left_expr = parse_muldiv ();
155+
156+ if (auto next_token = this ->peak_token ())
157+ {
158+ while (next_token)
159+ {
160+ if (next_token->value == token_tt::ADD || next_token->value == token_tt::SUB )
161+ {
162+ shared::token_t current = *this ->eat_token ();
163+ left_expr = std::make_unique<shared::binary_expr_t >(std::move (left_expr), this ->parse_addsub (), current.value );
164+ rtn_expr = left_expr;
165+ }
166+ else
167+ break ;
168+
169+ next_token = this ->peak_token ();
170+ }
171+ }
172+
173+ if (rtn_expr.get () == nullptr )
174+ rtn_expr = left_expr;
175+
176+ return rtn_expr;
177+ }
178+
179+ std::shared_ptr<shared::base_expr_t > parser_t::parse ()
180+ {
181+ return this ->parse_addsub ();
182+ }
183+
184+ std::shared_ptr<shared::base_expr_t > parser_t::parse (const std::vector<shared::token_t >& tokens)
185+ {
186+ this ->tokens = tokens;
187+ this ->current_index = 0 ;
188+
189+ return this ->parse ();
190+ }
191+ }
8192}
0 commit comments