update with initial syntaxer implementation
This commit is contained in:
+8
-2
@@ -11,15 +11,20 @@ set (GLOBAL_INC PRIVATE
|
||||
|
||||
|
||||
add_library(parser STATIC)
|
||||
|
||||
target_sources(parser PRIVATE
|
||||
src/parser.cpp
|
||||
)
|
||||
|
||||
target_include_directories(parser PRIVATE
|
||||
${GLOBAL_INC}
|
||||
)
|
||||
|
||||
add_library(syntaxer STATIC)
|
||||
target_sources(syntaxer PRIVATE
|
||||
src/syntaxer.cpp
|
||||
)
|
||||
target_include_directories(syntaxer PRIVATE
|
||||
${GLOBAL_INC}
|
||||
)
|
||||
|
||||
add_executable(tester)
|
||||
|
||||
@@ -34,4 +39,5 @@ target_include_directories(tester PRIVATE
|
||||
|
||||
target_link_libraries(tester PRIVATE
|
||||
parser
|
||||
syntaxer
|
||||
)
|
||||
|
||||
+22
-3
@@ -66,6 +66,11 @@ public:
|
||||
}
|
||||
} v;
|
||||
|
||||
Token(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Token(std::string s)
|
||||
: v(s)
|
||||
{
|
||||
@@ -168,9 +173,23 @@ public:
|
||||
};
|
||||
|
||||
class TreeNode {
|
||||
std::shared_ptr<Token> l; // left hand
|
||||
std::shared_ptr<Token> o; // operation
|
||||
std::shared_ptr<Token> r; // right hand
|
||||
public:
|
||||
TreeNode *l; // left hand
|
||||
TreeNode *r; // right hand
|
||||
Token o; // operator
|
||||
|
||||
~TreeNode()
|
||||
{
|
||||
if (l != nullptr)
|
||||
{
|
||||
delete l;
|
||||
}
|
||||
|
||||
if (r != nullptr)
|
||||
{
|
||||
delete r;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@
|
||||
#define pr_debug(...) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define pr_warn(...) std::cout << "[" << __func__ << ":" << __LINE__ << "] warning: " << __VA_ARGS__ << "\n"
|
||||
#define pr_warn(...) std::cout << "[" << __FILE__ << ":" << __LINE__ << " " << __func__ << "] warning: " << __VA_ARGS__ << "\n"
|
||||
|
||||
@@ -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
@@ -97,12 +97,14 @@ public:
|
||||
|
||||
void buf_clear(void)
|
||||
{
|
||||
memset(buffer, 0, 256);
|
||||
memset(buffer, 0, MAX_TOKEN_STRING_LEN);
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -140,7 +142,12 @@ public:
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -167,6 +174,34 @@ public:
|
||||
}
|
||||
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;
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
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";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
@@ -1,5 +1,6 @@
|
||||
#include "test-tools.hpp"
|
||||
#include "parser.hpp"
|
||||
#include "syntaxer.hpp"
|
||||
#include "expression.hpp"
|
||||
|
||||
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(25.4));
|
||||
r.push_back(Expression::Token(33));
|
||||
r.push_back(Expression::Token(35));
|
||||
r.push_back(Expression::Token(37));
|
||||
r.push_back(Expression::Token(39));
|
||||
@@ -88,9 +88,19 @@ TEST(parser_proper_test_3)
|
||||
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)
|
||||
{
|
||||
REGISTER(parser_proper_test_1);
|
||||
REGISTER(parser_proper_test_2);
|
||||
REGISTER(parser_proper_test_3);
|
||||
|
||||
REGISTER(tree_proper_test_1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user