From a6babf3e90abf53f47000fd0ae440946931909c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Fri, 16 Jun 2017 03:34:32 +0200 Subject: [PATCH] Reimplemented major parts of parsing preconditions. --- lib/pddlparse/include/pddlparse/AST.h | 15 ++- .../include/pddlparse/detail/ASTCopy.h | 53 +++++--- .../include/pddlparse/detail/VariableStack.h | 9 +- .../pddlparse/detail/parsing/Constant.h | 4 +- .../pddlparse/detail/parsing/Expressions.h | 12 +- .../pddlparse/detail/parsing/Precondition.h | 27 +++++ .../pddlparse/detail/parsing/Predicate.h | 27 +++++ .../include/pddlparse/detail/parsing/Type.h | 25 ++++ .../pddlparse/detail/parsing/Unsupported.h | 25 ++++ .../pddlparse/detail/parsing/Variable.h | 3 +- .../src/pddlparse/detail/VariableStack.cpp | 30 ++++- .../src/pddlparse/detail/parsing/Constant.cpp | 22 ++++ .../pddlparse/detail/parsing/Description.cpp | 2 +- .../pddlparse/detail/parsing/Precondition.cpp | 113 ++++++++++++++++++ .../pddlparse/detail/parsing/Predicate.cpp | 79 ++++++++++++ .../src/pddlparse/detail/parsing/Type.cpp | 53 ++++++++ .../pddlparse/detail/parsing/Unsupported.cpp | 35 ++++++ .../src/pddlparse/detail/parsing/Variable.cpp | 36 ++++++ .../detail/parsing/VariableDeclaration.cpp | 8 +- 19 files changed, 540 insertions(+), 38 deletions(-) create mode 100644 lib/pddlparse/include/pddlparse/detail/parsing/Precondition.h create mode 100644 lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h create mode 100644 lib/pddlparse/include/pddlparse/detail/parsing/Type.h create mode 100644 lib/pddlparse/include/pddlparse/detail/parsing/Unsupported.h create mode 100644 lib/pddlparse/src/pddlparse/detail/parsing/Precondition.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/parsing/Type.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/parsing/Unsupported.cpp create mode 100644 lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp diff --git a/lib/pddlparse/include/pddlparse/AST.h b/lib/pddlparse/include/pddlparse/AST.h index 7c5d388..d157059 100644 --- a/lib/pddlparse/include/pddlparse/AST.h +++ b/lib/pddlparse/include/pddlparse/AST.h @@ -114,7 +114,11 @@ struct PrimitiveTypeDeclaration struct Unsupported { - explicit Unsupported() = default; + explicit Unsupported(std::string &&type) + : type{std::move(type)} + { + } + Unsupported(const Unsupported &other) = delete; Unsupported &operator=(const Unsupported &&other) = delete; Unsupported(Unsupported &&other) = default; @@ -165,8 +169,11 @@ struct VariableDeclaration struct Predicate { - explicit Predicate(PredicateDeclaration *declaration) - : declaration{declaration} + using Arguments = Terms; + + explicit Predicate(Arguments &&arguments, PredicateDeclaration *declaration) + : arguments{std::move(arguments)}, + declaration{declaration} { } @@ -175,7 +182,7 @@ struct Predicate Predicate(Predicate &&other) = default; Predicate &operator=(Predicate &&other) = default; - Terms arguments; + Arguments arguments; PredicateDeclaration *declaration; }; diff --git a/lib/pddlparse/include/pddlparse/detail/ASTCopy.h b/lib/pddlparse/include/pddlparse/detail/ASTCopy.h index ced121d..2079a80 100644 --- a/lib/pddlparse/include/pddlparse/detail/ASTCopy.h +++ b/lib/pddlparse/include/pddlparse/detail/ASTCopy.h @@ -2,6 +2,7 @@ #define __PDDL_PARSE__DETAIL__AST_COPY_H #include +#include namespace pddl { @@ -27,11 +28,11 @@ inline Variable deepCopy(Variable &other); //////////////////////////////////////////////////////////////////////////////////////////////////// template -inline Binary deepCopy(Binary &other); +inline Derived deepCopy(Binary &other); template -inline NAry deepCopy(NAry &other); +inline Derived deepCopy(NAry &other); template -inline Quantified deepCopy(Quantified &other); +inline Derived deepCopy(Quantified &other); //////////////////////////////////////////////////////////////////////////////////////////////////// // Expressions @@ -46,7 +47,14 @@ inline Not deepCopy(Not &other); // Variants //////////////////////////////////////////////////////////////////////////////////////////////////// -inline ast::Term deepCopy(ast::Term &other); +inline ast::Type deepCopy(ast::Type &other); + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Unique Pointers +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +std::unique_ptr deepCopy(std::unique_ptr &other); //////////////////////////////////////////////////////////////////////////////////////////////////// // Primitives @@ -76,10 +84,10 @@ Variable deepCopy(Variable &other) //////////////////////////////////////////////////////////////////////////////////////////////////// template -Binary deepCopy(Binary &other) +Derived deepCopy(Binary &other) { - auto argumentLeft = deepCopy(other.argumentLeft); - auto argumentRight = deepCopy(other.argumentRight); + auto argumentLeft{deepCopy(other.argumentLeft)}; + auto argumentRight{deepCopy(other.argumentRight)}; return Binary(std::move(argumentLeft), std::move(argumentRight)); } @@ -87,23 +95,23 @@ Binary deepCopy(Binary -NAry deepCopy(NAry &other) +Derived deepCopy(NAry &other) { - typename NAry::Arguments arguments; + typename Derived::Arguments arguments; arguments.reserve(other.arguments.size()); for (auto &argument : other.arguments) arguments.emplace_back(deepCopy(argument)); - return NAry(std::move(arguments)); + return Derived(std::move(arguments)); } //////////////////////////////////////////////////////////////////////////////////////////////////// template -Quantified deepCopy(Quantified &other) +Derived deepCopy(Quantified &other) { - auto argument = deepCopy(other.argument); + auto argument{deepCopy(other.argument)}; return Quantified(std::move(argument)); } @@ -115,17 +123,27 @@ Quantified deepCopy(Quantified &other) template At deepCopy(At &other) { - auto argument = deepCopy(other.argument); + auto argument{deepCopy(other.argument)}; return At(other.timePoint, std::move(argument)); } +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* +template +Either deepCopy(Either &other) +{ + auto argument{deepCopy(other.argument)}; + + return Not(std::move(argument)); +}*/ + //////////////////////////////////////////////////////////////////////////////////////////////////// template Not deepCopy(Not &other) { - auto argument = deepCopy(other.argument); + auto argument{deepCopy(other.argument)}; return Not(std::move(argument)); } @@ -143,6 +161,13 @@ struct DeepCopyVisitor } }; +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::Type deepCopy(ast::Type &other) +{ + return other.match([](auto &x){deepCopy(x); return std::make_unique(nullptr);}); +} + //////////////////////////////////////////////////////////////////////////////////////////////////// // Unique Pointers //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/include/pddlparse/detail/VariableStack.h b/lib/pddlparse/include/pddlparse/detail/VariableStack.h index 22e000c..2bcc46f 100644 --- a/lib/pddlparse/include/pddlparse/detail/VariableStack.h +++ b/lib/pddlparse/include/pddlparse/detail/VariableStack.h @@ -17,11 +17,16 @@ namespace detail class VariableStack { public: - void push(ast::VariableDeclarations *variables); + using Layer = ast::VariableDeclarations *; + + public: + void push(Layer layer); void pop(); + std::experimental::optional findVariableDeclaration(const std::string &variableName); + private: - std::vector m_variableStack; + std::vector m_layers; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h b/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h index b62b25a..eb227a3 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Constant.h @@ -3,6 +3,7 @@ #include #include +#include namespace pddl { @@ -15,8 +16,7 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// -ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain); -ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem); +ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Expressions.h b/lib/pddlparse/include/pddlparse/detail/parsing/Expressions.h index e4c17d9..8fd61d8 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Expressions.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Expressions.h @@ -63,12 +63,12 @@ std::experimental::optional> parseBinary(Context &conte auto argumentLeft = parseArgument(context, astContext, variableStack); if (!argumentLeft) - throw ParserException(tokenizer.location(), "could not parse argument of “" + Derived::Identifier + "” expression"); + throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression"); auto argumentRight = parseArgument(context, astContext, variableStack); if (!argumentRight) - throw ParserException(tokenizer.location(), "could not parse argument of “" + Derived::Identifier + "” expression"); + throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression"); tokenizer.expect(")"); @@ -99,18 +99,18 @@ std::experimental::optional> parseNAry(Context &context // Parse arguments of the expression while (tokenizer.currentCharacter() != ')') { - auto &argument = parseArgument(context, astContext, variableStack); + auto argument = parseArgument(context, astContext, variableStack); if (!argument) - throw ParserException(tokenizer.location(), "could not parse argument of “" + Derived::Identifier + "” expression"); + throw ParserException(tokenizer.location(), "could not parse argument of “" + std::string(Derived::Identifier) + "” expression"); - arguments.emplace_back(std::move(argument.value)); + arguments.emplace_back(std::move(argument.value())); tokenizer.skipWhiteSpace(); } if (arguments.empty()) - context.warningCallback(tokenizer.location(), "“" + Derived::Identifier + "” expressions should not be empty"); + context.warningCallback(tokenizer.location(), "“" + std::string(Derived::Identifier) + "” expressions should not be empty"); tokenizer.expect(")"); diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Precondition.h b/lib/pddlparse/include/pddlparse/detail/parsing/Precondition.h new file mode 100644 index 0000000..fb27a86 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Precondition.h @@ -0,0 +1,27 @@ +#ifndef __PDDL_PARSE__DETAIL__PARSING__PRECONDITION_H +#define __PDDL_PARSE__DETAIL__PARSING__PRECONDITION_H + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Precondition +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h b/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h new file mode 100644 index 0000000..760b7f6 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Predicate.h @@ -0,0 +1,27 @@ +#ifndef __PDDL_PARSE__DETAIL__PARSING__PREDICATE_H +#define __PDDL_PARSE__DETAIL__PARSING__PREDICATE_H + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Predicate +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Type.h b/lib/pddlparse/include/pddlparse/detail/parsing/Type.h new file mode 100644 index 0000000..6ce11b8 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Type.h @@ -0,0 +1,25 @@ +#ifndef __PDDL_PARSE__DETAIL__PARSING__TYPE_H +#define __PDDL_PARSE__DETAIL__PARSING__TYPE_H + +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Type +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::Type parseType(Context &context, ast::Domain &domain); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Unsupported.h b/lib/pddlparse/include/pddlparse/detail/parsing/Unsupported.h new file mode 100644 index 0000000..6a58398 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Unsupported.h @@ -0,0 +1,25 @@ +#ifndef __PDDL_PARSE__DETAIL__PARSING__UNSUPPORTED_H +#define __PDDL_PARSE__DETAIL__PARSING__UNSUPPORTED_H + +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Unsupported +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::UnsupportedPointer parseUnsupported(Context &context); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h b/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h index 5348813..b007d9e 100644 --- a/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h +++ b/lib/pddlparse/include/pddlparse/detail/parsing/Variable.h @@ -3,6 +3,7 @@ #include #include +#include namespace pddl { @@ -15,7 +16,7 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// -ast::Variable parseVariable(Context &context, ast::Domain &domain); +ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack); //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp b/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp index 16f182e..0f4405b 100644 --- a/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp +++ b/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp @@ -1,5 +1,7 @@ #include +#include + #include namespace pddl @@ -13,16 +15,38 @@ namespace detail // //////////////////////////////////////////////////////////////////////////////////////////////////// -void VariableStack::push(ast::VariableDeclarations *variables) +void VariableStack::push(ast::VariableDeclarations *layer) { - m_variableStack.push_back(variables); + m_layers.push_back(layer); } //////////////////////////////////////////////////////////////////////////////////////////////////// void VariableStack::pop() { - m_variableStack.pop_back(); + m_layers.pop_back(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional VariableStack::findVariableDeclaration(const std::string &variableName) +{ + const auto variableDeclarationMatches = + [&variableName](const auto &variableDeclaration) + { + return variableDeclaration->name == variableName; + }; + + for (auto i = m_layers.rbegin(); i != m_layers.rend(); i++) + { + auto &layer = **i; + const auto matchingVariableDeclaration = std::find_if(layer.begin(), layer.end(), variableDeclarationMatches); + + if (matchingVariableDeclaration != layer.end()) + return matchingVariableDeclaration->get(); + } + + return std::experimental::nullopt; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp index d518438..718302d 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Constant.cpp @@ -30,6 +30,7 @@ std::experimental::optional findConstant(const std::string //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: remove if unneeded ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain) { auto &tokenizer = context.tokenizer; @@ -45,6 +46,7 @@ ast::ConstantPointer parseConstant(Context &context, ast::Domain &domain) //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: remove if unneeded ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem) { auto &tokenizer = context.tokenizer; @@ -65,5 +67,25 @@ ast::ConstantPointer parseConstant(Context &context, ast::Problem &problem) //////////////////////////////////////////////////////////////////////////////////////////////////// +ast::ConstantPointer parseConstant(Context &context, ASTContext &astContext) +{ + auto &tokenizer = context.tokenizer; + const auto constantName = tokenizer.getIdentifier(); + + auto constant = findConstant(constantName, astContext.domain->constants); + + if (constant) + return std::move(constant.value()); + + constant = findConstant(constantName, astContext.problem.value()->objects); + + if (constant) + return std::move(constant.value()); + + throw ParserException(tokenizer.location(), "constant “" + constantName + "” used but never declared"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp index 97236a5..9d41f75 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp @@ -51,7 +51,7 @@ ast::Description DescriptionParser::parse() // TODO: check consistency // * check typing requirement // * check that typing is used consistently - // * check that constants, variables, and predicates aren't declared twice + // * check that constants/objects, variables, and predicates aren't declared twice // * check section order // * check that preconditions and effects are well-formed return {std::move(domain), std::move(problem)}; diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Precondition.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Precondition.cpp new file mode 100644 index 0000000..53b1686 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Precondition.cpp @@ -0,0 +1,113 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Precondition +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePrecondition(Context &context, ASTContext &astContext, VariableStack &variableStack) +{ + auto &tokenizer = context.tokenizer; + + tokenizer.skipWhiteSpace(); + + std::experimental::optional precondition; + + if ((precondition = parseAnd(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseForAll(context, astContext, variableStack, parsePrecondition))) + { + return std::move(precondition.value()); + } + + const auto position = tokenizer.position(); + + tokenizer.expect("("); + + const auto expressionIdentifierPosition = tokenizer.position(); + + if (tokenizer.testIdentifierAndSkip("preference")) + { + // TODO: refactor + tokenizer.seek(expressionIdentifierPosition); + const auto expressionIdentifier = tokenizer.getIdentifier(); + + tokenizer.seek(position); + return parseUnsupported(context); + } + + tokenizer.seek(position); + return parsePreconditionBody(context, astContext, variableStack); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePreconditionBody(Context &context, ASTContext &astContext, VariableStack &variableStack) +{ + auto &tokenizer = context.tokenizer; + + tokenizer.skipWhiteSpace(); + + std::experimental::optional precondition; + + if ((precondition = parseAnd(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseOr(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseExists(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseForAll(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseNot(context, astContext, variableStack, parsePrecondition)) + || (precondition = parseImply(context, astContext, variableStack, parsePrecondition)) + || (precondition = parsePredicate(context, astContext, variableStack))) + { + return std::move(precondition.value()); + } + + const auto position = tokenizer.position(); + + tokenizer.expect("("); + + const auto expressionIdentifierPosition = tokenizer.position(); + + if (tokenizer.testIdentifierAndSkip("-") + || tokenizer.testIdentifierAndSkip("=") + || tokenizer.testIdentifierAndSkip("*") + || tokenizer.testIdentifierAndSkip("+") + || tokenizer.testIdentifierAndSkip("-") + || tokenizer.testIdentifierAndSkip("/") + || tokenizer.testIdentifierAndSkip(">") + || tokenizer.testIdentifierAndSkip("<") + || tokenizer.testIdentifierAndSkip("=") + || tokenizer.testIdentifierAndSkip(">=") + || tokenizer.testIdentifierAndSkip("<=")) + { + tokenizer.seek(expressionIdentifierPosition); + const auto expressionIdentifier = tokenizer.getIdentifier(); + + tokenizer.seek(position); + return parseUnsupported(context); + } + + tokenizer.seek(expressionIdentifierPosition); + const auto expressionIdentifier = tokenizer.getIdentifier(); + + tokenizer.seek(position); + throw tokenize::TokenizerException(tokenizer.location(), "expression type “" + expressionIdentifier + "” unknown or not allowed in this context"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp new file mode 100644 index 0000000..b8a2fcb --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Predicate.cpp @@ -0,0 +1,79 @@ +#include + +#include +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Predicate +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +std::experimental::optional parsePredicate(Context &context, ASTContext &astContext, VariableStack &variableStack) +{ + auto &tokenizer = context.tokenizer; + + const auto position = tokenizer.position(); + + if (!tokenizer.testAndSkip("(")) + { + tokenizer.seek(position); + return std::experimental::nullopt; + } + + const auto predicateName = tokenizer.getIdentifier(); + + ast::Predicate::Arguments arguments; + + /*const auto matchingPredicate = std::find_if(predicates.cbegin(), predicates.cend(), + [&](const auto &predicate) + { + return predicate->name() == predicateName; + }); + + if (matchingPredicate == predicates.cend()) + { + tokenizer.seek(position); + return std::experimental::nullopt; + } + + auto predicate = PredicatePointer(new Predicate); + + predicate->m_name = predicateName;*/ + + tokenizer.skipWhiteSpace(); + + // Parse arguments + while (tokenizer.currentCharacter() != ')') + { + // Parse variables + if (tokenizer.currentCharacter() == '?') + arguments.emplace_back(parseVariable(context, variableStack)); + // Parse constants + else + arguments.emplace_back(parseConstant(context, astContext)); + + tokenizer.skipWhiteSpace(); + } + + //const auto &predicates = astContext.domain->predicates; + + // TODO: check that signature matches one of the declared ones + + tokenizer.expect(")"); + + // TODO: add matching predicate declaration + return std::make_unique(std::move(arguments), nullptr); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Type.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Type.cpp new file mode 100644 index 0000000..803f8b3 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Type.cpp @@ -0,0 +1,53 @@ +#include + +#include +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Type +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::Type parseType(Context &context, ast::Domain &domain) +{ + auto &tokenizer = context.tokenizer; + + tokenizer.skipWhiteSpace(); + + if (tokenizer.testAndReturn('(')) + { + // TODO: put into Type parsing unit + // TODO: refactor + auto p = + [](auto &context, auto &astContext, auto &) -> std::experimental::optional + { + return parsePrimitiveType(context, *astContext.domain); + }; + + // TODO: refactor + ASTContext astContext(domain); + VariableStack variableStack; + + auto eitherType = parseEither(context, astContext, variableStack, p); + + if (!eitherType) + throw ParserException(tokenizer.location(), "expected primitive type or “either” expression"); + + return std::move(eitherType.value()); + } + + // If existing, parse and store parent type + return parsePrimitiveType(context, domain); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Unsupported.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Unsupported.cpp new file mode 100644 index 0000000..6bc9680 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Unsupported.cpp @@ -0,0 +1,35 @@ +#include + +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Unsupported +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::UnsupportedPointer parseUnsupported(Context &context) +{ + auto &tokenizer = context.tokenizer; + + tokenizer.expect("("); + + auto expressionType = tokenizer.getIdentifier(); + + context.warningCallback(tokenizer.location(), "expression type “" + expressionType + "” currently unsupported in this context"); + + skipSection(tokenizer); + + return std::make_unique(std::move(expressionType)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp new file mode 100644 index 0000000..31249a3 --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/parsing/Variable.cpp @@ -0,0 +1,36 @@ +#include + +#include +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Predicate +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +ast::VariablePointer parseVariable(Context &context, VariableStack &variableStack) +{ + auto &tokenizer = context.tokenizer; + + tokenizer.expect("?"); + + const auto variableName = tokenizer.getIdentifier(); + + auto variableDeclaration = variableStack.findVariableDeclaration(variableName); + + if (!variableDeclaration) + throw ParserException(tokenizer.location(), "undeclared variable “" + variableName + "”"); + + return std::make_unique(variableDeclaration.value()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/src/pddlparse/detail/parsing/VariableDeclaration.cpp b/lib/pddlparse/src/pddlparse/detail/parsing/VariableDeclaration.cpp index c9eb972..fdd3735 100644 --- a/lib/pddlparse/src/pddlparse/detail/parsing/VariableDeclaration.cpp +++ b/lib/pddlparse/src/pddlparse/detail/parsing/VariableDeclaration.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include namespace pddl { @@ -48,10 +48,8 @@ ast::VariableDeclarations parseVariableDeclarations(Context &context, ast::Domai if (!tokenizer.testAndSkip('-')) continue; - // TODO: reimplement parsing “either” types - - // If existing, parse and store parent type - auto parentType = parsePrimitiveType(context, domain); + auto parentType = parseType(context, domain); + parentType = ast::deepCopy(parentType); for (size_t i = inheritanceIndex; i < variableDeclarations.size(); i++) variableDeclarations[i]->type = ast::deepCopy(parentType);