From afb4b5de20be3e787a6fa53d89b6593e581dd1f5 Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Wed, 7 Oct 2026 16:15:42 +0300 Subject: [PATCH] add tree builder, fix multiple bugs --- inc/expression.hpp | 24 +++---- inc/syntaxer.hpp | 2 + src/main.cpp | 2 + src/syntaxer.cpp | 165 +++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 168 insertions(+), 25 deletions(-) diff --git a/inc/expression.hpp b/inc/expression.hpp index f200d22..5e6a345 100644 --- a/inc/expression.hpp +++ b/inc/expression.hpp @@ -7,18 +7,6 @@ namespace Expression { -#if 0 -namespace TokenType { - -enum TokenType { - VAR, - CONST, - OPERATOR -}; - -} -#endif - class Token { public: enum TokenType { @@ -310,7 +298,17 @@ class TreeNode { public: TreeNode *l; // left hand TreeNode *r; // right hand - Token o; // operator + Token o; // if operator, left and right hands are valid + // if value, left and right hands should be null + + explicit TreeNode(void) + { + } + + explicit TreeNode(const Token t) + : o(t) + { + } ~TreeNode() { diff --git a/inc/syntaxer.hpp b/inc/syntaxer.hpp index a40efed..1cb0e85 100644 --- a/inc/syntaxer.hpp +++ b/inc/syntaxer.hpp @@ -9,5 +9,7 @@ namespace Syntax int check_syntax(std::vector& tv); void apply_corrections(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 d9ea05d..0038e29 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,4 +18,6 @@ int main(int argc, char **argv) Syntax::apply_corrections(tv); std::vector ov = Syntax::build_op_vector(tv); + + Expression::TreeNode root = Syntax::ov_to_tree(tv, ov); } diff --git a/src/syntaxer.cpp b/src/syntaxer.cpp index 5fcffa0..940d232 100644 --- a/src/syntaxer.cpp +++ b/src/syntaxer.cpp @@ -2,6 +2,7 @@ #include "parser.hpp" #include "print.h" #include "syntaxer.hpp" +#include #include #include @@ -33,6 +34,72 @@ int check_syntax(std::vector& tv) { int problem_cnt = 0; + // check start and finish validity + { + int pc = problem_cnt; + + switch (tv[0].t) + { + case Expression::Token::VAR: + case Expression::Token::CONST: + break; + case Expression::Token::OPERATOR: + switch (tv[0].v.o) + { + case Expression::Token::OPA: + break; + case Expression::Token::CPA: + pr_warn("Expected value or opening bracket at token 0, got closing bracket"); + problem_cnt++; + break; + default: + pr_warn("Expected value or opening bracket at token 0, got operator"); + problem_cnt++; + break; + } + break; + default: + pr_warn("Impossible token type, this is a bug!"); + break; + } + + if (pc != problem_cnt) + { + highlight_issue(tv, 0); + pc = problem_cnt; + } + + switch (tv.back().t) + { + case Expression::Token::VAR: + case Expression::Token::CONST: + break; + case Expression::Token::OPERATOR: + switch (tv.back().v.o) + { + case Expression::Token::CPA: + break; + case Expression::Token::OPA: + pr_warn("Expected value or closing bracket at token 0, got opening bracket"); + problem_cnt++; + break; + default: + pr_warn("Expected value or closing bracket at token 0, got operator"); + problem_cnt++; + break; + } + break; + default: + pr_warn("Impossible token type, this is a bug!"); + break; + } + + if (pc != problem_cnt) + { + highlight_issue(tv, tv.size()-1); + } + } + // check token type sequence { for (int i = 0, l = tv.size() - 1, pc; pc = problem_cnt, i < l; i++) @@ -47,7 +114,7 @@ int check_syntax(std::vector& tv) switch (tv[i+1].v.o) { case Expression::Token::OPA: - pr_warn("Expected operator at token " << i << ", got opening bracket"); + pr_warn("Expected operator at token " << i + 1 << ", got opening bracket"); problem_cnt++; break; case Expression::Token::CPA: @@ -57,11 +124,11 @@ int check_syntax(std::vector& tv) } break; case Expression::Token::VAR: - pr_warn("Expected operator at token " << i << ", got variable"); + pr_warn("Expected operator at token " << i + 1 << ", got variable"); problem_cnt++; break; case Expression::Token::CONST: - pr_warn("Expected operator at token " << i << ", got constant"); + pr_warn("Expected operator at token " << i + 1 << ", got constant"); problem_cnt++; break; default: @@ -81,11 +148,11 @@ int check_syntax(std::vector& tv) case Expression::Token::OPA: break; case Expression::Token::CPA: - pr_warn("Expected value at token " << i << ", got closing bracket"); + pr_warn("Expected value at token " << i + 1 << ", got closing bracket"); problem_cnt++; break; default: - pr_warn("Expected value at token " << i << ", got operator"); + pr_warn("Expected value at token " << i + 1 << ", got operator"); problem_cnt++; break; } @@ -107,7 +174,7 @@ int check_syntax(std::vector& tv) case Expression::Token::CPA: break; case Expression::Token::OPA: - pr_warn("Expected operator at token " << i << ", got opening bracket"); + pr_warn("Expected operator at token " << i + 1 << ", got opening bracket"); problem_cnt++; break; default: @@ -115,11 +182,11 @@ int check_syntax(std::vector& tv) } break; case Expression::Token::CONST: - pr_warn("Expected operator at token " << i << ", got constant"); + pr_warn("Expected operator at token " << i + 1 << ", got constant"); problem_cnt++; break; case Expression::Token::VAR: - pr_warn("Expected operator at token " << i << ", got variable"); + pr_warn("Expected operator at token " << i + 1 << ", got variable"); problem_cnt++; break; default: @@ -134,13 +201,13 @@ int check_syntax(std::vector& tv) switch (tv[i+1].v.o) { case Expression::Token::CPA: - pr_warn("Expected value at token " << i << ", got closing bracket"); + pr_warn("Expected value at token " << i + 1 << ", got closing bracket"); problem_cnt++; break; case Expression::Token::OPA: break; default: - pr_warn("Expected value at token " << i << ", got operator"); + pr_warn("Expected value at token " << i + 1 << ", got operator"); problem_cnt++; break; } @@ -473,7 +540,7 @@ static void find_select_prio_op_ranges(const std::vector& mp, std::vector build_op_vector(const std::vector build_op_vector(const std::vector tv, const std::vector& ov) +{ + Expression::TreeNode root; + std::queue> queued_ops; + + const Expression::Operation &root_op = ov[ov.size() - 1]; + root.o = root_op.o; + + switch (root_op.tl) + { + case Expression::Operation::DERIVED: + queued_ops.emplace(root.l = new Expression::TreeNode(), root_op.il); + break; + case Expression::Operation::NORMAL: + root.l = new Expression::TreeNode(tv[root_op.il]); + break; + } + + switch (root_op.tr) + { + case Expression::Operation::DERIVED: + queued_ops.emplace(root.r = new Expression::TreeNode(), root_op.ir); + break; + case Expression::Operation::NORMAL: + root.r = new Expression::TreeNode(tv[root_op.ir]); + break; + } + + while (queued_ops.size()) + { + const std::pair item = queued_ops.front(); + queued_ops.pop(); + + const Expression::Operation &proc_op = ov[item.second]; + Expression::TreeNode &node = *item.first; + + node.o = proc_op.o; + + switch (proc_op.tl) + { + case Expression::Operation::DERIVED: + queued_ops.emplace(node.l = new Expression::TreeNode(), proc_op.il); + break; + case Expression::Operation::NORMAL: + node.l = new Expression::TreeNode(tv[proc_op.il]); + break; + } + + switch (proc_op.tr) + { + case Expression::Operation::DERIVED: + queued_ops.emplace(node.r = new Expression::TreeNode(), proc_op.ir); + break; + case Expression::Operation::NORMAL: + node.r = new Expression::TreeNode(tv[proc_op.ir]); + break; + } + } + + return root; +} + +#if 0 +static int get_tree_depth(const Expression::TreeNode& root) +{ + retur +} +#endif + +void print_op_tree(const Expression::TreeNode& root) +{ + std::vector> items_to_display; +} + }