diff --git a/include/plasp/pddl/expressions/NotExpression.h b/include/plasp/pddl/expressions/NotExpression.h new file mode 100644 index 0000000..b2a8f84 --- /dev/null +++ b/include/plasp/pddl/expressions/NotExpression.h @@ -0,0 +1,58 @@ +#ifndef __PLASP__PDDL__EXPRESSION__NOT_EXPRESSION_H +#define __PLASP__PDDL__EXPRESSION__NOT_EXPRESSION_H + +#include +#include + +namespace plasp +{ +namespace pddl +{ +namespace expressions +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// NotExpression +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class NotExpression: public Expression +{ + public: + template + static std::unique_ptr parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression); + + public: + void accept(ExpressionVisitor &expressionVisitor) const override; + + const Expression &argument(); + + private: + NotExpression() = default; + + std::unique_ptr m_argument; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +std::unique_ptr NotExpression::parse(utils::Parser &parser, Context &context, const Variables ¶meters, ExpressionParser parseExpression) +{ + auto expression = std::make_unique(NotExpression()); + + parser.skipWhiteSpace(); + + // Parse argument + expression->m_argument = parseExpression(parser, context, parameters); + + return expression; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +} + +#endif diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index 3f96c0c..d2a975a 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -57,8 +57,6 @@ Action &Action::parseDeclaration(utils::Parser &parser, Context &context) action->m_effect = parseEffectExpression(parser, context, action->m_parameters); } - parser.expect(")"); - // Store new action context.actions.emplace_back(std::move(action)); diff --git a/src/plasp/pddl/Expression.cpp b/src/plasp/pddl/Expression.cpp index 135b4e4..44de3b5 100644 --- a/src/plasp/pddl/Expression.cpp +++ b/src/plasp/pddl/Expression.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ namespace pddl std::unique_ptr parseExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters); std::unique_ptr parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters); +std::unique_ptr parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters); //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -32,8 +34,6 @@ void throwUnsupported(const utils::Parser &parser, const std::string &expression std::unique_ptr parsePreconditionExpression(utils::Parser &parser, Context &context, const Variables ¶meters) { - parser.skipWhiteSpace(); - parser.expect("("); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); @@ -59,8 +59,6 @@ std::unique_ptr parsePreconditionExpression(utils::Parser &parser, C std::unique_ptr parseExpression(utils::Parser &parser, Context &context, const Variables ¶meters) { - parser.skipWhiteSpace(); - parser.expect("("); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); @@ -84,8 +82,9 @@ std::unique_ptr parseExpressionContent(const std::string &expression expression = expressions::AndExpression::parse(parser, context, parameters, parseExpression); else if (expressionIdentifier == "or") expression = expressions::OrExpression::parse(parser, context, parameters, parseExpression); - else if (expressionIdentifier == "not" - || expressionIdentifier == "imply" + else if (expressionIdentifier == "not") + expression = expressions::NotExpression::parse(parser, context, parameters, parseExpression); + else if (expressionIdentifier == "imply" || expressionIdentifier == "exists" || expressionIdentifier == "forall" || expressionIdentifier == "-" @@ -125,14 +124,10 @@ std::unique_ptr parseExpressionContent(const std::string &expression std::unique_ptr parseEffectExpression(utils::Parser &parser, Context &context, const Variables ¶meters) { - parser.skipWhiteSpace(); - parser.expect("("); const auto expressionIdentifier = parser.parseIdentifier(isIdentifier); - std::cout << "Parsing effect expression " << expressionIdentifier << std::endl; - std::unique_ptr expression; if (expressionIdentifier == "and") @@ -154,12 +149,11 @@ std::unique_ptr parseEffectExpression(utils::Parser &parser, Context std::unique_ptr parseEffectBodyExpressionContent(const std::string &expressionIdentifier, utils::Parser &parser, Context &context, const Variables ¶meters) { - parser.skipWhiteSpace(); - std::unique_ptr expression; - if (expressionIdentifier == "not" - || expressionIdentifier == "=" + if (expressionIdentifier == "not") + expression = expressions::NotExpression::parse(parser, context, parameters, parsePredicateExpression); + else if (expressionIdentifier == "=" || expressionIdentifier == "assign" || expressionIdentifier == "scale-up" || expressionIdentifier == "scale-down" @@ -189,5 +183,33 @@ std::unique_ptr parseEffectBodyExpressionContent(const std::string & //////////////////////////////////////////////////////////////////////////////////////////////////// +std::unique_ptr parsePredicateExpression(utils::Parser &parser, Context &context, const Variables ¶meters) +{ + parser.expect("("); + + const auto predicateName = parser.parseIdentifier(isIdentifier); + + std::unique_ptr expression; + + // Check if predicate with that name exists + const auto match = std::find_if(context.predicates.cbegin(), context.predicates.cend(), + [&](const auto &predicate) + { + return predicate->name() == predicateName; + }); + + // If predicate exists, parse it + if (match == context.predicates.cend()) + throw utils::ParserException(parser.row(), parser.column(), "Unknown predicate \"" + predicateName + "\""); + + expression = expressions::PredicateExpression::parse(predicateName, parser, context, parameters); + + parser.expect(")"); + + return expression; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/src/plasp/pddl/expressions/NotExpression.cpp b/src/plasp/pddl/expressions/NotExpression.cpp new file mode 100644 index 0000000..1f880b8 --- /dev/null +++ b/src/plasp/pddl/expressions/NotExpression.cpp @@ -0,0 +1,27 @@ +#include + +#include + +namespace plasp +{ +namespace pddl +{ +namespace expressions +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// NotExpression +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void NotExpression::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const +{ + expressionVisitor.visit(*this); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +}