Refactored parsing of expressions, all classes parse from opening to closing parenthesis now.
This commit is contained in:
@@ -16,38 +16,17 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class And: public NAry
|
||||
class And: public NAry<And>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static AndPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
||||
private:
|
||||
And() = default;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
AndPointer And::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<And>(And());
|
||||
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
context.logger.parserWarning(context.parser, "\"and\" expressions should not be empty");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,17 +19,18 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class Binary: public Expression
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static std::unique_ptr<Derived> parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
const Expression *leftArgument() const;
|
||||
const Expression *rightArgument() const;
|
||||
|
||||
protected:
|
||||
template<typename ExpressionParser>
|
||||
void parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
|
||||
private:
|
||||
ExpressionPointer m_leftArgument;
|
||||
ExpressionPointer m_rightArgument;
|
||||
@@ -37,14 +38,48 @@ class Binary: public Expression
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
template<typename ExpressionParser>
|
||||
void Binary::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
std::unique_ptr<Derived> Binary<Derived>::parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
auto &parser = context.parser;
|
||||
|
||||
const auto position = parser.position();
|
||||
|
||||
if (!parser.probe<std::string>("(")
|
||||
|| !parser.probeIdentifier(Derived::Identifier))
|
||||
{
|
||||
parser.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = std::make_unique<Derived>();
|
||||
|
||||
// Assume that expression identifier (imply, exists, etc.) is already parsed
|
||||
// Parse arguments of the expression
|
||||
m_leftArgument = parseExpression(context, expressionContext);
|
||||
m_rightArgument = parseExpression(context, expressionContext);
|
||||
expression->m_leftArgument = parseExpression(context, expressionContext);
|
||||
expression->m_rightArgument = parseExpression(context, expressionContext);
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
const Expression *Binary<Derived>::leftArgument() const
|
||||
{
|
||||
return m_leftArgument.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
const Expression *Binary<Derived>::rightArgument() const
|
||||
{
|
||||
return m_rightArgument.get();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -16,38 +16,17 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Either: public NAry
|
||||
class Either: public NAry<Either>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static EitherPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
||||
private:
|
||||
Either() = default;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Either>(Either());
|
||||
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
throw ConsistencyException("\"and\" expressions should not be empty");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -16,35 +16,17 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Imply: public Binary
|
||||
class Imply: public Binary<Imply>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static ImplyPointer parse(Context &context, ExpressionContext ¶meters,
|
||||
ExpressionParser parseExpression);
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
||||
private:
|
||||
Imply() = default;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
ImplyPointer Imply::parse(Context &context, ExpressionContext ¶meters,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Imply>(Imply());
|
||||
|
||||
expression->Binary::parse(context, parameters, parseExpression);
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,14 +19,16 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
class NAry: public Expression
|
||||
{
|
||||
public:
|
||||
const Expressions &arguments() const;
|
||||
|
||||
protected:
|
||||
template<typename ExpressionParser>
|
||||
void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
static std::unique_ptr<Derived> parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||
|
||||
public:
|
||||
const Expressions &arguments() const;
|
||||
|
||||
private:
|
||||
Expressions m_arguments;
|
||||
@@ -34,19 +36,49 @@ class NAry: public Expression
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
template<typename ExpressionParser>
|
||||
void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
std::unique_ptr<Derived> NAry<Derived>::parse(Context &context,
|
||||
ExpressionContext &expressionContext, ExpressionParser parseExpression)
|
||||
{
|
||||
context.parser.skipWhiteSpace();
|
||||
auto &parser = context.parser;
|
||||
|
||||
const auto position = parser.position();
|
||||
|
||||
if (!parser.probe<std::string>("(")
|
||||
|| !parser.probeIdentifier(Derived::Identifier))
|
||||
{
|
||||
parser.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = std::make_unique<Derived>();
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Assume that expression identifier (and, or, etc.) is already parsed
|
||||
// Parse arguments of the expression
|
||||
while (context.parser.currentCharacter() != ')')
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
m_arguments.emplace_back(parseExpression(context, expressionContext));
|
||||
expression->m_arguments.emplace_back(parseExpression(context, expressionContext));
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (expression->m_arguments.empty())
|
||||
context.logger.parserWarning(context.parser, "\"" + Derived::Identifier + "\" expressions should not be empty");
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Derived>
|
||||
const Expressions &NAry<Derived>::arguments() const
|
||||
{
|
||||
return m_arguments;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@@ -30,8 +30,6 @@ class Not: public Expression
|
||||
const Expression &argument() const;
|
||||
|
||||
private:
|
||||
Not() = default;
|
||||
|
||||
ExpressionPointer m_argument;
|
||||
};
|
||||
|
||||
@@ -41,6 +39,17 @@ template<typename ExpressionParser>
|
||||
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto &parser = context.parser;
|
||||
|
||||
const auto position = parser.position();
|
||||
|
||||
if (!parser.probe<std::string>("(")
|
||||
|| !parser.probeIdentifier("not"))
|
||||
{
|
||||
parser.seek(position);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto expression = std::make_unique<Not>(Not());
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
@@ -48,6 +57,8 @@ NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||
// Parse argument
|
||||
expression->m_argument = parseExpression(context, expressionContext);
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
|
@@ -16,38 +16,17 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Or: public NAry
|
||||
class Or: public NAry<Or>
|
||||
{
|
||||
public:
|
||||
template<typename ExpressionParser>
|
||||
static OrPointer parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression);
|
||||
static const std::string Identifier;
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
||||
private:
|
||||
Or() = default;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<typename ExpressionParser>
|
||||
OrPointer Or::parse(Context &context, ExpressionContext &expressionContext,
|
||||
ExpressionParser parseExpression)
|
||||
{
|
||||
auto expression = std::make_unique<Or>(Or());
|
||||
|
||||
expression->NAry::parse(context, expressionContext, parseExpression);
|
||||
|
||||
if (expression->arguments().empty())
|
||||
throw ConsistencyException("\"or\" expressions should not be empty");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -19,9 +19,8 @@ namespace expressions
|
||||
class Predicate: public Expression
|
||||
{
|
||||
public:
|
||||
static PredicatePointer parse(std::string name, Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
static PredicatePointer parse(std::string name, Context &context, const Problem &problem);
|
||||
static PredicatePointer parse(Context &context, ExpressionContext &expressionContext);
|
||||
static PredicatePointer parse(Context &context, const Problem &problem);
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
Reference in New Issue
Block a user