diff --git a/include/plasp/pddl/expressions/And.h b/include/plasp/pddl/expressions/And.h index e9786c0..37e14ca 100644 --- a/include/plasp/pddl/expressions/And.h +++ b/include/plasp/pddl/expressions/And.h @@ -16,38 +16,17 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -class And: public NAry +class And: public NAry { public: - template - 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 -AndPointer And::parse(Context &context, ExpressionContext &expressionContext, - ExpressionParser parseExpression) -{ - auto expression = std::make_unique(And()); - - expression->NAry::parse(context, expressionContext, parseExpression); - - if (expression->arguments().empty()) - context.logger.parserWarning(context.parser, "\"and\" expressions should not be empty"); - - return expression; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } } diff --git a/include/plasp/pddl/expressions/Binary.h b/include/plasp/pddl/expressions/Binary.h index b041367..4aafbab 100644 --- a/include/plasp/pddl/expressions/Binary.h +++ b/include/plasp/pddl/expressions/Binary.h @@ -19,17 +19,18 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +template class Binary: public Expression { + public: + template + static std::unique_ptr parse(Context &context, + ExpressionContext &expressionContext, ExpressionParser parseExpression); + public: const Expression *leftArgument() const; const Expression *rightArgument() const; - protected: - template - void parse(Context &context, ExpressionContext &expressionContext, - ExpressionParser parseExpression); - private: ExpressionPointer m_leftArgument; ExpressionPointer m_rightArgument; @@ -37,14 +38,48 @@ class Binary: public Expression //////////////////////////////////////////////////////////////////////////////////////////////////// +template template -void Binary::parse(Context &context, ExpressionContext &expressionContext, - ExpressionParser parseExpression) +std::unique_ptr Binary::parse(Context &context, + ExpressionContext &expressionContext, ExpressionParser parseExpression) { + auto &parser = context.parser; + + const auto position = parser.position(); + + if (!parser.probe("(") + || !parser.probeIdentifier(Derived::Identifier)) + { + parser.seek(position); + return nullptr; + } + + auto expression = std::make_unique(); + // 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(")"); + + return expression; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +const Expression *Binary::leftArgument() const +{ + return m_leftArgument.get(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +const Expression *Binary::rightArgument() const +{ + return m_rightArgument.get(); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Either.h b/include/plasp/pddl/expressions/Either.h index b436894..dd5ac55 100644 --- a/include/plasp/pddl/expressions/Either.h +++ b/include/plasp/pddl/expressions/Either.h @@ -16,38 +16,17 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -class Either: public NAry +class Either: public NAry { public: - template - 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 -EitherPointer Either::parse(Context &context, ExpressionContext &expressionContext, - ExpressionParser parseExpression) -{ - auto expression = std::make_unique(Either()); - - expression->NAry::parse(context, expressionContext, parseExpression); - - if (expression->arguments().empty()) - throw ConsistencyException("\"and\" expressions should not be empty"); - - return expression; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } } diff --git a/include/plasp/pddl/expressions/Imply.h b/include/plasp/pddl/expressions/Imply.h index f3c476a..584a4ee 100644 --- a/include/plasp/pddl/expressions/Imply.h +++ b/include/plasp/pddl/expressions/Imply.h @@ -16,35 +16,17 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -class Imply: public Binary +class Imply: public Binary { public: - template - 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 -ImplyPointer Imply::parse(Context &context, ExpressionContext ¶meters, - ExpressionParser parseExpression) -{ - auto expression = std::make_unique(Imply()); - - expression->Binary::parse(context, parameters, parseExpression); - - return expression; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } } diff --git a/include/plasp/pddl/expressions/NAry.h b/include/plasp/pddl/expressions/NAry.h index c635654..c14ff9a 100644 --- a/include/plasp/pddl/expressions/NAry.h +++ b/include/plasp/pddl/expressions/NAry.h @@ -19,14 +19,16 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +template class NAry: public Expression { public: - const Expressions &arguments() const; - - protected: template - void parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression); + static std::unique_ptr 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 template -void NAry::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) +std::unique_ptr NAry::parse(Context &context, + ExpressionContext &expressionContext, ExpressionParser parseExpression) { - context.parser.skipWhiteSpace(); + auto &parser = context.parser; + + const auto position = parser.position(); + + if (!parser.probe("(") + || !parser.probeIdentifier(Derived::Identifier)) + { + parser.seek(position); + return nullptr; + } + + auto expression = std::make_unique(); + + 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(")"); + + return expression; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +const Expressions &NAry::arguments() const +{ + return m_arguments; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/expressions/Not.h b/include/plasp/pddl/expressions/Not.h index daa36ff..80c60aa 100644 --- a/include/plasp/pddl/expressions/Not.h +++ b/include/plasp/pddl/expressions/Not.h @@ -30,8 +30,6 @@ class Not: public Expression const Expression &argument() const; private: - Not() = default; - ExpressionPointer m_argument; }; @@ -41,6 +39,17 @@ template NotPointer Not::parse(Context &context, ExpressionContext &expressionContext, ExpressionParser parseExpression) { + auto &parser = context.parser; + + const auto position = parser.position(); + + if (!parser.probe("(") + || !parser.probeIdentifier("not")) + { + parser.seek(position); + return nullptr; + } + auto expression = std::make_unique(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(")"); + return expression; } diff --git a/include/plasp/pddl/expressions/Or.h b/include/plasp/pddl/expressions/Or.h index dfc5b19..14a3510 100644 --- a/include/plasp/pddl/expressions/Or.h +++ b/include/plasp/pddl/expressions/Or.h @@ -16,38 +16,17 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// -class Or: public NAry +class Or: public NAry { public: - template - 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 -OrPointer Or::parse(Context &context, ExpressionContext &expressionContext, - ExpressionParser parseExpression) -{ - auto expression = std::make_unique(Or()); - - expression->NAry::parse(context, expressionContext, parseExpression); - - if (expression->arguments().empty()) - throw ConsistencyException("\"or\" expressions should not be empty"); - - return expression; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - } } } diff --git a/include/plasp/pddl/expressions/Predicate.h b/include/plasp/pddl/expressions/Predicate.h index 14dc971..deafb51 100644 --- a/include/plasp/pddl/expressions/Predicate.h +++ b/include/plasp/pddl/expressions/Predicate.h @@ -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; diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index 45a332d..4cc1d98 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -42,9 +42,9 @@ void Action::parseDeclaration(Context &context, Domain &domain) { context.parser.expect(":"); - if (context.parser.probe("precondition")) + if (context.parser.probeIdentifier("precondition")) action->m_precondition = parsePreconditionExpression(context, expressionContext); - else if (context.parser.probe("effect")) + else if (context.parser.probeIdentifier("effect")) action->m_effect = parseEffectExpression(context, expressionContext); context.parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 4014abe..53546ad 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -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("("); + 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("("); + + 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(")"); - - return expression; + parser.seek(position); + return parseExpression(context, expressionContext); } //////////////////////////////////////////////////////////////////////////////////////////////////// ExpressionPointer parseExpression(Context &context, ExpressionContext &expressionContext) { - context.parser.expect("("); + auto &parser = context.parser; - const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier); + parser.skipWhiteSpace(); - auto expression = parseExpressionContent(expressionIdentifier, context, expressionContext); + ExpressionPointer expression; - context.parser.expect(")"); - - 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("("); + + 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("("); - - 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("("); + + 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(")"); - - 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("("); + + 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("("); - - 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(")"); - - return expression; + throw utils::ParserException(context.parser, "Expected predicate"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/InitialState.cpp b/src/plasp/pddl/InitialState.cpp index 680f7ea..dcaefdc 100644 --- a/src/plasp/pddl/InitialState.cpp +++ b/src/plasp/pddl/InitialState.cpp @@ -27,31 +27,54 @@ inline void warnUnsupported(Context &context, const std::string &expressionIdent std::unique_ptr InitialState::parseDeclaration(Context &context, const Problem &problem) { + auto &parser = context.parser; + auto initialState = std::make_unique(InitialState()); + const auto parseInitialStateElement = + [&]() + { + ExpressionPointer expression; + + if ((expression = expressions::Predicate::parse(context, problem))) + return expression; + + const auto position = parser.position(); + + parser.expect("("); + + 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("("); - 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(")"); - - context.parser.skipWhiteSpace(); + parser.skipWhiteSpace(); } return initialState; diff --git a/src/plasp/pddl/expressions/And.cpp b/src/plasp/pddl/expressions/And.cpp index d7c19b0..98e293c 100644 --- a/src/plasp/pddl/expressions/And.cpp +++ b/src/plasp/pddl/expressions/And.cpp @@ -15,6 +15,10 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +const std::string And::Identifier = "and"; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void And::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this); diff --git a/src/plasp/pddl/expressions/Binary.cpp b/src/plasp/pddl/expressions/Binary.cpp deleted file mode 100644 index 9dcf4c0..0000000 --- a/src/plasp/pddl/expressions/Binary.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include - -#include - -#include -#include -#include - -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(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} -} diff --git a/src/plasp/pddl/expressions/Either.cpp b/src/plasp/pddl/expressions/Either.cpp index 158481d..97d9663 100644 --- a/src/plasp/pddl/expressions/Either.cpp +++ b/src/plasp/pddl/expressions/Either.cpp @@ -15,6 +15,10 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +const std::string Either::Identifier = "either"; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Either::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this); diff --git a/src/plasp/pddl/expressions/Imply.cpp b/src/plasp/pddl/expressions/Imply.cpp index c2c91fb..b650d1d 100644 --- a/src/plasp/pddl/expressions/Imply.cpp +++ b/src/plasp/pddl/expressions/Imply.cpp @@ -15,6 +15,10 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +const std::string Imply::Identifier = "imply"; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Imply::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this); diff --git a/src/plasp/pddl/expressions/NAry.cpp b/src/plasp/pddl/expressions/NAry.cpp deleted file mode 100644 index 4fe4fd5..0000000 --- a/src/plasp/pddl/expressions/NAry.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -#include - -#include -#include -#include - -namespace plasp -{ -namespace pddl -{ -namespace expressions -{ - -//////////////////////////////////////////////////////////////////////////////////////////////////// -// -// NAry -// -//////////////////////////////////////////////////////////////////////////////////////////////////// - -const Expressions &NAry::arguments() const -{ - return m_arguments; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -} -} -} diff --git a/src/plasp/pddl/expressions/Or.cpp b/src/plasp/pddl/expressions/Or.cpp index f6d135a..a1a6f31 100644 --- a/src/plasp/pddl/expressions/Or.cpp +++ b/src/plasp/pddl/expressions/Or.cpp @@ -15,6 +15,10 @@ namespace expressions // //////////////////////////////////////////////////////////////////////////////////////////////////// +const std::string Or::Identifier = "or"; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Or::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const { expressionVisitor.visit(*this); diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index 1e3c27a..f32ea00 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -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("(")) + { + 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->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(")"); + 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("(")) + { + 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->m_name = name; + predicate->m_name = predicateName; context.parser.skipWhiteSpace(); diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 25cfa06..a31257d 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -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("("); - context.parser.expect("either"); - - variable->m_eitherExpression = Either::parse(context, expressionContext, parseExistingPrimitiveType); - - context.parser.expect(")"); - 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"); } ////////////////////////////////////////////////////////////////////////////////////////////////////