Move Menu Expression to Simple Namespace to have generic configurable expressions

This commit is contained in:
Jan
2021-11-24 17:44:14 +01:00
parent 4f2a8454a6
commit 38f3d7d10e
21 changed files with 619 additions and 407 deletions

View File

@ -3,7 +3,52 @@
#include <sstream>
#include <utility>
#include "AbstractParser.h"
#include "ParserSingleInputStream.h"
#include "Parsing/ParsingException.h"
#include "Parsing/Simple/SimpleLexer.h"
#include "Parsing/Simple/Expression/ISimpleExpression.h"
class DefinesIfDirectiveParsingState
{
public:
std::unique_ptr<ISimpleExpression> m_expression;
};
class DefinesIfDirectiveParser final : public AbstractParser<SimpleParserValue, DefinesIfDirectiveParsingState>
{
protected:
explicit DefinesIfDirectiveParser(ILexer<SimpleParserValue>* lexer)
: AbstractParser<SimpleParserValue, DefinesIfDirectiveParsingState>(lexer, std::make_unique<DefinesIfDirectiveParsingState>())
{
}
const std::vector<sequence_t*>& GetTestsForState() override
{
static std::vector<sequence_t*> sequences
{
};
return sequences;
}
public:
static bool EvaluateIfDirective(std::map<std::string, DefinesStreamProxy::Define>& defines, const std::string& value)
{
std::istringstream ss(value);
ParserSingleInputStream inputStream(ss, "");
SimpleLexer::Config config{};
config.m_emit_new_line_tokens = false;
config.m_read_numbers = true;
config.m_read_strings = false;
SimpleLexer lexer(&inputStream, std::move(config));
DefinesIfDirectiveParser parser(&lexer);
if (!parser.Parse())
return false;
const auto& expression = parser.m_state->m_expression;
return expression->IsStatic() && expression->Evaluate().IsTruthy();
}
};
DefinesStreamProxy::DefineParameterPosition::DefineParameterPosition()
: m_parameter_index(0u),

View File

@ -1,6 +1,6 @@
#pragma once
#include <unordered_map>
#include <map>
#include <stack>
#include <sstream>
@ -44,7 +44,7 @@ public:
private:
IParserLineStream* const m_stream;
std::unordered_map<std::string, Define> m_defines;
std::map<std::string, Define> m_defines;
std::stack<bool> m_modes;
unsigned m_ignore_depth;

View File

@ -7,6 +7,8 @@
#include "MatcherAnd.h"
#include "MatcherLabel.h"
#include "MatcherLoop.h"
#include "MatcherFalse.h"
#include "MatcherTrue.h"
#include "MatcherOptional.h"
#include "MatcherOr.h"
#include "Parsing/IParserValue.h"
@ -85,6 +87,16 @@ public:
{
}
_NODISCARD MatcherFactoryWrapper<TokenType> False() const
{
return MatcherFactoryWrapper<TokenType>(std::make_unique<MatcherFalse<TokenType>>());
}
_NODISCARD MatcherFactoryWrapper<TokenType> True() const
{
return MatcherFactoryWrapper<TokenType>(std::make_unique<MatcherTrue<TokenType>>());
}
_NODISCARD MatcherFactoryWrapper<TokenType> And(std::initializer_list<Movable<std::unique_ptr<AbstractMatcher<TokenType>>>> matchers) const
{
return MatcherFactoryWrapper<TokenType>(std::make_unique<MatcherAnd<TokenType>>(matchers));

View File

@ -0,0 +1,23 @@
#pragma once
#include <memory>
#include "Parsing/IParserValue.h"
#include "AbstractMatcher.h"
template <typename TokenType>
class MatcherFalse final : public AbstractMatcher<TokenType>
{
// TokenType must inherit IParserValue
static_assert(std::is_base_of<IParserValue, TokenType>::value);
protected:
MatcherResult<TokenType> CanMatch(ILexer<TokenType>* lexer, unsigned tokenOffset) override
{
return MatcherResult<TokenType>::NoMatch();
}
public:
MatcherFalse()
= default;
};

View File

@ -0,0 +1,23 @@
#pragma once
#include <memory>
#include "Parsing/IParserValue.h"
#include "AbstractMatcher.h"
template <typename TokenType>
class MatcherTrue final : public AbstractMatcher<TokenType>
{
// TokenType must inherit IParserValue
static_assert(std::is_base_of<IParserValue, TokenType>::value);
protected:
MatcherResult<TokenType> CanMatch(ILexer<TokenType>* lexer, unsigned tokenOffset) override
{
return MatcherResult<TokenType>::Match(0);
}
public:
MatcherTrue()
= default;
};

View File

@ -3,14 +3,17 @@
#include <cassert>
#include <cmath>
SimpleExpressionBinaryOperationType::SimpleExpressionBinaryOperationType(std::string syntax, const SimpleOperationPrecedence precedence, evaluation_function_t evaluationFunction)
: m_syntax(std::move(syntax)),
SimpleExpressionBinaryOperationType::SimpleExpressionBinaryOperationType(const SimpleBinaryOperationId id, std::string syntax, const SimpleOperationPrecedence precedence,
evaluation_function_t evaluationFunction)
: m_id(id),
m_syntax(std::move(syntax)),
m_precedence(precedence),
m_evaluation_function(std::move(evaluationFunction))
{
}
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_ADD(
SimpleBinaryOperationId::ADD,
"+",
SimpleOperationPrecedence::ADDITION_SUBTRACTION,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -48,6 +51,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SUBTRACT(
SimpleBinaryOperationId::SUBTRACT,
"-",
SimpleOperationPrecedence::ADDITION_SUBTRACTION,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -72,6 +76,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_MULTIPLY(
SimpleBinaryOperationId::MULTIPLY,
"*",
SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -96,6 +101,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_DIVIDE(
SimpleBinaryOperationId::DIVIDE,
"/",
SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -120,6 +126,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_REMAINDER(
SimpleBinaryOperationId::REMAINDER,
"%",
SimpleOperationPrecedence::MULTIPLICATION_DIVISION_REMAINDER,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -132,6 +139,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_BITWISE_AND(
SimpleBinaryOperationId::BITWISE_AND,
"&",
SimpleOperationPrecedence::BITWISE_AND,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -144,6 +152,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_BITWISE_OR(
SimpleBinaryOperationId::BITWISE_OR,
"|",
SimpleOperationPrecedence::BITWISE_OR,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -156,6 +165,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SHIFT_LEFT(
SimpleBinaryOperationId::SHIFT_LEFT,
"<<",
SimpleOperationPrecedence::BITWISE_SHIFT,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -168,6 +178,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_SHIFT_RIGHT(
SimpleBinaryOperationId::SHIFT_RIGHT,
">>",
SimpleOperationPrecedence::BITWISE_SHIFT,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -180,6 +191,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_GREATER_THAN(
SimpleBinaryOperationId::GREATER_THAN,
">",
SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -207,6 +219,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_GREATER_EQUAL_THAN(
SimpleBinaryOperationId::GREATER_EQUAL_THAN,
">=",
SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -234,6 +247,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_LESS_THAN(
SimpleBinaryOperationId::LESS_THAN,
"<",
SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -261,6 +275,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_LESS_EQUAL_THAN(
SimpleBinaryOperationId::LESS_EQUAL_THAN,
"<=",
SimpleOperationPrecedence::RELATIONAL_GREATER_LESS_THAN,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -288,6 +303,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_EQUALS(
SimpleBinaryOperationId::EQUALS,
"==",
SimpleOperationPrecedence::RELATIONAL_EQUALS,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -325,6 +341,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_NOT_EQUAL(
SimpleBinaryOperationId::NOT_EQUAL,
"!=",
SimpleOperationPrecedence::RELATIONAL_EQUALS,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -362,6 +379,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_AND(
SimpleBinaryOperationId::AND,
"&&",
SimpleOperationPrecedence::LOGICAL_AND,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue
@ -373,6 +391,7 @@ const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::O
);
const SimpleExpressionBinaryOperationType SimpleExpressionBinaryOperationType::OPERATION_OR(
SimpleBinaryOperationId::OR,
"||",
SimpleOperationPrecedence::LOGICAL_OR,
[](const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2) -> SimpleExpressionValue

View File

@ -49,12 +49,13 @@ class SimpleExpressionBinaryOperationType
public:
using evaluation_function_t = std::function<SimpleExpressionValue(const SimpleExpressionValue& operand1, const SimpleExpressionValue& operand2)>;
SimpleBinaryOperationId m_id;
std::string m_syntax;
SimpleOperationPrecedence m_precedence;
evaluation_function_t m_evaluation_function;
private:
SimpleExpressionBinaryOperationType(std::string syntax, SimpleOperationPrecedence precedence, evaluation_function_t evaluationFunction);
SimpleExpressionBinaryOperationType(SimpleBinaryOperationId id, std::string syntax, SimpleOperationPrecedence precedence, evaluation_function_t evaluationFunction);
public:
static const SimpleExpressionBinaryOperationType OPERATION_ADD;

View File

@ -0,0 +1,316 @@
#include "SimpleExpressionMatchers.h"
#include <list>
#include "Parsing/Simple/Matcher/SimpleMatcherFactory.h"
#include "Parsing/Simple/Expression/SimpleExpressionBinaryOperation.h"
#include "Parsing/Simple/Expression/SimpleExpressionUnaryOperation.h"
static constexpr int TAG_EXPRESSION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 1;
static constexpr int TAG_OPERAND = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 2;
static constexpr int TAG_UNARY_OPERATION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 3;
static constexpr int TAG_PARENTHESIS = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 4;
static constexpr int TAG_PARENTHESIS_END = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 5;
static constexpr int TAG_BINARY_OPERATION = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 6;
static constexpr int TAG_OPERAND_EXT = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 7;
static constexpr int TAG_OPERAND_EXT_END = SimpleExpressionMatchers::TAG_OFFSET_EXPRESSION + 8;
static constexpr int CAPTURE_OPERAND = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 1;
static constexpr int CAPTURE_UNARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 2;
static constexpr int CAPTURE_BINARY_OPERATION_TYPE = SimpleExpressionMatchers::CAPTURE_OFFSET_EXPRESSION + 3;
SimpleExpressionMatchers::SimpleExpressionMatchers()
: SimpleExpressionMatchers(true, true, true, true)
{
}
SimpleExpressionMatchers::SimpleExpressionMatchers(const bool enableStringOperands, const bool enableIdentifierOperands, const bool enableFloatingPointOperands, const bool enableIntOperands)
: m_enable_string_operands(enableStringOperands),
m_enable_identifier_operands(enableIdentifierOperands),
m_enable_floating_point_operands(enableFloatingPointOperands),
m_enable_int_operands(enableIntOperands)
{
}
SimpleExpressionMatchers::~SimpleExpressionMatchers()
= default;
void SimpleExpressionMatchers::ApplyTokensToLexerConfig(SimpleLexer::Config& lexerConfig)
{
for (const auto* unaryOperation : SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES)
{
if (unaryOperation->m_syntax.size() <= 1)
continue;
lexerConfig.m_multi_character_tokens.emplace_back(MULTI_TOKEN_OFFSET_UNARY + static_cast<int>(unaryOperation->m_id), unaryOperation->m_syntax);
}
for (const auto* binaryOperation : SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES)
{
if (binaryOperation->m_syntax.size() <= 1)
continue;
lexerConfig.m_multi_character_tokens.emplace_back(MULTI_TOKEN_OFFSET_BINARY + static_cast<int>(binaryOperation->m_id), binaryOperation->m_syntax);
}
}
std::vector<const SimpleExpressionUnaryOperationType*> SimpleExpressionMatchers::EnabledUnaryOperations() const
{
return std::vector(&SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[0],
&SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[std::extent_v<decltype(SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES)>]);
}
std::vector<const SimpleExpressionBinaryOperationType*> SimpleExpressionMatchers::EnabledBinaryOperations() const
{
return std::vector(&SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES[0],
&SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES[std::extent_v<decltype(SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES)>]);
}
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessExpressionInParenthesis(SequenceResult<SimpleParserValue>& result) const
{
auto processedEvaluation = ProcessExpression(result);
if (result.PeekAndRemoveIfTag(TAG_PARENTHESIS_END) != TAG_PARENTHESIS_END)
throw ParsingException(TokenPos(), "Expected parenthesis end tag @ ExpressionInParenthesis");
return processedEvaluation;
}
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessOperand(SequenceResult<SimpleParserValue>& result) const
{
const auto& operandToken = result.NextCapture(CAPTURE_OPERAND);
switch (operandToken.m_type)
{
case SimpleParserValueType::INTEGER:
return std::make_unique<SimpleExpressionValue>(operandToken.IntegerValue());
case SimpleParserValueType::FLOATING_POINT:
return std::make_unique<SimpleExpressionValue>(operandToken.FloatingPointValue());
case SimpleParserValueType::STRING:
return std::make_unique<SimpleExpressionValue>(operandToken.StringValue());
case SimpleParserValueType::IDENTIFIER:
return std::make_unique<SimpleExpressionValue>(operandToken.IdentifierValue());
default:
throw ParsingException(TokenPos(), "Unknown operand type @ Operand");
}
}
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const
{
return nullptr;
}
std::unique_ptr<ISimpleExpression> SimpleExpressionMatchers::ProcessExpression(SequenceResult<SimpleParserValue>& result) const
{
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) != TAG_EXPRESSION)
return nullptr;
std::vector<std::unique_ptr<ISimpleExpression>> operands;
std::list<std::pair<unsigned, const SimpleExpressionBinaryOperationType*>> operators;
while (true)
{
std::unique_ptr<ISimpleExpression> firstStatementPart;
std::vector<int> unaryOperations;
auto nextTag = result.NextTag();
while (nextTag == TAG_UNARY_OPERATION)
{
unaryOperations.push_back(result.NextCapture(CAPTURE_UNARY_OPERATION_TYPE).IntegerValue());
nextTag = result.NextTag();
}
switch (nextTag)
{
case TAG_PARENTHESIS:
firstStatementPart = ProcessExpressionInParenthesis(result);
break;
case TAG_OPERAND:
firstStatementPart = ProcessOperand(result);
break;
case TAG_OPERAND_EXT:
firstStatementPart = ProcessOperandExtension(result);
if (result.PeekAndRemoveIfTag(TAG_OPERAND_EXT_END) != TAG_OPERAND_EXT_END)
throw ParsingException(TokenPos(), "Unclosed operand extension @ Expression");
break;
default:
throw ParsingException(TokenPos(), "Invalid followup tag @ Expression");
}
for (auto i = unaryOperations.size(); i > 0; i--)
{
const auto operationIndex = unaryOperations[i - 1];
if (operationIndex < 0 || operationIndex >= static_cast<int>(SimpleUnaryOperationId::COUNT))
throw ParsingException(TokenPos(), "Invalid unary operation id @ Expression");
firstStatementPart = std::make_unique<SimpleExpressionUnaryOperation>(SimpleExpressionUnaryOperationType::ALL_OPERATION_TYPES[operationIndex],
std::move(firstStatementPart));
}
operands.emplace_back(std::move(firstStatementPart));
if (result.PeekAndRemoveIfTag(TAG_BINARY_OPERATION) == TAG_BINARY_OPERATION)
{
const auto operationIndex = result.NextCapture(CAPTURE_BINARY_OPERATION_TYPE).IntegerValue();
if (operationIndex < 0 || operationIndex >= static_cast<int>(SimpleBinaryOperationId::COUNT))
throw ParsingException(TokenPos(), "Invalid binary operation id @ Expression");
operators.emplace_back(operators.size(), SimpleExpressionBinaryOperationType::ALL_OPERATION_TYPES[operationIndex]);
}
else
break;
if (result.PeekAndRemoveIfTag(TAG_EXPRESSION) != TAG_EXPRESSION)
throw ParsingException(TokenPos(), "Expected EvaluationTag @ Evaluation");
}
operators.sort([](const std::pair<unsigned, const SimpleExpressionBinaryOperationType*>& p1, const std::pair<unsigned, const SimpleExpressionBinaryOperationType*>& p2)
{
if (p1.second->m_precedence != p2.second->m_precedence)
return p1.second->m_precedence > p2.second->m_precedence;
return p1.first > p2.first;
});
while (!operators.empty())
{
const auto& [operatorIndex, operatorType] = operators.back();
auto operation = std::make_unique<SimpleExpressionBinaryOperation>(operatorType, std::move(operands[operatorIndex]), std::move(operands[operatorIndex + 1]));
operands.erase(operands.begin() + static_cast<int>(operatorIndex));
operands[operatorIndex] = std::move(operation);
operators.pop_back();
for (auto& [opIndex, _] : operators)
{
if (opIndex > operatorIndex)
opIndex--;
}
}
return std::move(operands.front());
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::ParseOperand(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
std::vector<std::unique_ptr<matcher_t>> operandMatchers;
operandMatchers.reserve(4);
if (m_enable_string_operands)
operandMatchers.emplace_back(create.String());
if (m_enable_identifier_operands)
operandMatchers.emplace_back(create.Identifier());
if (m_enable_floating_point_operands)
operandMatchers.emplace_back(create.FloatingPoint());
if (m_enable_int_operands)
operandMatchers.emplace_back(create.Integer());
return create.Or(std::move(operandMatchers)).Tag(TAG_OPERAND).Capture(CAPTURE_OPERAND);
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::ParseBinaryOperationType(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
const auto enabledBinaryOperations = EnabledBinaryOperations();
std::vector<std::unique_ptr<matcher_t>> binaryOperationsMatchers;
binaryOperationsMatchers.reserve(enabledBinaryOperations.size());
for (const auto* enabledBinaryOperation : enabledBinaryOperations)
{
if (enabledBinaryOperation->m_syntax.size() > 1)
{
binaryOperationsMatchers.emplace_back(
create.MultiChar(MULTI_TOKEN_OFFSET_BINARY + static_cast<int>(enabledBinaryOperation->m_id))
.Transform([enabledBinaryOperation](const SimpleMatcherFactory::token_list_t& values)
{
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledBinaryOperation->m_id));
}));
}
else if (!enabledBinaryOperation->m_syntax.empty())
{
binaryOperationsMatchers.emplace_back(
create.Char(enabledBinaryOperation->m_syntax[0])
.Transform([enabledBinaryOperation](const SimpleMatcherFactory::token_list_t& values)
{
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledBinaryOperation->m_id));
}));
}
}
return create.Or(std::move(binaryOperationsMatchers)).Capture(CAPTURE_BINARY_OPERATION_TYPE);
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::ParseOperandExtension(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
return create.False();
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::ParseUnaryOperationType(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
const auto enabledUnaryOperations = EnabledUnaryOperations();
std::vector<std::unique_ptr<matcher_t>> unaryOperationsMatchers;
unaryOperationsMatchers.reserve(enabledUnaryOperations.size());
for (const auto* enabledUnaryOperation : enabledUnaryOperations)
{
if (enabledUnaryOperation->m_syntax.size() > 1)
{
unaryOperationsMatchers.emplace_back(
create.MultiChar(MULTI_TOKEN_OFFSET_UNARY + static_cast<int>(enabledUnaryOperation->m_id))
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
{
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
}));
}
else if (!enabledUnaryOperation->m_syntax.empty())
{
unaryOperationsMatchers.emplace_back(
create.Char(enabledUnaryOperation->m_syntax[0])
.Transform([enabledUnaryOperation](const SimpleMatcherFactory::token_list_t& values)
{
return SimpleParserValue::Integer(values[0].get().GetPos(), static_cast<int>(enabledUnaryOperation->m_id));
}));
}
}
return create.Or(std::move(unaryOperationsMatchers)).Tag(TAG_UNARY_OPERATION).Capture(CAPTURE_UNARY_OPERATION_TYPE);
}
std::unique_ptr<SimpleExpressionMatchers::matcher_t> SimpleExpressionMatchers::Expression(const supplier_t* labelSupplier) const
{
const SimpleMatcherFactory create(labelSupplier);
return create.And({
create.OptionalLoop(ParseUnaryOperationType(labelSupplier)),
create.Or({
create.And({
create.Char('('),
create.Label(LABEL_EXPRESSION),
create.Char(')').Tag(TAG_PARENTHESIS_END)
}).Tag(TAG_PARENTHESIS),
create.And({
create.True().Tag(TAG_OPERAND_EXT),
ParseOperandExtension(labelSupplier),
create.True().Tag(TAG_OPERAND_EXT_END)
}),
ParseOperand(labelSupplier)
}),
create.Optional(create.And({
ParseBinaryOperationType(labelSupplier),
create.Label(LABEL_EXPRESSION)
}).Tag(TAG_BINARY_OPERATION))
}).Tag(TAG_EXPRESSION);
}

View File

@ -0,0 +1,65 @@
#pragma once
#include <memory>
#include "SimpleExpressionBinaryOperation.h"
#include "SimpleExpressionUnaryOperation.h"
#include "Utils/ClassUtils.h"
#include "Parsing/Matcher/AbstractMatcher.h"
#include "Parsing/Matcher/MatcherLabel.h"
#include "Parsing/Simple/Expression/ISimpleExpression.h"
#include "Parsing/Sequence/SequenceResult.h"
#include "Parsing/Simple/SimpleParserValue.h"
#include <Parsing/Simple/SimpleLexer.h>
class SimpleExpressionMatchers
{
public:
using matcher_t = AbstractMatcher<SimpleParserValue>;
typedef IMatcherForLabelSupplier<SimpleParserValue> supplier_t;
static constexpr auto CAPTURE_OFFSET_EXPRESSION = 7000;
static constexpr auto TAG_OFFSET_EXPRESSION = 7000;
static constexpr auto CAPTURE_OFFSET_EXPRESSION_EXT = 8000;
static constexpr auto TAG_OFFSET_EXPRESSION_EXT = 8000;
static constexpr auto LABEL_EXPRESSION = 7000;
static constexpr auto MULTI_TOKEN_OFFSET_UNARY = 700;
static constexpr auto MULTI_TOKEN_OFFSET_BINARY = 720;
private:
bool m_enable_string_operands;
bool m_enable_identifier_operands;
bool m_enable_floating_point_operands;
bool m_enable_int_operands;
public:
SimpleExpressionMatchers();
virtual ~SimpleExpressionMatchers();
SimpleExpressionMatchers(const SimpleExpressionMatchers& other) = default;
SimpleExpressionMatchers(SimpleExpressionMatchers&& other) noexcept = default;
SimpleExpressionMatchers& operator=(const SimpleExpressionMatchers& other) = default;
SimpleExpressionMatchers& operator=(SimpleExpressionMatchers&& other) noexcept = default;
protected:
SimpleExpressionMatchers(bool enableStringOperands, bool enableIdentifierOperands, bool enableFloatingPointOperands, bool enableIntOperands);
virtual std::unique_ptr<matcher_t> ParseOperandExtension(const supplier_t* labelSupplier) const;
virtual std::unique_ptr<ISimpleExpression> ProcessOperandExtension(SequenceResult<SimpleParserValue>& result) const;
_NODISCARD virtual std::vector<const SimpleExpressionUnaryOperationType*> EnabledUnaryOperations() const;
_NODISCARD virtual std::vector<const SimpleExpressionBinaryOperationType*> EnabledBinaryOperations() const;
private:
std::unique_ptr<matcher_t> ParseBinaryOperationType(const supplier_t* labelSupplier) const;
std::unique_ptr<matcher_t> ParseOperand(const supplier_t* labelSupplier) const;
std::unique_ptr<matcher_t> ParseUnaryOperationType(const supplier_t* labelSupplier) const;
std::unique_ptr<ISimpleExpression> ProcessExpressionInParenthesis(SequenceResult<SimpleParserValue>& result) const;
std::unique_ptr<ISimpleExpression> ProcessOperand(SequenceResult<SimpleParserValue>& result) const;
public:
std::unique_ptr<matcher_t> Expression(const supplier_t* labelSupplier) const;
std::unique_ptr<ISimpleExpression> ProcessExpression(SequenceResult<SimpleParserValue>& result) const;
virtual void ApplyTokensToLexerConfig(SimpleLexer::Config& lexerConfig);
};

View File

@ -4,13 +4,15 @@
#include "SimpleExpressionBinaryOperation.h"
SimpleExpressionUnaryOperationType::SimpleExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction)
: m_syntax(std::move(syntax)),
SimpleExpressionUnaryOperationType::SimpleExpressionUnaryOperationType(const SimpleUnaryOperationId id, std::string syntax, evaluation_function_t evaluationFunction)
: m_id(id),
m_syntax(std::move(syntax)),
m_evaluation_function(std::move(evaluationFunction))
{
}
const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_NOT(
SimpleUnaryOperationId::NOT,
"!",
[](const SimpleExpressionValue& operand) -> SimpleExpressionValue
{
@ -19,10 +21,11 @@ const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPE
);
const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_BITWISE_NOT(
SimpleUnaryOperationId::BITWISE_NOT,
"~",
[](const SimpleExpressionValue& operand) -> SimpleExpressionValue
{
if(operand.m_type == SimpleExpressionValue::Type::INT)
if (operand.m_type == SimpleExpressionValue::Type::INT)
return SimpleExpressionValue(~operand.m_int_value);
return SimpleExpressionValue(0);
@ -30,10 +33,11 @@ const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPE
);
const SimpleExpressionUnaryOperationType SimpleExpressionUnaryOperationType::OPERATION_NEGATIVE(
SimpleUnaryOperationId::NEGATIVE,
"-",
[](const SimpleExpressionValue& operand) -> SimpleExpressionValue
{
if(operand.m_type == SimpleExpressionValue::Type::INT)
if (operand.m_type == SimpleExpressionValue::Type::INT)
return SimpleExpressionValue(-operand.m_int_value);
if (operand.m_type == SimpleExpressionValue::Type::DOUBLE)
return SimpleExpressionValue(-operand.m_double_value);

View File

@ -21,11 +21,12 @@ class SimpleExpressionUnaryOperationType
public:
using evaluation_function_t = std::function<SimpleExpressionValue(const SimpleExpressionValue& operand)>;
SimpleUnaryOperationId m_id;
std::string m_syntax;
evaluation_function_t m_evaluation_function;
private:
SimpleExpressionUnaryOperationType(std::string syntax, evaluation_function_t evaluationFunction);
SimpleExpressionUnaryOperationType(SimpleUnaryOperationId id, std::string syntax, evaluation_function_t evaluationFunction);
public:
static const SimpleExpressionUnaryOperationType OPERATION_NOT;

View File

@ -9,7 +9,7 @@ class SimpleMatcherFactory : public AbstractMatcherFactory<SimpleParserValue>
{
public:
explicit SimpleMatcherFactory(const IMatcherForLabelSupplier<SimpleParserValue>* labelSupplier);
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> Type(SimpleParserValueType type) const;
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> Keyword(std::string value) const;
_NODISCARD MatcherFactoryWrapper<SimpleParserValue> KeywordIgnoreCase(std::string value) const;