diff --git a/inc/syntaxer.hpp b/inc/syntaxer.hpp index 1cb0e85..a7e2401 100644 --- a/inc/syntaxer.hpp +++ b/inc/syntaxer.hpp @@ -6,8 +6,9 @@ namespace Syntax { -int check_syntax(std::vector& tv); -void apply_corrections(std::vector& tv); +void pre_process(std::vector& tv); +int check_syntax(const std::vector& tv); +void post_process(std::vector& tv); std::vector build_op_vector(const std::vector& tv); Expression::TreeNode ov_to_tree(const std::vector tv, const std::vector& ov); void print_op_tree(const std::vector tv, const std::vector& ov); diff --git a/src/main.cpp b/src/main.cpp index 0038e29..7a3bfe1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,12 +10,14 @@ int main(int argc, char **argv) std::vector tv = Parser::tokenize_input(argv[1]); + Syntax::pre_process(tv); + if (Syntax::check_syntax(tv)) { return 0; } - Syntax::apply_corrections(tv); + Syntax::post_process(tv); std::vector ov = Syntax::build_op_vector(tv); diff --git a/src/syntaxer.cpp b/src/syntaxer.cpp index e2e75a2..56153bb 100644 --- a/src/syntaxer.cpp +++ b/src/syntaxer.cpp @@ -8,6 +8,8 @@ namespace Syntax { +static int add_bracket_to(std::vector& tv, const int location, const int direction); + static void highlight_issue(const std::vector& tv, const int location) { int start = location - 7 < 0 ? 0 : location - 7; @@ -30,7 +32,62 @@ static void highlight_issue(const std::vector& tv, const int std::cout << "\n"; } -int check_syntax(std::vector& tv) +void pre_process(std::vector& tv) +{ + pr_debug("Pre-process: remove empty brackets"); + for (int i = 0; i < tv.size() - 1; i++) + { + if (tv[i].t == Expression::Token::OPERATOR + && tv[i].v.o == Expression::Token::OPA + && tv[i+1].t == Expression::Token::OPERATOR + && tv[i+1].v.o == Expression::Token::CPA) + { + std::vector highlight; + highlight.emplace_back(i); + highlight.emplace_back(i+1); + Parser::print_math_vector(tv, highlight); + + tv.erase(tv.begin() + i, tv.begin() + i + 2); + i--; + } + } + + pr_debug("Pre-process: unary minus"); + int change = 1; + while (change) + { + change = 0; + + for (int i = 0; i < tv.size() - 2; i++) + { + if (tv[i].t == Expression::Token::OPERATOR + && tv[i].v.o != Expression::Token::CPA + && tv[i+1].t == Expression::Token::OPERATOR + && tv[i+1].v.o == Expression::Token::SUB + && (tv[i+2].t == Expression::Token::CONST + || tv[i+2].t == Expression::Token::VAR + || (tv[i+2].t == Expression::Token::OPERATOR + && tv[i+2].v.o == Expression::Token::OPA))) + { + std::vector highlight; + + tv.insert(tv.begin() + i + 1, Expression::Token(0.0)); + tv.insert(tv.begin() + i + 1, Expression::Token(Expression::Token::OPA)); + highlight.emplace_back(add_bracket_to(tv, i + 3, 1)); + + highlight.emplace(highlight.begin(), i+2); + highlight.emplace(highlight.begin(), i+1); + Parser::print_math_vector(tv, highlight); + + i += 4; + + change++; + } + } + } +} + +int check_syntax(const std::vector& tv) { int problem_cnt = 0; @@ -639,7 +696,7 @@ static void weight_operators(std::vector& operator_weights, const std::vect } } -void apply_corrections(std::vector& tv) +void post_process(std::vector& tv) { pr_debug("Post processing:"); Parser::print_math_vector(tv); diff --git a/src/test-cases.cpp b/src/test-cases.cpp index b372e86..c499977 100644 --- a/src/test-cases.cpp +++ b/src/test-cases.cpp @@ -99,7 +99,7 @@ TEST(tree_proper_test_1) TEST(tree_proper_test_2) { std::vector o = Parser::tokenize_input("(1**5 * (1-2-3-4-5-6-7-8))"); - Syntax::apply_corrections(o); + Syntax::post_process(o); std::vector ov = Syntax::build_op_vector(o); return 0;