Implemented variable stack for parsing nested variable lists (as within quantified expressions).
This commit is contained in:
parent
f4f0e07bc1
commit
eb28ed3938
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <plasp/pddl/Expression.h>
|
#include <plasp/pddl/Expression.h>
|
||||||
#include <plasp/pddl/Requirement.h>
|
#include <plasp/pddl/Requirement.h>
|
||||||
|
#include <plasp/pddl/VariableStack.h>
|
||||||
|
|
||||||
namespace plasp
|
namespace plasp
|
||||||
{
|
{
|
||||||
@ -18,8 +19,8 @@ namespace pddl
|
|||||||
class ExpressionContext
|
class ExpressionContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExpressionContext(Domain &domain, expressions::Variables ¶meters);
|
ExpressionContext(Domain &domain);
|
||||||
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters);
|
ExpressionContext(Domain &domain, Problem *problem);
|
||||||
|
|
||||||
bool hasRequirement(Requirement::Type requirementType) const;
|
bool hasRequirement(Requirement::Type requirementType) const;
|
||||||
void checkRequirement(Requirement::Type requirementType) const;
|
void checkRequirement(Requirement::Type requirementType) const;
|
||||||
@ -27,7 +28,7 @@ class ExpressionContext
|
|||||||
Domain &domain;
|
Domain &domain;
|
||||||
Problem *problem;
|
Problem *problem;
|
||||||
|
|
||||||
expressions::Variables ¶meters;
|
VariableStack variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
34
include/plasp/pddl/VariableStack.h
Normal file
34
include/plasp/pddl/VariableStack.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#ifndef __PLASP__PDDL__VARIABLE_STACK_H
|
||||||
|
#define __PLASP__PDDL__VARIABLE_STACK_H
|
||||||
|
|
||||||
|
#include <plasp/pddl/expressions/Variable.h>
|
||||||
|
|
||||||
|
namespace plasp
|
||||||
|
{
|
||||||
|
namespace pddl
|
||||||
|
{
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// VariableStack
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class VariableStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void push(expressions::Variables *variables);
|
||||||
|
void pop();
|
||||||
|
|
||||||
|
expressions::VariablePointer parseAndFind(Context &context);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<expressions::Variables *> m_variableStack;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -26,9 +26,6 @@ class Variable: public ExpressionCRTP<Variable>
|
|||||||
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext,
|
static void parseTypedDeclarations(Context &context, ExpressionContext &expressionContext,
|
||||||
Variables &variables);
|
Variables &variables);
|
||||||
|
|
||||||
static VariablePointer parseAndFind(Context &context,
|
|
||||||
const ExpressionContext &expressionContext);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setName(std::string name);
|
void setName(std::string name);
|
||||||
const std::string &name() const;
|
const std::string &name() const;
|
||||||
|
@ -29,7 +29,8 @@ void Action::parseDeclaration(Context &context, Domain &domain)
|
|||||||
parser.expect<std::string>(":parameters");
|
parser.expect<std::string>(":parameters");
|
||||||
parser.expect<std::string>("(");
|
parser.expect<std::string>("(");
|
||||||
|
|
||||||
ExpressionContext expressionContext(domain, action->m_parameters);
|
ExpressionContext expressionContext(domain);
|
||||||
|
expressionContext.variables.push(&action->m_parameters);
|
||||||
|
|
||||||
// Read parameters
|
// Read parameters
|
||||||
expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters);
|
expressions::Variable::parseTypedDeclarations(context, expressionContext, action->m_parameters);
|
||||||
|
@ -14,19 +14,17 @@ namespace pddl
|
|||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables ¶meters)
|
ExpressionContext::ExpressionContext(Domain &domain)
|
||||||
: domain(domain),
|
: domain(domain),
|
||||||
problem(nullptr),
|
problem(nullptr)
|
||||||
parameters(parameters)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables ¶meters)
|
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem)
|
||||||
: domain(domain),
|
: domain(domain),
|
||||||
problem{problem},
|
problem{problem}
|
||||||
parameters(parameters)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,9 +333,7 @@ void Problem::parseInitialStateSection()
|
|||||||
parser.expect<std::string>(":");
|
parser.expect<std::string>(":");
|
||||||
parser.expect<std::string>("init");
|
parser.expect<std::string>("init");
|
||||||
|
|
||||||
// TODO: remove workaround
|
ExpressionContext expressionContext(m_domain, this);
|
||||||
expressions::Variables noParameters;
|
|
||||||
ExpressionContext expressionContext(m_domain, this, noParameters);
|
|
||||||
|
|
||||||
m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
|
m_initialState = InitialState::parseDeclaration(m_context, expressionContext);
|
||||||
|
|
||||||
@ -352,9 +350,7 @@ void Problem::parseGoalSection()
|
|||||||
parser.expect<std::string>(":");
|
parser.expect<std::string>(":");
|
||||||
parser.expect<std::string>("goal");
|
parser.expect<std::string>("goal");
|
||||||
|
|
||||||
// TODO: remove workaround
|
ExpressionContext expressionContext(m_domain, this);
|
||||||
expressions::Variables noParameters;
|
|
||||||
ExpressionContext expressionContext(m_domain, this, noParameters);
|
|
||||||
|
|
||||||
m_goal = parsePreconditionExpression(m_context, expressionContext);
|
m_goal = parsePreconditionExpression(m_context, expressionContext);
|
||||||
|
|
||||||
|
62
src/plasp/pddl/VariableStack.cpp
Normal file
62
src/plasp/pddl/VariableStack.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#include <plasp/pddl/VariableStack.h>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Context.h>
|
||||||
|
|
||||||
|
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<std::string>("?");
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -66,7 +66,7 @@ PredicatePointer Predicate::parse(Context &context, ExpressionContext &expressio
|
|||||||
// Parse variables
|
// Parse variables
|
||||||
if (context.parser.currentCharacter() == '?')
|
if (context.parser.currentCharacter() == '?')
|
||||||
{
|
{
|
||||||
const auto variable = Variable::parseAndFind(context, expressionContext);
|
const auto variable = expressionContext.variables.parseAndFind(context);
|
||||||
predicate->m_arguments.emplace_back(variable);
|
predicate->m_arguments.emplace_back(variable);
|
||||||
}
|
}
|
||||||
// Parse constants
|
// Parse constants
|
||||||
|
@ -39,7 +39,8 @@ void PredicateDeclaration::parse(Context &context, Domain &domain)
|
|||||||
|
|
||||||
context.parser.skipWhiteSpace();
|
context.parser.skipWhiteSpace();
|
||||||
|
|
||||||
ExpressionContext expressionContext(domain, predicate->m_parameters);
|
ExpressionContext expressionContext(domain);
|
||||||
|
expressionContext.variables.push(&predicate->m_parameters);
|
||||||
|
|
||||||
// Parse arguments
|
// Parse arguments
|
||||||
expressions::Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters);
|
expressions::Variable::parseTypedDeclarations(context, expressionContext, predicate->m_parameters);
|
||||||
|
@ -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<std::string>("?");
|
|
||||||
|
|
||||||
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)
|
void Variable::setName(std::string name)
|
||||||
{
|
{
|
||||||
m_name = name;
|
m_name = name;
|
||||||
|
Reference in New Issue
Block a user