Skip to content

Commit

Permalink
Use shunting yard algorithm for parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
fintarin committed Sep 25, 2023
1 parent 69aca69 commit df2ca50
Show file tree
Hide file tree
Showing 10 changed files with 290 additions and 266 deletions.
1 change: 1 addition & 0 deletions include/fintamath/core/MathObjectTypes.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ class MathObjectType {
Nequiv,
Index,
Deg,
Comma,

None = std::numeric_limits<size_t>::max(),
};
Expand Down
29 changes: 7 additions & 22 deletions include/fintamath/expressions/Expression.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <stack>

#include "fintamath/core/CoreConstants.hpp"
#include "fintamath/core/IArithmetic.hpp"
#include "fintamath/expressions/IExpression.hpp"
Expand All @@ -22,6 +24,7 @@ struct Term {
};

using TermVector = std::vector<std::shared_ptr<Term>>;
using OperandStack = std::stack<ArgumentPtr>;

class Expression : public IExpressionCRTP<Expression> {
public:
Expand Down Expand Up @@ -80,17 +83,13 @@ class Expression : public IExpressionCRTP<Expression> {

void updateStringMutable() const;

bool parseOperator(const TermVector &terms, size_t start, size_t end);

bool parseFunction(const TermVector &terms, size_t start, size_t end);

bool parseBrackets(const TermVector &terms, size_t start, size_t end);
static TermVector tokensToTerms(const TokenVector &tokens);

bool parseTerm(const TermVector &terms, size_t start, size_t end);
static OperandStack termsToOperands(const TermVector &terms);

static ArgumentPtrVector parseFunctionArgs(const TermVector &terms, size_t start, size_t end);
static ArgumentPtr operandsToExpr(OperandStack &operands);

static TermVector tokensToTerms(const TokenVector &tokens);
static ArgumentPtrVector unwrapComma(const ArgumentPtr &child);

static void insertMultiplications(TermVector &terms);

Expand All @@ -102,12 +101,6 @@ class Expression : public IExpressionCRTP<Expression> {

static bool canPrevTermBeBinaryOperator(const Term &term);

static bool skipBrackets(const TermVector &terms, size_t &openBracketIndex);

static void cutBrackets(const TermVector &terms, size_t &start, size_t &end);

static std::string termsToString(const TermVector &terms);

static bool isBinaryOperator(const ArgumentPtr &val);

static bool isPrefixOperator(const ArgumentPtr &val);
Expand All @@ -128,10 +121,6 @@ class Expression : public IExpressionCRTP<Expression> {

friend ArgumentPtr parseExpr(const std::string &str);

friend ArgumentPtr parseExpr(const TermVector &terms);

friend ArgumentPtr parseExpr(const TermVector &terms, size_t start, size_t end);

static Parser::Vector<std::unique_ptr<Term>, const Token &> &getTermMakers();

static Parser::Map<std::unique_ptr<IMathObject>, const ArgumentPtrVector &> &getExpressionMakers();
Expand All @@ -148,10 +137,6 @@ class Expression : public IExpressionCRTP<Expression> {

ArgumentPtr parseExpr(const std::string &str);

ArgumentPtr parseExpr(const TermVector &terms);

ArgumentPtr parseExpr(const TermVector &terms, size_t start, size_t end);

Expression operator+(const Variable &lhs, const Variable &rhs);

Expression operator+(const Expression &lhs, const Variable &rhs);
Expand Down
10 changes: 6 additions & 4 deletions include/fintamath/functions/IOperator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class IOperator : public IFunction {

public:
enum class Priority : uint16_t {
Highest,
Exponentiation, // e.g. a ^ b
PostfixUnary, // e.g. a!
PrefixUnary, // e.g. -a
Expand All @@ -19,7 +20,8 @@ class IOperator : public IFunction {
Disjunction, // e.g. a | b
Implication, // e.g. a -> b
Equivalence, // e.g. a <-> b
Any,
Comma, // e.g. a , b
Lowest,
};

public:
Expand All @@ -33,9 +35,9 @@ class IOperator : public IFunction {
Parser::registerType<T>(getParser());
}

static std::unique_ptr<IOperator> parse(const std::string &parsedStr, IOperator::Priority priority = IOperator::Priority::Any) {
static std::unique_ptr<IOperator> parse(const std::string &parsedStr, IOperator::Priority priority = IOperator::Priority::Lowest) {
Parser::Comparator<const std::unique_ptr<IOperator> &> comp = [priority](const std::unique_ptr<IOperator> &oper) {
return priority == IOperator::Priority::Any || oper->getOperatorPriority() == priority;
return priority == IOperator::Priority::Lowest || oper->getOperatorPriority() == priority;
};
return Parser::parse<std::unique_ptr<IOperator>>(getParser(), comp, parsedStr);
}
Expand All @@ -55,7 +57,7 @@ class IOperatorCRTP : public IOperator {
#undef I_OPERATOR_CRTP

public:
explicit IOperatorCRTP(IOperator::Priority inPriority = IOperator::Priority::Any,
explicit IOperatorCRTP(IOperator::Priority inPriority = IOperator::Priority::Lowest,
bool isAssociative = false,
bool isNonExressionEvaluatable = true)
: isNonExressionEvaluatableFunc(isNonExressionEvaluatable),
Expand Down
27 changes: 27 additions & 0 deletions include/fintamath/functions/other/Comma.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "fintamath/core/IArithmetic.hpp"
#include "fintamath/functions/IOperator.hpp"

namespace fintamath {

class Comma : public IOperatorCRTP<IArithmetic, Comma, IMathObject, IMathObject> {
public:
Comma() : IOperatorCRTP(IOperator::Priority::Comma, true) {
}

std::string toString() const override {
return ",";
}

static MathObjectType getTypeStatic() {
return MathObjectType::Comma;
}

protected:
std::unique_ptr<IMathObject> call(const ArgumentRefVector &argsVect) const override;
};

FINTAMATH_FUNCTION_EXPRESSION(Comma, commaExpr);

}
2 changes: 2 additions & 0 deletions src/fintamath/config/ParserConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "fintamath/functions/logic/Nequiv.hpp"
#include "fintamath/functions/logic/Not.hpp"
#include "fintamath/functions/logic/Or.hpp"
#include "fintamath/functions/other/Comma.hpp"
#include "fintamath/functions/other/Deg.hpp"
#include "fintamath/functions/other/Factorial.hpp"
#include "fintamath/functions/other/Index.hpp"
Expand Down Expand Up @@ -230,6 +231,7 @@ struct ParserConfig {
IOperator::registerType<Nequiv>();
IOperator::registerType<Index>();
IOperator::registerType<Deg>();
IOperator::registerType<Comma>();

IExpression::registerType<Expression>();
}
Expand Down
Loading

0 comments on commit df2ca50

Please sign in to comment.