From d7db0d8ccddb34fb8c788ef6b9f8d7085ca982cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Tue, 9 May 2017 21:12:30 +0200 Subject: [PATCH] Started implementing clean, separate PDDL syntax tree and parser. --- CMakeLists.txt | 1 + lib/pddlparse/CMakeLists.txt | 28 + lib/pddlparse/include/pddlparse/AST.h | 538 ++++++++++++++++++ lib/pddlparse/include/pddlparse/ASTForward.h | 194 +++++++ lib/pddlparse/include/pddlparse/Variant.h | 281 +++++++++ .../include/pddlparse/detail/Parser.h | 56 ++ .../include/pddlparse/detail/VariableStack.h | 32 ++ lib/pddlparse/src/CMakeLists.txt | 28 + .../src/pddlparse/detail/VariableStack.cpp | 31 + lib/pddlparse/tests/CMakeLists.txt | 21 + lib/pddlparse/tests/main.cpp | 2 + 11 files changed, 1212 insertions(+) create mode 100644 lib/pddlparse/CMakeLists.txt create mode 100644 lib/pddlparse/include/pddlparse/AST.h create mode 100644 lib/pddlparse/include/pddlparse/ASTForward.h create mode 100644 lib/pddlparse/include/pddlparse/Variant.h create mode 100644 lib/pddlparse/include/pddlparse/detail/Parser.h create mode 100644 lib/pddlparse/include/pddlparse/detail/VariableStack.h create mode 100644 lib/pddlparse/src/CMakeLists.txt create mode 100644 lib/pddlparse/src/pddlparse/detail/VariableStack.cpp create mode 100644 lib/pddlparse/tests/CMakeLists.txt create mode 100644 lib/pddlparse/tests/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6953a83..e503a58 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ if (CMAKE_GENERATOR STREQUAL "Ninja" AND endif() add_subdirectory(lib/parsebase) +add_subdirectory(lib/pddlparse) add_subdirectory(src) add_subdirectory(app) if(PLASP_BUILD_TESTS) diff --git a/lib/pddlparse/CMakeLists.txt b/lib/pddlparse/CMakeLists.txt new file mode 100644 index 0000000..1f5ced9 --- /dev/null +++ b/lib/pddlparse/CMakeLists.txt @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 2.6) +project(pddlparse) + +option(PDDLPARSE_BUILD_TESTS "Build unit tests" OFF) + +set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic -Werror") +set(CMAKE_CXX_FLAGS_DEBUG "-g") + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) + +if (CMAKE_GENERATOR STREQUAL "Ninja" AND + ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR + (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5))) + # Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support. + # Rationale in https://github.com/ninja-build/ninja/issues/814 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") +endif() + +add_subdirectory(src) +if(PDDLPARSE_BUILD_TESTS) + add_subdirectory(tests) +endif(PDDLPARSE_BUILD_TESTS) diff --git a/lib/pddlparse/include/pddlparse/AST.h b/lib/pddlparse/include/pddlparse/AST.h new file mode 100644 index 0000000..846219c --- /dev/null +++ b/lib/pddlparse/include/pddlparse/AST.h @@ -0,0 +1,538 @@ +#ifndef __PDDL_PARSE__AST_H +#define __PDDL_PARSE__AST_H + +#include +#include +#include +#include +#include + +#include + +#include + +namespace pddl +{ +namespace ast +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AST +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Primitives +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Constant +{ + explicit Constant(ConstantDeclaration *declaration) + : declaration{declaration} + { + } + + Constant(const Constant &other) = delete; + Constant &operator=(const Constant &&other) = delete; + Constant(Constant &&other) = default; + Constant &operator=(Constant &&other) = default; + + ConstantDeclaration *declaration{nullptr}; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct ConstantDeclaration +{ + explicit ConstantDeclaration(std::string &&name, std::experimental::optional &&type = std::experimental::nullopt, bool isDirty = true) + : name{std::move(name)}, + type{std::move(type)}, + isDirty{isDirty} + { + } + + ConstantDeclaration(const ConstantDeclaration &other) = delete; + ConstantDeclaration &operator=(const ConstantDeclaration &&other) = delete; + ConstantDeclaration(ConstantDeclaration &&other) = default; + ConstantDeclaration &operator=(ConstantDeclaration &&other) = default; + + std::string name; + std::experimental::optional type; + bool isDirty{true}; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Dummy +{ + explicit Dummy(std::string name) + : name{name} + { + } + + Dummy(const Dummy &other) = delete; + Dummy &operator=(const Dummy &&other) = delete; + Dummy(Dummy &&other) = default; + Dummy &operator=(Dummy &&other) = default; + + std::string name; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct PrimitiveType +{ + explicit PrimitiveType(PrimitiveTypeDeclaration &declaration) + : declaration{declaration} + { + } + + PrimitiveType(const PrimitiveType &other) = delete; + PrimitiveType &operator=(const PrimitiveType &&other) = delete; + PrimitiveType(PrimitiveType &&other) = default; + PrimitiveType &operator=(PrimitiveType &&other) = default; + + PrimitiveTypeDeclaration &declaration; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct PrimitiveTypeDeclaration +{ + explicit PrimitiveTypeDeclaration(std::string &&name) + : name{std::move(name)} + { + } + + PrimitiveTypeDeclaration(const PrimitiveTypeDeclaration &other) = delete; + PrimitiveTypeDeclaration &operator=(const PrimitiveTypeDeclaration &&other) = delete; + PrimitiveTypeDeclaration(PrimitiveTypeDeclaration &&other) = default; + PrimitiveTypeDeclaration &operator=(PrimitiveTypeDeclaration &&other) = default; + + std::string name; + std::vector parentTypes; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Unsupported +{ + explicit Unsupported() = default; + Unsupported(const Unsupported &other) = delete; + Unsupported &operator=(const Unsupported &&other) = delete; + Unsupported(Unsupported &&other) = default; + Unsupported &operator=(Unsupported &&other) = default; + + std::string type; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Variable +{ + explicit Variable(VariableDeclaration &declaration) + : declaration{declaration} + { + } + + Variable(const Variable &other) = delete; + Variable &operator=(const Variable &&other) = delete; + Variable(Variable &&other) = default; + Variable &operator=(Variable &&other) = default; + + VariableDeclaration &declaration; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct VariableDeclaration +{ + explicit VariableDeclaration(std::string &&name, std::experimental::optional type = std::experimental::nullopt, bool isDirty = true) + : name{std::move(name)}, + type{std::move(type)}, + isDirty{isDirty} + { + } + + VariableDeclaration(const VariableDeclaration &other) = delete; + VariableDeclaration &operator=(const VariableDeclaration &&other) = delete; + VariableDeclaration(VariableDeclaration &&other) = default; + VariableDeclaration &operator=(VariableDeclaration &&other) = default; + + std::string name; + std::experimental::optional type; + bool isDirty{true}; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Compounds +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Predicate +{ + explicit Predicate(PredicateDeclaration &declaration) + : declaration{declaration} + { + } + + Predicate(const Predicate &other) = delete; + Predicate &operator=(const Predicate &&other) = delete; + Predicate(Predicate &&other) = default; + Predicate &operator=(Predicate &&other) = default; + + std::string name; + Terms arguments; + + PredicateDeclaration &declaration; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct PredicateDeclaration +{ + explicit PredicateDeclaration(std::string &&name, VariableDeclarations &¶meters) + : name{std::move(name)}, + parameters{std::move(parameters)} + { + } + + PredicateDeclaration(const PredicateDeclaration &other) = delete; + PredicateDeclaration &operator=(const PredicateDeclaration &&other) = delete; + PredicateDeclaration(PredicateDeclaration &&other) = default; + PredicateDeclaration &operator=(PredicateDeclaration &&other) = default; + + std::string name; + VariableDeclarations parameters; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Expressions: Base Classes +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Binary +{ + explicit Binary(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight) + : argumentLeft{std::move(argumentLeft)}, + argumentRight{std::move(argumentRight)} + { + } + + Binary(const Binary &other) = delete; + Binary &operator=(const Binary &&other) = delete; + Binary(Binary &&other) = default; + Binary &operator=(Binary &&other) = default; + + ArgumentLeft argumentLeft; + ArgumentRight argumentRight; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct NAry +{ + using Arguments = std::vector; + + explicit NAry(Arguments &&arguments) noexcept + : arguments{std::move(arguments)} + { + } + + NAry(const NAry &other) = delete; + NAry &operator=(const NAry &&other) = delete; + NAry(NAry &&other) = default; + NAry &operator=(NAry &&other) = default; + + Arguments arguments; + + protected: + static Arguments copyArguments(const NAry &other) + { + Arguments arguments; + arguments.reserve(other.arguments.size()); + + for (const auto &argument : other.arguments) + arguments.emplace_back(std::move(deepCopyVariant(argument))); + + return arguments; + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Quantified +{ + using Parameters = VariableDeclarations; + + explicit Quantified(Parameters &¶meters, Argument &&argument) + : parameters{std::move(parameters)}, + argument{std::move(argument)} + { + } + + Quantified(const Quantified &other) = delete; + Quantified &operator=(const Quantified &&other) = delete; + Quantified(Quantified &&other) = default; + Quantified &operator=(Quantified &&other) = default; + + Parameters parameters; + Argument argument; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Expressions +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct And: public NAry, Argument> +{ + using typename NAry, Argument>::Arguments; + static constexpr const auto Identifier = "and"; + + explicit And(Arguments &&arguments) noexcept + : NAry, Argument>(std::move(arguments)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct At +{ + static constexpr const auto TimePointStart = std::numeric_limits::max(); + static constexpr const auto TimePointEnd = std::numeric_limits::max() - 1; + + At(std::size_t timePoint, Argument &&argument) + : timePoint{timePoint}, + argument{std::move(argument)} + { + } + + At(const At &other) = delete; + At &operator=(const At &&other) = delete; + At(At &&other) = default; + At &operator=(At &&other) = default; + + std::size_t timePoint; + Argument argument; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Either: public NAry, Argument> +{ + using typename NAry, Argument>::Arguments; + static constexpr const auto Identifier = "either"; + + explicit Either(Arguments &&arguments) noexcept + : NAry, Argument>(std::move(arguments)) + { + } + + Either(const Either &other) + : NAry, Argument>(this->copyArguments(other)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Exists: public Quantified, Argument> +{ + static constexpr const auto Identifier = "exists"; + + explicit Exists(VariableDeclarations &¶meters, Argument &&argument) + : Quantified, Argument>(std::move(parameters), std::move(argument)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct ForAll: public Quantified, Argument> +{ + static constexpr const auto Identifier = "forall"; + + explicit ForAll(VariableDeclarations &¶meters, Argument &&argument) + : Quantified, Argument>(std::move(parameters), std::move(argument)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Imply: public Binary, Argument> +{ + static constexpr const auto Identifier = "imply"; + + // TODO: make noexcept consistent + explicit Imply(Argument &&argumentLeft, Argument &&argumentRight) + : Binary, Argument>(std::move(argumentLeft), std::move(argumentRight)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Not +{ + explicit Not(Argument &&argument) + : argument{std::move(argument)} + { + } + + Not(const Not &other) = delete; + Not &operator=(const Not &&other) = delete; + Not(Not &&other) = default; + Not &operator=(Not &&other) = default; + + Argument argument; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct Or: public NAry, Argument> +{ + using typename NAry, Argument>::Arguments; + static constexpr const auto Identifier = "or"; + + explicit Or(Arguments &&arguments) noexcept + : NAry, Argument>(std::move(arguments)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct When: public Binary, ArgumentLeft, ArgumentRight> +{ + static constexpr const auto Identifier = "when"; + + explicit When(ArgumentLeft &&argumentLeft, ArgumentRight &&argumentRight) + : Binary, ArgumentLeft, ArgumentRight>(std::move(argumentLeft), std::move(argumentRight)) + { + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PDDL Structure +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Action +{ + Action(const Action &other) = delete; + Action &operator=(const Action &&other) = delete; + Action(Action &&other) = default; + Action &operator=(Action &&other) = default; + + std::string name; + + ast::VariableDeclarations parameters; + std::experimental::optional precondition; + std::experimental::optional effect; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Domain +{ + Domain(const Domain &other) = delete; + Domain &operator=(const Domain &&other) = delete; + Domain(Domain &&other) = default; + Domain &operator=(Domain &&other) = default; + + std::string name; + Requirements requirements; + ast::PrimitiveTypeDeclarations types; + ast::ConstantDeclarations constants; + ast::PredicateDeclarations predicates; + std::vector actions; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct InitialState +{ + InitialState(const InitialState &other) = delete; + InitialState &operator=(const InitialState &&other) = delete; + InitialState(InitialState &&other) = default; + InitialState &operator=(InitialState &&other) = default; + + ast::Facts facts; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Problem +{ + Problem(const Problem &other) = delete; + Problem &operator=(const Problem &&other) = delete; + Problem(Problem &&other) = default; + Problem &operator=(Problem &&other) = default; + + Domain &domain; + std::string name; + Requirements requirements; + ast::ConstantDeclarations objects; + InitialState initialState; + std::experimental::optional goal; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class Requirement +{ + STRIPS, + Typing, + NegativePreconditions, + DisjunctivePreconditions, + Equality, + ExistentialPreconditions, + UniversalPreconditions, + QuantifiedPreconditions, + ConditionalEffects, + Fluents, + NumericFluents, + ObjectFluents, + ADL, + DurativeActions, + DurationInequalities, + ContinuousEffects, + DerivedPredicates, + TimedInitialLiterals, + Preferences, + Constraints, + ActionCosts, + GoalUtilities +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Description +{ + Description(const Description &other) = delete; + Description &operator=(const Description &&other) = delete; + Description(Description &&other) = default; + Description &operator=(Description &&other) = default; + + Domain domain; + std::experimental::optional problem; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/ASTForward.h b/lib/pddlparse/include/pddlparse/ASTForward.h new file mode 100644 index 0000000..399dbcb --- /dev/null +++ b/lib/pddlparse/include/pddlparse/ASTForward.h @@ -0,0 +1,194 @@ +#ifndef __PDDL_PARSE__AST_FORWARD_H +#define __PDDL_PARSE__AST_FORWARD_H + +#include +#include +#include +#include +#include + +#include + +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// AST Forward Declarations +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace ast +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Primitives +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Constant; +struct ConstantDeclaration; +using ConstantDeclarations = std::vector; +struct Dummy; +struct PrimitiveType; +using PrimitiveTypes = std::vector; +struct PrimitiveTypeDeclaration; +using PrimitiveTypeDeclarations = std::vector; +struct Unsupported; +struct Variable; +using Variables = std::vector; +struct VariableDeclaration; +using VariableDeclarations = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Compounds +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Predicate; +using Predicates = std::vector; +struct PredicateDeclaration; +using PredicateDeclarations = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Expressions +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +struct And; +template +struct At; +template +struct Either; +template +struct Exists; +template +struct ForAll; +template +struct Imply; +template +struct Not; +template +struct Or; +template +struct When; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// PDDL Structure +//////////////////////////////////////////////////////////////////////////////////////////////////// + +struct Description; +struct Domain; +struct Problem; +enum class Requirement; +using Requirements = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Variants +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using TermT = Variant< + Constant, + Variable>; + +class Term : public TermT +{ + using TermT::TermT; +}; + +using Terms = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using AtomicFormulaT = Variant< + Predicate, + Unsupported>; + +class AtomicFormula : public AtomicFormulaT +{ + using AtomicFormulaT::AtomicFormulaT; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class Precondition; + +using PreconditionT = Variant< + AtomicFormula, + And, + Exists, + ForAll, + Imply, + Not, + Or, + Unsupported>; + +class Precondition : public PreconditionT +{ + using PreconditionT::PreconditionT; +}; + +using Preconditions = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class Effect; + +using EffectT = Variant< + AtomicFormula, + And, + ForAll, + Not, + When, + Unsupported>; + +class Effect : public EffectT +{ + using EffectT::EffectT; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using TypeT = Variant< + Either, + PrimitiveType>; + +class Type : public TypeT +{ + using TypeT::TypeT; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using LiteralT = Variant< + AtomicFormula, + Not>; + +class Literal : public LiteralT +{ + using LiteralT::LiteralT; +}; + +using Literals = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using FactT = Variant< + AtomicFormula, + At>; + +class Fact : public FactT +{ + using FactT::FactT; +}; + +using Facts = std::vector; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using Goal = Precondition; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/Variant.h b/lib/pddlparse/include/pddlparse/Variant.h new file mode 100644 index 0000000..8e10e86 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/Variant.h @@ -0,0 +1,281 @@ +#ifndef __PDDL_PARSE__VARIANT_H +#define __PDDL_PARSE__VARIANT_H + +#include +#include +#include + +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Variant (from clingo, written by Roland Kaminski) +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace detail { + +template +struct TypeInList : std::false_type { }; + +template +struct TypeInList : std::true_type { }; + +template +struct TypeInList : TypeInList { }; + +template +struct VariantHolder; + +template +struct VariantHolder { + bool check_type() const { return type_ == 0; } + void emplace() { } + void emplace2() { } + void copy(VariantHolder const &) { } + void destroy() { + type_ = 0; + data_ = nullptr; + } + void print(std::ostream &) const { } + void swap(VariantHolder &other) { + std::swap(type_, other.type_); + std::swap(data_, other.data_); + } + unsigned type_ = 0; + void *data_ = nullptr; +}; + +template +struct VariantHolder : VariantHolder{ + using Helper = VariantHolder; + using Helper::check_type; + using Helper::emplace; + using Helper::emplace2; + using Helper::data_; + using Helper::type_; + bool check_type(T *) const { return type_ == n; } + template + void emplace(T *, Args&& ...x) { + data_ = new T{std::forward(x)...}; + type_ = n; + } + // NOTE: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467 + template + void emplace2(T *, Args&& ...x) { + data_ = new T(std::forward(x)...); + type_ = n; + } + void copy(VariantHolder const &src) { + if (src.type_ == n) { + data_ = new T(*static_cast(src.data_)); + type_ = src.type_; + } + Helper::copy(src); + } + // NOTE: workaround for visual studio (C++14 can also simply use auto) +# define CLINGO_VARIANT_RETURN(Type) decltype(std::declval().visit(std::declval(), std::declval()...)) + template + using Ret_ = CLINGO_VARIANT_RETURN(T); + template + using ConstRet_ = CLINGO_VARIANT_RETURN(T const); + // non-const + template + auto accept_(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) { + static_assert(std::is_same, typename Helper::template Ret_>::value, ""); + return n == type_ + ? visitor.visit(*static_cast(data_), std::forward(args)...) + : Helper::template accept(std::forward(visitor), std::forward(args)...); + } + template + auto accept_(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) { + assert(n == type_); + return visitor.visit(*static_cast(data_), std::forward(args)...); + } + template + auto accept(V &&visitor, Args &&... args) -> CLINGO_VARIANT_RETURN(T) { + return accept_(std::forward(visitor), std::forward(args)...); + } + // const + template + auto accept_(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) { + static_assert(std::is_same, typename Helper::template ConstRet_>::value, ""); + return n == type_ + ? visitor.visit(*static_cast(data_), std::forward(args)...) + : Helper::template accept(std::forward(visitor), std::forward(args)...); + } + template + auto accept_(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) { + assert(n == type_); + return visitor.visit(*static_cast(data_), std::forward(args)...); + } + template + auto accept(V &&visitor, Args &&... args) const -> CLINGO_VARIANT_RETURN(T const) { + return accept_(std::forward(visitor), std::forward(args)...); + } +# undef CLINGO_VARIANT_RETURN + void destroy() { + if (n == type_) { delete static_cast(data_); } + Helper::destroy(); + } + void print(std::ostream &out) const { + if (n == type_) { out << *static_cast(data_); } + Helper::print(out); + } +}; + +} + +template +class Optional { +public: + Optional() { } + Optional(T const &x) : data_(new T(x)) { } + Optional(T &x) : data_(new T(x)) { } + Optional(T &&x) : data_(new T(std::move(x))) { } + template + Optional(Args&&... x) : data_(new T{std::forward(x)...}) { } + Optional(Optional &&opt) noexcept : data_(opt.data_.release()) { } + Optional(Optional const &opt) : data_(opt ? new T(*opt.get()) : nullptr) { } + Optional &operator=(T const &x) { + clear(); + data_.reset(new T(x)); + } + Optional &operator=(T &x) { + clear(); + data_.reset(new T(x)); + } + Optional &operator=(T &&x) { + clear(); + data_.reset(new T(std::move(x))); + } + Optional &operator=(Optional &&opt) noexcept { + data_ = std::move(opt.data_); + } + Optional &operator=(Optional const &opt) { + clear(); + data_.reset(opt ? new T(*opt.get()) : nullptr); + } + T *get() { return data_.get(); } + T const *get() const { return data_.get(); } + T *operator->() { return get(); } + T const *operator->() const { return get(); } + T &operator*() & { return *get(); } + T const &operator*() const & { return *get(); } + T &&operator*() && { return std::move(*get()); } + T const &&operator*() const && { return std::move(*get()); } + template + void emplace(Args&&... x) { + clear(); + data_(new T{std::forward(x)...}); + } + void clear() { data_.reset(nullptr); } + explicit operator bool() const { return data_.get() != nullptr; } +private: + std::unique_ptr data_; +}; + +template +class Variant { + using Holder = detail::VariantHolder<1, T...>; +public: + Variant(Variant const &other) : Variant(other.data_) { } + Variant(Variant &&other) noexcept { data_.swap(other.data_); } + template + Variant(U &&u, typename std::enable_if::value>::type * = nullptr) { emplace2(std::forward(u)); } + template + Variant(U &u, typename std::enable_if::value>::type * = nullptr) { emplace2(u); } + template + Variant(U const &u, typename std::enable_if::value>::type * = nullptr) { emplace2(u); } + template + static Variant make(Args&& ...args) { + Variant x; + x.data_.emplace(static_cast(nullptr), std::forward(args)...); + return std::move(x); + } + ~Variant() { data_.destroy(); } + Variant &operator=(Variant const &other) { return *this = other.data_; } + Variant &operator=(Variant &&other) noexcept { return *this = std::move(other.data_); } + template + typename std::enable_if::value, Variant>::type &operator=(U &&u) { + emplace2(std::forward(u)); + return *this; + } + template + typename std::enable_if::value, Variant>::type &operator=(U &u) { + emplace2(u); + return *this; + } + template + typename std::enable_if::value, Variant>::type &operator=(U const &u) { + emplace2(u); + return *this; + } + template + U &get() { + if (!data_.check_type(static_cast(nullptr))) { throw std::bad_cast(); } + return *static_cast(data_.data_); + } + template + U const &get() const { + if (!data_.check_type(static_cast(nullptr))) { throw std::bad_cast(); } + return *static_cast(data_.data_); + } + template + void emplace(Args&& ...args) { + Variant x; + x.data_.emplace(static_cast(nullptr), std::forward(args)...); + data_.swap(x.data_); + } + template + bool is() const { return data_.check_type(static_cast(nullptr)); } + void swap(Variant &other) { data_.swap(other.data_); } + template + typename Holder::template Ret_ accept(V &&visitor, Args &&... args) { + return data_.accept(std::forward(visitor), std::forward(args)...); + } + template + typename Holder::template ConstRet_ accept(V &&visitor, Args &&... args) const { + return data_.accept(std::forward(visitor), std::forward(args)...); + } + friend std::ostream &operator<<(std::ostream &out, Variant const &x) { + x.data_.print(out); + return out; + } + +private: + Variant() { } + Variant(Holder const &data) { + data_.copy(data); + } + Variant &operator=(Holder const &data) { + Variant x(data); + data_.swap(x.data_); + return *this; + } + Variant &operator=(Holder &&data) noexcept { + Holder x; + x.swap(data); + // Destroy the old data_ only after securing the new data + // Otherwise, data would be destroyed together with data_ if it was a descendant of data_ + data_.destroy(); + x.swap(data_); + return *this; + } + template + void emplace2(Args&& ...args) { + Variant x; + x.data_.emplace2(static_cast(nullptr), std::forward(args)...); + data_.swap(x.data_); + } + +private: + Holder data_; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/Parser.h b/lib/pddlparse/include/pddlparse/detail/Parser.h new file mode 100644 index 0000000..b9170b2 --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/Parser.h @@ -0,0 +1,56 @@ +#ifndef __PDDL_PARSE__DETAIL__PARSER_H +#define __PDDL_PARSE__DETAIL__PARSER_H + +#include + +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Parser +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class PDDLParserPolicy +{ + public: + static char transformCharacter(char c) noexcept + { + return std::tolower(c); + } + + static bool isWhiteSpaceCharacter(char c) + { + return std::iswspace(c); + } + + static bool isBlankCharacter(char c) + { + return std::isblank(c); + } + + static bool isIdentifierCharacter(char c) + { + return c != '?' + && c != '(' + && c != ')' + && c != ';' + && std::isgraph(c); + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using Parser = parsebase::Parser; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/include/pddlparse/detail/VariableStack.h b/lib/pddlparse/include/pddlparse/detail/VariableStack.h new file mode 100644 index 0000000..22e000c --- /dev/null +++ b/lib/pddlparse/include/pddlparse/detail/VariableStack.h @@ -0,0 +1,32 @@ +#ifndef __PDDL_PARSE__DETAIL__VARIABLE_STACK_H +#define __PDDL_PARSE__DETAIL__VARIABLE_STACK_H + +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableStack +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class VariableStack +{ + public: + void push(ast::VariableDeclarations *variables); + void pop(); + + private: + std::vector m_variableStack; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/lib/pddlparse/src/CMakeLists.txt b/lib/pddlparse/src/CMakeLists.txt new file mode 100644 index 0000000..cd5788c --- /dev/null +++ b/lib/pddlparse/src/CMakeLists.txt @@ -0,0 +1,28 @@ +set(target pddlparse) + +file(GLOB core_sources "pddlparse/*.cpp") +file(GLOB core_headers "../include/pddlparse/*.h") + +file(GLOB detail_sources "pddlparse/detail/*.cpp") +file(GLOB detail_headers "../include/pddlparse/detail/*.h") + +set(includes + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/../../lib/parsebase/include +) + +set(sources + ${core_sources} + ${core_headers} + + ${detail_sources} + ${detail_headers} +) + +set(libraries + parsebase +) + +add_library(${target} ${sources}) +target_include_directories(${target} PRIVATE ${includes}) +target_link_libraries(${target} ${libraries}) diff --git a/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp b/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp new file mode 100644 index 0000000..16f182e --- /dev/null +++ b/lib/pddlparse/src/pddlparse/detail/VariableStack.cpp @@ -0,0 +1,31 @@ +#include + +#include + +namespace pddl +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableStack +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableStack::push(ast::VariableDeclarations *variables) +{ + m_variableStack.push_back(variables); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableStack::pop() +{ + m_variableStack.pop_back(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/lib/pddlparse/tests/CMakeLists.txt b/lib/pddlparse/tests/CMakeLists.txt new file mode 100644 index 0000000..9b3c78a --- /dev/null +++ b/lib/pddlparse/tests/CMakeLists.txt @@ -0,0 +1,21 @@ +set(target pddlparse-tests) + +file(GLOB core_sources "*.cpp") + +set(includes + ${PROJECT_SOURCE_DIR}/include + ${PROJECT_SOURCE_DIR}/../../lib/catch/single_include +) + +set(libraries + pddlparse +) + +add_executable(${target} ${core_sources}) +target_include_directories(${target} PRIVATE ${includes}) +target_link_libraries(${target} ${libraries}) + +add_custom_target(run-pddlparse-tests + COMMAND ${CMAKE_BINARY_DIR}/bin/pddlparse-tests + DEPENDS ${target} + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/tests) diff --git a/lib/pddlparse/tests/main.cpp b/lib/pddlparse/tests/main.cpp new file mode 100644 index 0000000..b3143fb --- /dev/null +++ b/lib/pddlparse/tests/main.cpp @@ -0,0 +1,2 @@ +#define CATCH_CONFIG_MAIN +#include