add tree builder, fix multiple bugs

This commit is contained in:
2026-10-07 16:15:42 +03:00
parent b365e1d05c
commit afb4b5de20
4 changed files with 168 additions and 25 deletions
+11 -13
View File
@@ -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()
{
+2
View File
@@ -9,5 +9,7 @@ namespace Syntax
int check_syntax(std::vector<Expression::Token>& tv);
void apply_corrections(std::vector<Expression::Token>& tv);
std::vector<Expression::Operation> build_op_vector(const std::vector<Expression::Token>& tv);
Expression::TreeNode ov_to_tree(const std::vector<Expression::Token> tv, const std::vector<Expression::Operation>& ov);
void print_op_tree(const std::vector<Expression::Token> tv, const std::vector<Expression::Operation>& ov);
}
+2
View File
@@ -18,4 +18,6 @@ int main(int argc, char **argv)
Syntax::apply_corrections(tv);
std::vector<Expression::Operation> ov = Syntax::build_op_vector(tv);
Expression::TreeNode root = Syntax::ov_to_tree(tv, ov);
}
+153 -12
View File
@@ -2,6 +2,7 @@
#include "parser.hpp"
#include "print.h"
#include "syntaxer.hpp"
#include <queue>
#include <stack>
#include <vector>
@@ -33,6 +34,72 @@ int check_syntax(std::vector<Expression::Token>& 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<Expression::Token>& 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<Expression::Token>& 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<Expression::Token>& 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<Expression::Token>& 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<Expression::Token>& 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<Expression::Token>& 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<int>& mp, std::vector<R
if (mp[i] == target_prio && !recording_range)
{
recording_range = 1;
ranges.emplace_back(i, 0);
ranges.emplace_back(i, i);
}
else if (mp[i] == target_prio && recording_range)
{
@@ -695,7 +762,7 @@ std::vector<Expression::Operation> build_op_vector(const std::vector<Expression:
{
const Expression::Operation &o = ov[i];
prs_debug("OP: ");
prs_debug("OP (w=" << o.w << "): ");
if (o.tl == Expression::Operation::NORMAL)
{
@@ -741,4 +808,78 @@ std::vector<Expression::Operation> build_op_vector(const std::vector<Expression:
return ov;
}
Expression::TreeNode ov_to_tree(const std::vector<Expression::Token> tv, const std::vector<Expression::Operation>& ov)
{
Expression::TreeNode root;
std::queue<std::pair<Expression::TreeNode *, int>> 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<Expression::TreeNode *, int> 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<std::pair<Expression::TreeNode *, int>> items_to_display;
}
}