aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/server/parser
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2019-12-31 20:51:34 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2019-12-31 20:51:34 +0300
commit6d43c1316cf2e7f438c6ca73a43b63d063d7029f (patch)
treedf08df2bc681acc0e6c2906c3c675088fddb5789 /server/parser
parentparser: refactoring (diff)
downloadmath-server-6d43c1316cf2e7f438c6ca73a43b63d063d7029f.tar.gz
math-server-6d43c1316cf2e7f438c6ca73a43b63d063d7029f.zip
parser: support unary +
Diffstat (limited to 'server/parser')
-rw-r--r--server/parser/parser.hpp24
1 files changed, 18 insertions, 6 deletions
diff --git a/server/parser/parser.hpp b/server/parser/parser.hpp
index 7d6f31d..fb2a5ff 100644
--- a/server/parser/parser.hpp
+++ b/server/parser/parser.hpp
@@ -36,7 +36,7 @@ public:
private:
double exec_expr() {
- return exec_expr(exec_primary(), parser::BinaryOp::min_precedence());
+ return exec_expr(exec_factor(), parser::BinaryOp::min_precedence());
}
double exec_expr(double lhs, unsigned min_prec) {
@@ -45,7 +45,7 @@ private:
const auto prev_prec = prev.get_precedence();
m_lexer.drop_token();
- auto rhs = exec_primary();
+ auto rhs = exec_factor();
for (op = peek_operator(); op.has_value(); op = peek_operator()) {
const auto next = *op;
@@ -77,16 +77,28 @@ private:
return parser::BinaryOp::from_token(*token);
}
- double exec_primary() {
+ double exec_factor() {
if (!m_lexer.has_token()) {
- throw ParserError{"expected '-', '(' or a number"};
+ throw ParserError{"expected '-', '+', '(' or a number"};
}
using Type = lexer::Token::Type;
if (m_lexer.drop_token_of_type(Type::MINUS).has_value()) {
- return -exec_primary();
+ return -exec_factor();
}
+ if (m_lexer.drop_token_of_type(Type::PLUS).has_value()) {
+ return exec_factor();
+ }
+ return exec_atom();
+ }
+
+ double exec_atom() {
+ if (!m_lexer.has_token()) {
+ throw ParserError{"expected '-', '+', '(' or a number"};
+ }
+
+ using Type = lexer::Token::Type;
if (m_lexer.drop_token_of_type(Type::LEFT_PAREN).has_value()) {
const auto inner = exec_expr();
@@ -100,7 +112,7 @@ private:
return token.value().as_number();
}
- throw ParserError{"expected '-', '(' or a number"};
+ throw ParserError{"expected '-', '+', '(' or a number"};
}
Lexer m_lexer;