4 Commits
Author SHA1 Message Date
hasslesstech 0777faa11d fix dot crashing in multiple places 2026-10-07 18:11:39 +03:00
hasslesstech 8bc359fed6 fix bugs and simplify code 2026-10-07 17:35:04 +03:00
hasslesstech afb4b5de20 add tree builder, fix multiple bugs 2026-10-07 16:15:42 +03:00
hasslesstech b365e1d05c clean up includes 2026-10-07 10:09:05 +03:00
5 changed files with 166 additions and 33 deletions
+12 -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,18 @@ 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)
: l(nullptr), r(nullptr), o()
{
}
explicit TreeNode(const Token t)
: l(nullptr), r(nullptr), 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);
}
+12 -7
View File
@@ -1,10 +1,9 @@
#include <iostream>
#include <cctype>
#include <cstring>
#include <memory>
#include <vector>
#include "expression.hpp"
#include "print.h"
#include <cctype>
#include <cstring>
#include <iostream>
#include <vector>
namespace Parser {
@@ -378,7 +377,10 @@ void print_token_vector(const std::vector<Expression::Token>& tv)
std::cout << "(" << *tv[i].to_str() << ") ";
}
std::cout << "(" << *tv[i].to_str() << ")\n";
if (tv.size())
{
std::cout << "(" << *tv[i].to_str() << ")\n";
}
}
void print_math_vector(const std::vector<Expression::Token>& tv)
@@ -389,7 +391,10 @@ void print_math_vector(const std::vector<Expression::Token>& tv)
std::cout << *tv[i].to_math_str(); //<< " ";
}
std::cout << *tv[i].to_math_str() << "\n";
if (tv.size())
{
std::cout << *tv[i].to_math_str() << "\n";
}
}
}
+138 -13
View File
@@ -2,6 +2,7 @@
#include "parser.hpp"
#include "print.h"
#include "syntaxer.hpp"
#include <queue>
#include <stack>
#include <vector>
@@ -12,7 +13,7 @@ static void highlight_issue(const std::vector<Expression::Token>& tv, const int
int start = location - 7 < 0 ? 0 : location - 7;
int finish = location + 7 > tv.size() - 1 ? tv.size() - 1 : location + 7;
std::cout << " >>> ";
std::cout << " >>> ";
for (int i = start; i <= finish; i++)
{
@@ -33,7 +34,75 @@ int check_syntax(std::vector<Expression::Token>& tv)
{
int problem_cnt = 0;
// check start and finish validity
if (tv.size())
{
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 " << tv.size() - 1 << ", got opening bracket");
problem_cnt++;
break;
default:
pr_warn("Expected value or closing bracket at token " << tv.size() - 1 << ", 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
if (tv.size() > 1)
{
for (int i = 0, l = tv.size() - 1, pc; pc = problem_cnt, i < l; i++)
{
@@ -47,7 +116,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 +126,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 +150,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 +176,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 +184,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 +203,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 +542,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 +764,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 +810,60 @@ 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;
if (ov.size())
{
queued_ops.emplace(&root, ov.size() - 1);
}
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;
}
}