update with initial syntaxer implementation

This commit is contained in:
2026-10-04 14:13:14 +03:00
parent 79642d3fd1
commit f00ed50d32
8 changed files with 188 additions and 10 deletions
+8 -2
View File
@@ -11,15 +11,20 @@ set (GLOBAL_INC PRIVATE
add_library(parser STATIC) add_library(parser STATIC)
target_sources(parser PRIVATE target_sources(parser PRIVATE
src/parser.cpp src/parser.cpp
) )
target_include_directories(parser PRIVATE target_include_directories(parser PRIVATE
${GLOBAL_INC} ${GLOBAL_INC}
) )
add_library(syntaxer STATIC)
target_sources(syntaxer PRIVATE
src/syntaxer.cpp
)
target_include_directories(syntaxer PRIVATE
${GLOBAL_INC}
)
add_executable(tester) add_executable(tester)
@@ -34,4 +39,5 @@ target_include_directories(tester PRIVATE
target_link_libraries(tester PRIVATE target_link_libraries(tester PRIVATE
parser parser
syntaxer
) )
+1
View File
@@ -1,3 +1,4 @@
#pragma once #pragma once
#define DEBUG 1 #define DEBUG 1
#define MAX_TOKEN_STRING_LEN 256
+22 -3
View File
@@ -66,6 +66,11 @@ public:
} }
} v; } v;
Token(void)
{
}
Token(std::string s) Token(std::string s)
: v(s) : v(s)
{ {
@@ -168,9 +173,23 @@ public:
}; };
class TreeNode { class TreeNode {
std::shared_ptr<Token> l; // left hand public:
std::shared_ptr<Token> o; // operation TreeNode *l; // left hand
std::shared_ptr<Token> r; // right hand TreeNode *r; // right hand
Token o; // operator
~TreeNode()
{
if (l != nullptr)
{
delete l;
}
if (r != nullptr)
{
delete r;
}
}
}; };
} }
+1 -1
View File
@@ -9,4 +9,4 @@
#define pr_debug(...) do {} while (0) #define pr_debug(...) do {} while (0)
#endif #endif
#define pr_warn(...) std::cout << "[" << __func__ << ":" << __LINE__ << "] warning: " << __VA_ARGS__ << "\n" #define pr_warn(...) std::cout << "[" << __FILE__ << ":" << __LINE__ << " " << __func__ << "] warning: " << __VA_ARGS__ << "\n"
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <vector>
#include <memory>
#include "expression.hpp"
namespace Syntax
{
struct SyntaxIssue
{
};
std::vector<SyntaxIssue> check_syntax(std::vector<Expression::Token>& tv);
std::shared_ptr<Expression::TreeNode> build_op_tree(std::vector<Expression::Token>& tv);
}
+49 -3
View File
@@ -97,12 +97,14 @@ public:
void buf_clear(void) void buf_clear(void)
{ {
memset(buffer, 0, 256); memset(buffer, 0, MAX_TOKEN_STRING_LEN);
} }
void buf_push(char c) void buf_push(char c)
{ {
buffer[strlen(buffer)] = c; if (int i = strlen(buffer); i < MAX_TOKEN_STRING_LEN - 1) {
buffer[i] = c;
}
} }
int dispatch_to_current(char c) int dispatch_to_current(char c)
@@ -140,7 +142,12 @@ public:
} }
else else
{ {
pr_debug("Unknown character skipped (" << c << "), still in idle"); // as per requirements (report all wrong symbols)
if (c != ' ' && c != '\0')
{
pr_warn("Unrecognized character: " << c);
}
return 0; return 0;
} }
} }
@@ -167,6 +174,34 @@ public:
} }
int leave_rc(void) int leave_rc(void)
{ {
// additional check as per requirements
{
int i, c;
#if (MAX_TOKEN_STRING_LEN % 8) == 0
for (i = 0, c = 0; i < MAX_TOKEN_STRING_LEN; i += 8)
{
c += (buffer[i+0] == '.')
+ (buffer[i+1] == '.')
+ (buffer[i+2] == '.')
+ (buffer[i+3] == '.')
+ (buffer[i+4] == '.')
+ (buffer[i+5] == '.')
+ (buffer[i+6] == '.')
+ (buffer[i+7] == '.');
}
#else
for (int i = 0, c = 0; i < MAX_TOKEN_STRING_LEN; i++)
{
c += buffer[i] == '.';
}
#endif
if (c > 1)
{
pr_warn("Too many dots in CONST: " << buffer);
return 0;
}
}
double value; double value;
if (!sscanf(buffer, "%lf", &value)) if (!sscanf(buffer, "%lf", &value))
@@ -342,4 +377,15 @@ void print_token_vector(const std::vector<Expression::Token>& tv)
std::cout << "(" << *tv[i].to_str() << ")\n"; std::cout << "(" << *tv[i].to_str() << ")\n";
} }
void print_token_vector(const std::vector<Expression::Token>& tv, const std::vector<unsigned char>& colorcoding)
{
int i, l;
for (i = 0, l = tv.size() - 1; i < l; i++)
{
std::cout << "(" << *tv[i].to_str() << ") ";
}
std::cout << "(" << *tv[i].to_str() << ")\n";
}
} }
+78
View File
@@ -0,0 +1,78 @@
#include "syntaxer.hpp"
#include "expression.hpp"
#include <vector>
#include "print.h"
namespace Syntax {
struct OpImportance
{
int pos;
int prio;
};
#if 0
std::vector<SyntaxIssue> check_syntax(std::vector<Expression::Token>& tv);
{
}
#endif
std::shared_ptr<Expression::TreeNode> build_op_tree(const std::vector<Expression::Token>& tv)
{
// define operator precedency
int prios_cnt = ({
int i = 0, c = 0, l = tv.size();
for (; i < l; c += tv[i].t == Expression::Token::OPERATOR
&& tv[i].v.o != Expression::Token::CPA
&& tv[i].v.o != Expression::Token::OPA, i++);
c;
});
OpImportance prios[prios_cnt];
for (int i = 0, p = 0, cp = 0, l = tv.size(); i < l; i++)
{
if (tv[i].t == Expression::Token::OPERATOR)
{
switch (tv[i].v.o)
{
case Expression::Token::OPA:
cp++;
break;
case Expression::Token::CPA:
cp--;
break;
case Expression::Token::ADD:
case Expression::Token::SUB:
case Expression::Token::MUL:
case Expression::Token::DIV:
case Expression::Token::POW:
prios[p].prio = cp;
prios[p].pos = i;
p++;
break;
default:
pr_warn("Token vector has broken operator at " << i);
break;
}
}
}
for (int i = 0; i < prios_cnt; i++)
{
pr_debug("pos=" << prios[i].pos << ",prio=" << prios[i].prio);
}
// build dependency graph
{
std::vector<Expression::Token> mv = tv;
}
// build operation tree
Expression::TreeNode *root = new Expression::TreeNode;
return std::shared_ptr<Expression::TreeNode>(root);
}
}
+11 -1
View File
@@ -1,5 +1,6 @@
#include "test-tools.hpp" #include "test-tools.hpp"
#include "parser.hpp" #include "parser.hpp"
#include "syntaxer.hpp"
#include "expression.hpp" #include "expression.hpp"
TEST(parser_proper_test_1) TEST(parser_proper_test_1)
@@ -63,7 +64,6 @@ TEST(parser_proper_test_3)
r.push_back(Expression::Token(Expression::Token::CPA)); r.push_back(Expression::Token(Expression::Token::CPA));
r.push_back(Expression::Token(Expression::Token::CPA)); r.push_back(Expression::Token(Expression::Token::CPA));
r.push_back(Expression::Token(25.4)); r.push_back(Expression::Token(25.4));
r.push_back(Expression::Token(33));
r.push_back(Expression::Token(35)); r.push_back(Expression::Token(35));
r.push_back(Expression::Token(37)); r.push_back(Expression::Token(37));
r.push_back(Expression::Token(39)); r.push_back(Expression::Token(39));
@@ -88,9 +88,19 @@ TEST(parser_proper_test_3)
return 0; return 0;
} }
TEST(tree_proper_test_1)
{
auto o = Parser::tokenize_input("(1**5 * (1 + 2 + 3 + 4))");
Syntax::build_op_tree(*o);
return 0;
}
void register_tests(void) void register_tests(void)
{ {
REGISTER(parser_proper_test_1); REGISTER(parser_proper_test_1);
REGISTER(parser_proper_test_2); REGISTER(parser_proper_test_2);
REGISTER(parser_proper_test_3); REGISTER(parser_proper_test_3);
REGISTER(tree_proper_test_1);
} }