Refactored parsing of expressions, all classes parse from opening to closing parenthesis now.
This commit is contained in:
parent
04aac10f1d
commit
9506dcb31e
@ -16,38 +16,17 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class And: public NAry
|
class And: public NAry<And>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename ExpressionParser>
|
static const std::string Identifier;
|
||||||
static AndPointer parse(Context &context, ExpressionContext &expressionContext,
|
|
||||||
ExpressionParser parseExpression);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
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
|
class Binary: public Expression
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
template<typename ExpressionParser>
|
||||||
|
static std::unique_ptr<Derived> parse(Context &context,
|
||||||
|
ExpressionContext &expressionContext, ExpressionParser parseExpression);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const Expression *leftArgument() const;
|
const Expression *leftArgument() const;
|
||||||
const Expression *rightArgument() const;
|
const Expression *rightArgument() const;
|
||||||
|
|
||||||
protected:
|
|
||||||
template<typename ExpressionParser>
|
|
||||||
void parse(Context &context, ExpressionContext &expressionContext,
|
|
||||||
ExpressionParser parseExpression);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ExpressionPointer m_leftArgument;
|
ExpressionPointer m_leftArgument;
|
||||||
ExpressionPointer m_rightArgument;
|
ExpressionPointer m_rightArgument;
|
||||||
@ -37,14 +38,48 @@ class Binary: public Expression
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
template<typename ExpressionParser>
|
template<typename ExpressionParser>
|
||||||
void Binary::parse(Context &context, ExpressionContext &expressionContext,
|
std::unique_ptr<Derived> Binary<Derived>::parse(Context &context,
|
||||||
ExpressionParser parseExpression)
|
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
|
// Assume that expression identifier (imply, exists, etc.) is already parsed
|
||||||
// Parse arguments of the expression
|
// Parse arguments of the expression
|
||||||
m_leftArgument = parseExpression(context, expressionContext);
|
expression->m_leftArgument = parseExpression(context, expressionContext);
|
||||||
m_rightArgument = 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:
|
public:
|
||||||
template<typename ExpressionParser>
|
static const std::string Identifier;
|
||||||
static EitherPointer parse(Context &context, ExpressionContext &expressionContext,
|
|
||||||
ExpressionParser parseExpression);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
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:
|
public:
|
||||||
template<typename ExpressionParser>
|
static const std::string Identifier;
|
||||||
static ImplyPointer parse(Context &context, ExpressionContext ¶meters,
|
|
||||||
ExpressionParser parseExpression);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
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
|
class NAry: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const Expressions &arguments() const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
template<typename ExpressionParser>
|
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:
|
private:
|
||||||
Expressions m_arguments;
|
Expressions m_arguments;
|
||||||
@ -34,19 +36,49 @@ class NAry: public Expression
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<class Derived>
|
||||||
template<typename ExpressionParser>
|
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
|
// Assume that expression identifier (and, or, etc.) is already parsed
|
||||||
// Parse arguments of the expression
|
// 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;
|
const Expression &argument() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Not() = default;
|
|
||||||
|
|
||||||
ExpressionPointer m_argument;
|
ExpressionPointer m_argument;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,6 +39,17 @@ template<typename ExpressionParser>
|
|||||||
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
||||||
ExpressionParser parseExpression)
|
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());
|
auto expression = std::make_unique<Not>(Not());
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
@ -48,6 +57,8 @@ NotPointer Not::parse(Context &context, ExpressionContext &expressionContext,
|
|||||||
// Parse argument
|
// Parse argument
|
||||||
expression->m_argument = parseExpression(context, expressionContext);
|
expression->m_argument = parseExpression(context, expressionContext);
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,38 +16,17 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class Or: public NAry
|
class Or: public NAry<Or>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
template<typename ExpressionParser>
|
static const std::string Identifier;
|
||||||
static OrPointer parse(Context &context, ExpressionContext &expressionContext,
|
|
||||||
ExpressionParser parseExpression);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
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
|
class Predicate: public Expression
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static PredicatePointer parse(std::string name, Context &context,
|
static PredicatePointer parse(Context &context, ExpressionContext &expressionContext);
|
||||||
ExpressionContext &expressionContext);
|
static PredicatePointer parse(Context &context, const Problem &problem);
|
||||||
static PredicatePointer parse(std::string name, Context &context, const Problem &problem);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||||
|
@ -42,9 +42,9 @@ void Action::parseDeclaration(Context &context, Domain &domain)
|
|||||||
{
|
{
|
||||||
context.parser.expect<std::string>(":");
|
context.parser.expect<std::string>(":");
|
||||||
|
|
||||||
if (context.parser.probe<std::string>("precondition"))
|
if (context.parser.probeIdentifier("precondition"))
|
||||||
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
action->m_precondition = parsePreconditionExpression(context, expressionContext);
|
||||||
else if (context.parser.probe<std::string>("effect"))
|
else if (context.parser.probeIdentifier("effect"))
|
||||||
action->m_effect = parseEffectExpression(context, expressionContext);
|
action->m_effect = parseEffectExpression(context, expressionContext);
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
@ -26,10 +26,7 @@ namespace pddl
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
|
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext);
|
||||||
ExpressionContext &expressionContext);
|
|
||||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
|
||||||
Context &context, ExpressionContext &expressionContext);
|
|
||||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
|
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -45,194 +42,187 @@ inline void warnUnsupported(Context &context, const std::string &expressionIdent
|
|||||||
ExpressionPointer parsePreconditionExpression(Context &context,
|
ExpressionPointer parsePreconditionExpression(Context &context,
|
||||||
ExpressionContext &expressionContext)
|
ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
auto &parser = context.parser;
|
||||||
|
|
||||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
ExpressionPointer expression;
|
ExpressionPointer expression;
|
||||||
|
|
||||||
if (expressionIdentifier == "and")
|
if ((expression = expressions::And::parse(context, expressionContext, parsePreconditionExpression)))
|
||||||
{
|
return expression;
|
||||||
expression = expressions::And::parse(context, expressionContext,
|
|
||||||
parsePreconditionExpression);
|
const auto position = parser.position();
|
||||||
}
|
|
||||||
else if (expressionIdentifier == "forall"
|
parser.expect<std::string>("(");
|
||||||
|| expressionIdentifier == "preference")
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("forall")
|
||||||
|
|| parser.probeIdentifier("preference"))
|
||||||
{
|
{
|
||||||
|
// TODO: refactor
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
warnUnsupported(context, expressionIdentifier);
|
warnUnsupported(context, expressionIdentifier);
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
parser.seek(position);
|
||||||
|
return parseExpression(context, expressionContext);
|
||||||
return expression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
|
ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
auto &parser = context.parser;
|
||||||
|
|
||||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
ExpressionPointer expression;
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
if ((expression = expressions::And::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Or::parse(context, expressionContext, parseExpression))
|
||||||
return expression;
|
|| (expression = expressions::Not::parse(context, expressionContext, parseExpression))
|
||||||
}
|
|| (expression = expressions::Imply::parse(context, expressionContext, parseExpression))
|
||||||
|
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
|
|
||||||
ExpressionContext &expressionContext)
|
|
||||||
{
|
|
||||||
context.parser.skipWhiteSpace();
|
|
||||||
|
|
||||||
if (expressionIdentifier == "and")
|
|
||||||
return expressions::And::parse(context, expressionContext, parseExpression);
|
|
||||||
|
|
||||||
if (expressionIdentifier == "or")
|
|
||||||
return expressions::Or::parse(context, expressionContext, parseExpression);
|
|
||||||
|
|
||||||
if (expressionIdentifier == "not")
|
|
||||||
return expressions::Not::parse(context, expressionContext, parseExpression);
|
|
||||||
|
|
||||||
if (expressionIdentifier == "imply")
|
|
||||||
return expressions::Imply::parse(context, expressionContext, parseExpression);
|
|
||||||
|
|
||||||
if (expressionIdentifier == "exists"
|
|
||||||
|| expressionIdentifier == "forall"
|
|
||||||
|| expressionIdentifier == "-"
|
|
||||||
|| expressionIdentifier == "="
|
|
||||||
|| expressionIdentifier == "*"
|
|
||||||
|| expressionIdentifier == "+"
|
|
||||||
|| expressionIdentifier == "-"
|
|
||||||
|| expressionIdentifier == "/"
|
|
||||||
|| expressionIdentifier == ">"
|
|
||||||
|| expressionIdentifier == "<"
|
|
||||||
|| expressionIdentifier == "="
|
|
||||||
|| expressionIdentifier == ">="
|
|
||||||
|| expressionIdentifier == "<=")
|
|
||||||
{
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("exists")
|
||||||
|
|| parser.probeIdentifier("forall")
|
||||||
|
|| parser.probeIdentifier("-")
|
||||||
|
|| parser.probeIdentifier("=")
|
||||||
|
|| parser.probeIdentifier("*")
|
||||||
|
|| parser.probeIdentifier("+")
|
||||||
|
|| parser.probeIdentifier("-")
|
||||||
|
|| parser.probeIdentifier("/")
|
||||||
|
|| parser.probeIdentifier(">")
|
||||||
|
|| parser.probeIdentifier("<")
|
||||||
|
|| parser.probeIdentifier("=")
|
||||||
|
|| parser.probeIdentifier(">=")
|
||||||
|
|| parser.probeIdentifier("<="))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
warnUnsupported(context, expressionIdentifier);
|
warnUnsupported(context, expressionIdentifier);
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &predicateDeclarations = expressionContext.domain.predicates();
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
// Check if predicate with that name exists
|
parser.seek(position);
|
||||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
|
||||||
[&](const auto &predicate)
|
|
||||||
{
|
|
||||||
return predicate->name() == expressionIdentifier;
|
|
||||||
});
|
|
||||||
|
|
||||||
// If predicate exists, parse it
|
|
||||||
if (match != predicateDeclarations.cend())
|
|
||||||
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
|
|
||||||
|
|
||||||
throw utils::ParserException(context.parser, "Unknown expression \"" + expressionIdentifier + "\"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
auto &parser = context.parser;
|
||||||
|
|
||||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
|
||||||
|
|
||||||
ExpressionPointer expression;
|
ExpressionPointer expression;
|
||||||
|
|
||||||
if (expressionIdentifier == "and")
|
if ((expression = expressions::And::parse(context, expressionContext, parseEffectExpression)))
|
||||||
expression = expressions::And::parse(context, expressionContext, parseEffectExpression);
|
return expression;
|
||||||
else if (expressionIdentifier == "forall"
|
|
||||||
|| expressionIdentifier == "when")
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("forall")
|
||||||
|
|| parser.probeIdentifier("when"))
|
||||||
{
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
warnUnsupported(context, expressionIdentifier);
|
warnUnsupported(context, expressionIdentifier);
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
parser.seek(position);
|
||||||
|
return parseEffectBodyExpression(context, expressionContext);
|
||||||
return expression;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext)
|
||||||
Context &context, ExpressionContext &expressionContext)
|
|
||||||
{
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
ExpressionPointer expression;
|
ExpressionPointer expression;
|
||||||
|
|
||||||
if (expressionIdentifier == "not")
|
if ((expression = expressions::Not::parse(context, expressionContext, parsePredicate))
|
||||||
return expressions::Not::parse(context, expressionContext, parsePredicate);
|
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
|
||||||
if (expressionIdentifier == "="
|
|
||||||
|| expressionIdentifier == "assign"
|
|
||||||
|| expressionIdentifier == "scale-up"
|
|
||||||
|| expressionIdentifier == "scale-down"
|
|
||||||
|| expressionIdentifier == "increase"
|
|
||||||
|| expressionIdentifier == "decrease")
|
|
||||||
{
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("=")
|
||||||
|
|| parser.probeIdentifier("assign")
|
||||||
|
|| parser.probeIdentifier("scale-up")
|
||||||
|
|| parser.probeIdentifier("scale-down")
|
||||||
|
|| parser.probeIdentifier("increase")
|
||||||
|
|| parser.probeIdentifier("decrease"))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
warnUnsupported(context, expressionIdentifier);
|
warnUnsupported(context, expressionIdentifier);
|
||||||
|
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
// Check if predicate with that name exists
|
parser.seek(position);
|
||||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
|
||||||
[&](const auto &predicate)
|
|
||||||
{
|
|
||||||
return predicate->name() == expressionIdentifier;
|
|
||||||
});
|
|
||||||
|
|
||||||
// If predicate exists, parse it
|
|
||||||
if (match != predicateDeclarations.cend())
|
|
||||||
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
|
|
||||||
|
|
||||||
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
|
||||||
|
|
||||||
const auto predicateName = context.parser.parseIdentifier(isIdentifier);
|
|
||||||
|
|
||||||
ExpressionPointer expression;
|
ExpressionPointer expression;
|
||||||
|
|
||||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||||
|
|
||||||
// Check if predicate with that name exists
|
|
||||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
|
||||||
[&](const auto &predicate)
|
|
||||||
{
|
|
||||||
return predicate->name() == predicateName;
|
|
||||||
});
|
|
||||||
|
|
||||||
// If predicate exists, parse it
|
|
||||||
if (match == predicateDeclarations.cend())
|
|
||||||
throw utils::ParserException(context.parser, "Unknown predicate \"" + predicateName + "\"");
|
|
||||||
|
|
||||||
expression = expressions::Predicate::parse(predicateName, context, expressionContext);
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
|
||||||
|
|
||||||
return expression;
|
return expression;
|
||||||
|
|
||||||
|
throw utils::ParserException(context.parser, "Expected predicate");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -27,31 +27,54 @@ inline void warnUnsupported(Context &context, const std::string &expressionIdent
|
|||||||
|
|
||||||
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
|
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
|
||||||
{
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
auto initialState = std::make_unique<InitialState>(InitialState());
|
auto initialState = std::make_unique<InitialState>(InitialState());
|
||||||
|
|
||||||
|
const auto parseInitialStateElement =
|
||||||
|
[&]()
|
||||||
|
{
|
||||||
|
ExpressionPointer expression;
|
||||||
|
|
||||||
|
if ((expression = expressions::Predicate::parse(context, problem)))
|
||||||
|
return expression;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
|
const auto expressionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
if (parser.probeIdentifier("at")
|
||||||
|
|| parser.probeIdentifier("=")
|
||||||
|
|| parser.probeIdentifier("not"))
|
||||||
|
{
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
warnUnsupported(context, expressionIdentifier);
|
||||||
|
|
||||||
|
return ExpressionPointer();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.seek(expressionIdentifierPosition);
|
||||||
|
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
|
||||||
|
};
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
while (context.parser.currentCharacter() != ')')
|
while (context.parser.currentCharacter() != ')')
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
|
||||||
|
|
||||||
ExpressionPointer expression;
|
ExpressionPointer expression;
|
||||||
|
|
||||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
if ((expression = parseInitialStateElement()))
|
||||||
|
initialState->m_facts.emplace_back(std::move(expression));
|
||||||
|
|
||||||
if (expressionIdentifier == "at"
|
parser.skipWhiteSpace();
|
||||||
|| expressionIdentifier == "="
|
|
||||||
|| expressionIdentifier == "not")
|
|
||||||
{
|
|
||||||
warnUnsupported(context, expressionIdentifier);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If none of the above types apply, the content is a predicate over constants and objects
|
|
||||||
initialState->m_facts.emplace_back(expressions::Predicate::parse(expressionIdentifier, context, problem));
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return initialState;
|
return initialState;
|
||||||
|
@ -15,6 +15,10 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string And::Identifier = "and";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void And::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
void And::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||||
{
|
{
|
||||||
expressionVisitor.visit(*this);
|
expressionVisitor.visit(*this);
|
||||||
|
@ -1,38 +0,0 @@
|
|||||||
#include <plasp/pddl/expressions/Binary.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <plasp/pddl/Context.h>
|
|
||||||
#include <plasp/pddl/ExpressionVisitor.h>
|
|
||||||
#include <plasp/pddl/Identifier.h>
|
|
||||||
|
|
||||||
namespace plasp
|
|
||||||
{
|
|
||||||
namespace pddl
|
|
||||||
{
|
|
||||||
namespace expressions
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Binary
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const Expression *Binary::leftArgument() const
|
|
||||||
{
|
|
||||||
return m_leftArgument.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const Expression *Binary::rightArgument() const
|
|
||||||
{
|
|
||||||
return m_rightArgument.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,6 +15,10 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Either::Identifier = "either";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Either::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
void Either::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||||
{
|
{
|
||||||
expressionVisitor.visit(*this);
|
expressionVisitor.visit(*this);
|
||||||
|
@ -15,6 +15,10 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Imply::Identifier = "imply";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Imply::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
void Imply::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||||
{
|
{
|
||||||
expressionVisitor.visit(*this);
|
expressionVisitor.visit(*this);
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
#include <plasp/pddl/expressions/NAry.h>
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
#include <plasp/pddl/Context.h>
|
|
||||||
#include <plasp/pddl/ExpressionVisitor.h>
|
|
||||||
#include <plasp/pddl/Identifier.h>
|
|
||||||
|
|
||||||
namespace plasp
|
|
||||||
{
|
|
||||||
namespace pddl
|
|
||||||
{
|
|
||||||
namespace expressions
|
|
||||||
{
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// NAry
|
|
||||||
//
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const Expressions &NAry::arguments() const
|
|
||||||
{
|
|
||||||
return m_arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,6 +15,10 @@ namespace expressions
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
const std::string Or::Identifier = "or";
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Or::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
void Or::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||||
{
|
{
|
||||||
expressionVisitor.visit(*this);
|
expressionVisitor.visit(*this);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <plasp/pddl/ExpressionContext.h>
|
#include <plasp/pddl/ExpressionContext.h>
|
||||||
#include <plasp/pddl/ExpressionVisitor.h>
|
#include <plasp/pddl/ExpressionVisitor.h>
|
||||||
#include <plasp/pddl/Identifier.h>
|
#include <plasp/pddl/Identifier.h>
|
||||||
|
#include <plasp/pddl/Problem.h>
|
||||||
#include <plasp/pddl/expressions/Constant.h>
|
#include <plasp/pddl/expressions/Constant.h>
|
||||||
#include <plasp/pddl/expressions/Reference.h>
|
#include <plasp/pddl/expressions/Reference.h>
|
||||||
#include <plasp/pddl/expressions/Variable.h>
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
@ -29,12 +30,36 @@ Predicate::Predicate()
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PredicatePointer Predicate::parse(std::string name, Context &context,
|
PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressionContext)
|
||||||
ExpressionContext &expressionContext)
|
|
||||||
{
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier(isIdentifier);
|
||||||
|
const auto &predicates = expressionContext.domain.predicates();
|
||||||
|
|
||||||
|
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
return predicate->name() == predicateName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingPredicate == predicates.cend())
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto predicate = std::make_unique<Predicate>(Predicate());
|
auto predicate = std::make_unique<Predicate>(Predicate());
|
||||||
|
|
||||||
predicate->m_name = name;
|
predicate->m_name = predicateName;
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
@ -63,16 +88,43 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
|
|||||||
|
|
||||||
// TODO: check that signature matches one of the declared ones
|
// TODO: check that signature matches one of the declared ones
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
PredicatePointer Predicate::parse(std::string name, Context &context, const Problem &problem)
|
PredicatePointer Predicate::parse(Context &context, const Problem &problem)
|
||||||
{
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
if (!parser.probe<std::string>("("))
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto predicateName = parser.parseIdentifier(isIdentifier);
|
||||||
|
const auto &predicates = problem.domain().predicates();
|
||||||
|
|
||||||
|
const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(),
|
||||||
|
[&](const auto &predicate)
|
||||||
|
{
|
||||||
|
return predicate->name() == predicateName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (matchingPredicate == predicates.cend())
|
||||||
|
{
|
||||||
|
parser.seek(position);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
auto predicate = std::make_unique<Predicate>(Predicate());
|
auto predicate = std::make_unique<Predicate>(Predicate());
|
||||||
|
|
||||||
predicate->m_name = name;
|
predicate->m_name = predicateName;
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
@ -65,6 +65,7 @@ void Variable::parseDeclaration(Context &context, Variables ¶meters)
|
|||||||
|
|
||||||
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
|
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
|
auto &parser = context.parser;
|
||||||
auto &variables = expressionContext.parameters;
|
auto &variables = expressionContext.parameters;
|
||||||
|
|
||||||
// Parse and store variable itself
|
// Parse and store variable itself
|
||||||
@ -72,10 +73,10 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
|||||||
|
|
||||||
auto &variable = variables.back();
|
auto &variable = variables.back();
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
// Check if the variable has a type declaration
|
// Check if the variable has a type declaration
|
||||||
if (!context.parser.probe('-'))
|
if (!parser.probe('-'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto setType =
|
const auto setType =
|
||||||
@ -93,18 +94,11 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
// Parse argument of "either" type (always begins with opening parenthesis)
|
// Parse argument of "either" type (always begins with opening parenthesis)
|
||||||
if (context.parser.currentCharacter() == '(')
|
if ((variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType)))
|
||||||
{
|
{
|
||||||
context.parser.expect<std::string>("(");
|
|
||||||
context.parser.expect<std::string>("either");
|
|
||||||
|
|
||||||
variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType);
|
|
||||||
|
|
||||||
context.parser.expect<std::string>(")");
|
|
||||||
|
|
||||||
setType(variable->m_eitherExpression.get());
|
setType(variable->m_eitherExpression.get());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -119,9 +113,15 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
|||||||
|
|
||||||
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext)
|
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext)
|
||||||
{
|
{
|
||||||
while (context.parser.currentCharacter() != ')')
|
auto &parser = context.parser;
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
parseTypedDeclaration(context, expressionContext);
|
parseTypedDeclaration(context, expressionContext);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
if (expressionContext.parameters.empty())
|
if (expressionContext.parameters.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
|
|||||||
expressionContext.checkRequirement(Requirement::Type::Typing);
|
expressionContext.checkRequirement(Requirement::Type::Typing);
|
||||||
// If no types are given, check that typing is not a requirement
|
// If no types are given, check that typing is not a requirement
|
||||||
else if (expressionContext.hasRequirement(Requirement::Type::Typing))
|
else if (expressionContext.hasRequirement(Requirement::Type::Typing))
|
||||||
throw utils::ParserException(context.parser, "Variable has undeclared type");
|
throw utils::ParserException(parser, "Variable has undeclared type");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user