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:
|
||||
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;
|
||||
|
@ -42,9 +42,9 @@ void Action::parseDeclaration(Context &context, Domain &domain)
|
||||
{
|
||||
context.parser.expect<std::string>(":");
|
||||
|
||||
if (context.parser.probe<std::string>("precondition"))
|
||||
if (context.parser.probeIdentifier("precondition"))
|
||||
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);
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
@ -26,10 +26,7 @@ namespace pddl
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier, Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, ExpressionContext &expressionContext);
|
||||
ExpressionPointer parseEffectBodyExpression(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,
|
||||
ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
auto &parser = context.parser;
|
||||
|
||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
{
|
||||
expression = expressions::And::parse(context, expressionContext,
|
||||
parsePreconditionExpression);
|
||||
}
|
||||
else if (expressionIdentifier == "forall"
|
||||
|| expressionIdentifier == "preference")
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parsePreconditionExpression)))
|
||||
return expression;
|
||||
|
||||
const auto position = parser.position();
|
||||
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
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);
|
||||
|
||||
skipSection(parser);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
parser.seek(position);
|
||||
return parseExpression(context, 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>(")");
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 == "<=")
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Or::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Not::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Imply::parse(context, expressionContext, parseExpression))
|
||||
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
{
|
||||
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);
|
||||
|
||||
skipSection(parser);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
parser.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
||||
[&](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 + "\"");
|
||||
parser.seek(position);
|
||||
throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
||||
auto &parser = context.parser;
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "and")
|
||||
expression = expressions::And::parse(context, expressionContext, parseEffectExpression);
|
||||
else if (expressionIdentifier == "forall"
|
||||
|| expressionIdentifier == "when")
|
||||
if ((expression = expressions::And::parse(context, expressionContext, parseEffectExpression)))
|
||||
return expression;
|
||||
|
||||
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);
|
||||
|
||||
skipSection(parser);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
|
||||
context.parser.expect<std::string>(")");
|
||||
|
||||
return expression;
|
||||
parser.seek(position);
|
||||
return parseEffectBodyExpression(context, expressionContext);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parseEffectBodyExpressionContent(const std::string &expressionIdentifier,
|
||||
Context &context, ExpressionContext &expressionContext)
|
||||
ExpressionPointer parseEffectBodyExpression(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &parser = context.parser;
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
if (expressionIdentifier == "not")
|
||||
return expressions::Not::parse(context, expressionContext, parsePredicate);
|
||||
|
||||
if (expressionIdentifier == "="
|
||||
|| expressionIdentifier == "assign"
|
||||
|| expressionIdentifier == "scale-up"
|
||||
|| expressionIdentifier == "scale-down"
|
||||
|| expressionIdentifier == "increase"
|
||||
|| expressionIdentifier == "decrease")
|
||||
if ((expression = expressions::Not::parse(context, expressionContext, parsePredicate))
|
||||
|| (expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
{
|
||||
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);
|
||||
|
||||
skipSection(parser);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
parser.seek(expressionIdentifierPosition);
|
||||
const auto expressionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||
|
||||
// Check if predicate with that name exists
|
||||
const auto match = std::find_if(predicateDeclarations.cbegin(), predicateDeclarations.cend(),
|
||||
[&](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");
|
||||
parser.seek(position);
|
||||
throw utils::ParserException(context.parser, "Expression type \"" + expressionIdentifier + "\" unknown or not allowed in this context");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExpressionPointer parsePredicate(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
const auto predicateName = context.parser.parseIdentifier(isIdentifier);
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
if ((expression = expressions::Predicate::parse(context, expressionContext)))
|
||||
return expression;
|
||||
|
||||
// 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;
|
||||
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)
|
||||
{
|
||||
auto &parser = context.parser;
|
||||
|
||||
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() != ')')
|
||||
{
|
||||
context.parser.expect<std::string>("(");
|
||||
|
||||
ExpressionPointer expression;
|
||||
|
||||
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
|
||||
if ((expression = parseInitialStateElement()))
|
||||
initialState->m_facts.emplace_back(std::move(expression));
|
||||
|
||||
if (expressionIdentifier == "at"
|
||||
|| 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();
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
return initialState;
|
||||
|
@ -15,6 +15,10 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string And::Identifier = "and";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void And::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||
{
|
||||
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
|
||||
{
|
||||
expressionVisitor.visit(*this);
|
||||
|
@ -15,6 +15,10 @@ namespace expressions
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const std::string Imply::Identifier = "imply";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Imply::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
|
||||
{
|
||||
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
|
||||
{
|
||||
expressionVisitor.visit(*this);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/ExpressionVisitor.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/Problem.h>
|
||||
#include <plasp/pddl/expressions/Constant.h>
|
||||
#include <plasp/pddl/expressions/Reference.h>
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
@ -29,12 +30,36 @@ Predicate::Predicate()
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PredicatePointer Predicate::parse(std::string name, Context &context,
|
||||
ExpressionContext &expressionContext)
|
||||
PredicatePointer Predicate::parse(Context &context, 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());
|
||||
|
||||
predicate->m_name = name;
|
||||
predicate->m_name = predicateName;
|
||||
|
||||
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
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
|
||||
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());
|
||||
|
||||
predicate->m_name = name;
|
||||
predicate->m_name = predicateName;
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
|
||||
|
@ -65,6 +65,7 @@ void Variable::parseDeclaration(Context &context, Variables ¶meters)
|
||||
|
||||
void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
auto &parser = context.parser;
|
||||
auto &variables = expressionContext.parameters;
|
||||
|
||||
// Parse and store variable itself
|
||||
@ -72,10 +73,10 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
||||
|
||||
auto &variable = variables.back();
|
||||
|
||||
context.parser.skipWhiteSpace();
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Check if the variable has a type declaration
|
||||
if (!context.parser.probe('-'))
|
||||
if (!parser.probe('-'))
|
||||
return;
|
||||
|
||||
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)
|
||||
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());
|
||||
return;
|
||||
}
|
||||
@ -119,9 +113,15 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres
|
||||
|
||||
void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expressionContext)
|
||||
{
|
||||
while (context.parser.currentCharacter() != ')')
|
||||
auto &parser = context.parser;
|
||||
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
parseTypedDeclaration(context, expressionContext);
|
||||
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
if (expressionContext.parameters.empty())
|
||||
return;
|
||||
|
||||
@ -133,7 +133,7 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre
|
||||
expressionContext.checkRequirement(Requirement::Type::Typing);
|
||||
// If no types are given, check that typing is not a requirement
|
||||
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