Implemented variable stack for parsing nested variable lists (as within quantified expressions).

This commit is contained in:
Patrick Lühne 2016-09-06 17:34:07 +02:00
parent f4f0e07bc1
commit eb28ed3938
10 changed files with 111 additions and 47 deletions

View File

@ -3,6 +3,7 @@
#include <plasp/pddl/Expression.h>
#include <plasp/pddl/Requirement.h>
#include <plasp/pddl/VariableStack.h>
namespace plasp
{
@ -18,8 +19,8 @@ namespace pddl
class ExpressionContext
{
public:
ExpressionContext(Domain &domain, expressions::Variables &parameters);
ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters);
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 &parameters;
VariableStack variables;
};
////////////////////////////////////////////////////////////////////////////////////////////////////

View 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

View File

@ -26,9 +26,6 @@ class Variable: public ExpressionCRTP<Variable>
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;

View File

@ -29,7 +29,8 @@ void Action::parseDeclaration(Context &context, Domain &domain)
parser.expect<std::string>(":parameters");
parser.expect<std::string>("(");
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);

View File

@ -14,19 +14,17 @@ namespace pddl
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, expressions::Variables &parameters)
ExpressionContext::ExpressionContext(Domain &domain)
: domain(domain),
problem(nullptr),
parameters(parameters)
problem(nullptr)
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem, expressions::Variables &parameters)
ExpressionContext::ExpressionContext(Domain &domain, Problem *problem)
: domain(domain),
problem{problem},
parameters(parameters)
problem{problem}
{
}

View File

@ -333,9 +333,7 @@ void Problem::parseInitialStateSection()
parser.expect<std::string>(":");
parser.expect<std::string>("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<std::string>(":");
parser.expect<std::string>("goal");
// TODO: remove workaround
expressions::Variables noParameters;
ExpressionContext expressionContext(m_domain, this, noParameters);
ExpressionContext expressionContext(m_domain, this);
m_goal = parsePreconditionExpression(m_context, expressionContext);

View 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");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -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

View File

@ -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);

View File

@ -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)
{
m_name = name;