diff --git a/include/plasp/pddl/ExpressionContext.h b/include/plasp/pddl/ExpressionContext.h index 20bb013..983baee 100644 --- a/include/plasp/pddl/ExpressionContext.h +++ b/include/plasp/pddl/ExpressionContext.h @@ -3,6 +3,7 @@ #include #include +#include namespace plasp { @@ -18,8 +19,8 @@ namespace pddl class ExpressionContext { public: - ExpressionContext(Domain &domain, expressions::Variables ¶meters); - ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters); + ExpressionContext(Domain &domain); + ExpressionContext(Domain &domain, Problem *problem); bool hasRequirement(Requirement::Type requirementType) const; void checkRequirement(Requirement::Type requirementType) const; @@ -27,7 +28,7 @@ class ExpressionContext Domain &domain; Problem *problem; - expressions::Variables ¶meters; + VariableStack variables; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/pddl/VariableStack.h b/include/plasp/pddl/VariableStack.h new file mode 100644 index 0000000..452902f --- /dev/null +++ b/include/plasp/pddl/VariableStack.h @@ -0,0 +1,34 @@ +#ifndef __PLASP__PDDL__VARIABLE_STACK_H +#define __PLASP__PDDL__VARIABLE_STACK_H + +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableStack +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class VariableStack +{ + public: + void push(expressions::Variables *variables); + void pop(); + + expressions::VariablePointer parseAndFind(Context &context); + + private: + std::vector m_variableStack; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/plasp/pddl/expressions/Variable.h b/include/plasp/pddl/expressions/Variable.h index 3c7ba63..654d0b4 100644 --- a/include/plasp/pddl/expressions/Variable.h +++ b/include/plasp/pddl/expressions/Variable.h @@ -26,9 +26,6 @@ class Variable: public ExpressionCRTP static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext, Variables &variables); - static VariablePointer parseAndFind(Context &context, - const ExpressionContext &expressionContext); - public: void setName(std::string name); const std::string &name() const; diff --git a/src/plasp/pddl/Action.cpp b/src/plasp/pddl/Action.cpp index 2bbb7df..657b68a 100644 --- a/src/plasp/pddl/Action.cpp +++ b/src/plasp/pddl/Action.cpp @@ -29,7 +29,8 @@ void Action::parseDeclaration(Context &context, Domain &domain) parser.expect(":parameters"); parser.expect("("); - ExpressionContext expressionContext(domain, action->m_parameters); + ExpressionContext expressionContext(domain); + expressionContext.variables.push(&action->m_parameters); // Read parameters expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters); diff --git a/src/plasp/pddl/ExpressionContext.cpp b/src/plasp/pddl/ExpressionContext.cpp index ed3fb97..25b2275 100644 --- a/src/plasp/pddl/ExpressionContext.cpp +++ b/src/plasp/pddl/ExpressionContext.cpp @@ -14,19 +14,17 @@ namespace pddl // //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables ¶meters) +ExpressionContext::ExpressionContext(Domain &domain) : domain(domain), - problem(nullptr), - parameters(parameters) + problem(nullptr) { } //////////////////////////////////////////////////////////////////////////////////////////////////// -ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters) +ExpressionContext::ExpressionContext(Domain &domain, Problem *problem) : domain(domain), - problem{problem}, - parameters(parameters) + problem{problem} { } diff --git a/src/plasp/pddl/Problem.cpp b/src/plasp/pddl/Problem.cpp index 5673b22..f4d38fd 100644 --- a/src/plasp/pddl/Problem.cpp +++ b/src/plasp/pddl/Problem.cpp @@ -333,9 +333,7 @@ void Problem::parseInitialStateSection() parser.expect(":"); parser.expect("init"); - // TODO: remove workaround - expressions::Variables noParameters; - ExpressionContext expressionContext(m_domain, this, noParameters); + ExpressionContext expressionContext(m_domain, this); m_initialState = InitialState::parseDeclaration(m_context, expressionContext); @@ -352,9 +350,7 @@ void Problem::parseGoalSection() parser.expect(":"); parser.expect("goal"); - // TODO: remove workaround - expressions::Variables noParameters; - ExpressionContext expressionContext(m_domain, this, noParameters); + ExpressionContext expressionContext(m_domain, this); m_goal = parsePreconditionExpression(m_context, expressionContext); diff --git a/src/plasp/pddl/VariableStack.cpp b/src/plasp/pddl/VariableStack.cpp new file mode 100644 index 0000000..54d0f35 --- /dev/null +++ b/src/plasp/pddl/VariableStack.cpp @@ -0,0 +1,62 @@ +#include + +#include + +namespace plasp +{ +namespace pddl +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// VariableStack +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableStack::push(expressions::Variables *variables) +{ + m_variableStack.push_back(variables); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void VariableStack::pop() +{ + m_variableStack.pop_back(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +expressions::VariablePointer VariableStack::parseAndFind(plasp::pddl::Context &context) +{ + auto &parser = context.parser; + + parser.skipWhiteSpace(); + + parser.expect("?"); + + const auto variableName = parser.parseIdentifier(); + + for (auto i = m_variableStack.crbegin(); i != m_variableStack.crend(); i++) + { + const auto *variables = *i; + + BOOST_ASSERT(variables); + + const auto match = std::find_if(variables->crbegin(), variables->crend(), + [&](const auto &variable) + { + return variable->name() == variableName; + }); + + if (match != variables->crend()) + return match->get(); + } + + throw utils::ParserException(parser.coordinate(), "variable “" + variableName + "” used but never declared"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} diff --git a/src/plasp/pddl/expressions/Predicate.cpp b/src/plasp/pddl/expressions/Predicate.cpp index 0e40cbc..fc10da9 100644 --- a/src/plasp/pddl/expressions/Predicate.cpp +++ b/src/plasp/pddl/expressions/Predicate.cpp @@ -66,7 +66,7 @@ PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressio // Parse variables if (context.parser.currentCharacter() == '?') { - const auto variable = Variable::parseAndFind(context, expressionContext); + const auto variable = expressionContext.variables.parseAndFind(context); predicate->m_arguments.emplace_back(variable); } // Parse constants diff --git a/src/plasp/pddl/expressions/PredicateDeclaration.cpp b/src/plasp/pddl/expressions/PredicateDeclaration.cpp index fec9d1e..b492a1c 100644 --- a/src/plasp/pddl/expressions/PredicateDeclaration.cpp +++ b/src/plasp/pddl/expressions/PredicateDeclaration.cpp @@ -39,7 +39,8 @@ void PredicateDeclaration::parse(Context &context, Domain &domain) context.parser.skipWhiteSpace(); - ExpressionContext expressionContext(domain, predicate->m_parameters); + ExpressionContext expressionContext(domain); + expressionContext.variables.push(&predicate->m_parameters); // Parse arguments expressions::Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters); diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index 7609588..67a72a8 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -136,32 +136,6 @@ void Variable::parseTypedDeclarations(Context &context, ExpressionContext &expre //////////////////////////////////////////////////////////////////////////////////////////////////// -VariablePointer Variable::parseAndFind(Context &context, const ExpressionContext &expressionContext) -{ - auto &parser = context.parser; - - parser.skipWhiteSpace(); - - parser.expect("?"); - - const auto variableName = parser.parseIdentifier(); - - const auto &variables = expressionContext.parameters; - - const auto match = std::find_if(variables.cbegin(), variables.cend(), - [&](const auto &variable) - { - return variable->name() == variableName; - }); - - if (match == variables.cend()) - throw utils::ParserException(parser.coordinate(), "parameter “" + variableName + "” used but never declared"); - - return match->get(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - void Variable::setName(std::string name) { m_name = name;