patrick
/
plasp
Archived
1
0
Fork 0

Parsing domains in two passes and continued working on parsing the initial state.

This commit is contained in:
Patrick Lühne 2016-06-09 01:25:18 +02:00
parent ff7a6b8c8f
commit 8428c20bd4
13 changed files with 380 additions and 175 deletions

View File

@ -26,7 +26,8 @@ class Domain
Domain(Context &context); Domain(Context &context);
public: public:
void readPDDL(); void findSections();
void parse();
void setName(std::string name); void setName(std::string name);
const std::string &name() const; const std::string &name() const;
@ -66,10 +67,20 @@ class Domain
Context &m_context; Context &m_context;
std::string m_name; std::string m_name;
utils::Parser::Position m_requirementsPosition;
Requirements m_requirements; Requirements m_requirements;
expressions::PrimitiveTypes m_primitiveTypes;
utils::Parser::Position m_typesPosition;
expressions::PrimitiveTypes m_types;
utils::Parser::Position m_constantsPosition;
expressions::Constants m_constants; expressions::Constants m_constants;
expressions::PredicateDeclarations m_predicateDeclarations;
utils::Parser::Position m_predicatesPosition;
expressions::PredicateDeclarations m_predicates;
std::vector<utils::Parser::Position> m_actionPositions;
std::vector<std::unique_ptr<Action>> m_actions; std::vector<std::unique_ptr<Action>> m_actions;
}; };

View File

@ -7,20 +7,27 @@ namespace plasp
{ {
namespace pddl namespace pddl
{ {
namespace expressions
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class InitialState
{ {
public:
static std::unique_ptr<InitialState> parseDeclaration(Context &context, const Problem &problem);
//////////////////////////////////////////////////////////////////////////////////////////////////// public:
// const Expressions &facts() const;
// Type
//
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseInitialState(Context &context); private:
Expressions m_facts;
};
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
}
} }
} }

View File

@ -3,6 +3,7 @@
#include <plasp/pddl/Context.h> #include <plasp/pddl/Context.h>
#include <plasp/pddl/Expression.h> #include <plasp/pddl/Expression.h>
#include <plasp/pddl/InitialState.h>
#include <plasp/pddl/Requirement.h> #include <plasp/pddl/Requirement.h>
namespace plasp namespace plasp
@ -21,7 +22,7 @@ class Problem
public: public:
Problem(Context &context, Domain &domain); Problem(Context &context, Domain &domain);
void readPDDL(); void parse();
bool isDeclared() const; bool isDeclared() const;
@ -37,6 +38,9 @@ class Problem
expressions::Constants &objects(); expressions::Constants &objects();
const expressions::Constants &objects() const; const expressions::Constants &objects() const;
InitialState &initialState();
const InitialState &initialState() const;
void checkConsistency(); void checkConsistency();
private: private:
@ -49,6 +53,8 @@ class Problem
void parseObjectSection(); void parseObjectSection();
void parseInitialStateSection();
Context &m_context; Context &m_context;
Domain &m_domain; Domain &m_domain;
bool m_isDeclared; bool m_isDeclared;
@ -57,6 +63,8 @@ class Problem
Requirements m_requirements; Requirements m_requirements;
expressions::Constants m_objects; expressions::Constants m_objects;
std::unique_ptr<InitialState> m_initialState;
}; };
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -27,7 +27,8 @@ class Constant: public Expression
static void parseTypedDeclaration(Context &context, Problem &problem); static void parseTypedDeclaration(Context &context, Problem &problem);
static void parseTypedDeclarations(Context &context, Problem &problem); static void parseTypedDeclarations(Context &context, Problem &problem);
static Constant *parseAndFind(Context &context, const ExpressionContext &expressionContext); static Constant *parseAndFind(Context &context, const Domain &domain);
static Constant *parseAndFind(Context &context, const Problem &problem);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;

View File

@ -21,6 +21,7 @@ class Predicate: public Expression
public: public:
static PredicatePointer parse(std::string name, Context &context, static PredicatePointer parse(std::string name, Context &context,
ExpressionContext &expressionContext); ExpressionContext &expressionContext);
static PredicatePointer parse(std::string name, Context &context, const Problem &problem);
public: public:
void accept(ExpressionVisitor &expressionVisitor) const override; void accept(ExpressionVisitor &expressionVisitor) const override;

View File

@ -106,12 +106,12 @@ void Description::parseContent()
throw ConsistencyException("No PDDL domain specified"); throw ConsistencyException("No PDDL domain specified");
m_context.parser.seek(m_domainPosition); m_context.parser.seek(m_domainPosition);
m_domain->readPDDL(); m_domain->parse();
if (m_problemPosition != -1) if (m_problemPosition != -1)
{ {
m_context.parser.seek(m_problemPosition); m_context.parser.seek(m_problemPosition);
m_problem->readPDDL(); m_problem->parse();
} }
} }
@ -119,41 +119,45 @@ void Description::parseContent()
void Description::findSections() void Description::findSections()
{ {
while (true) auto &parser = m_context.parser;
parser.skipWhiteSpace();
while (!parser.atEndOfStream())
{ {
m_context.parser.skipWhiteSpace(); const auto position = parser.position();
if (m_context.parser.atEndOfStream()) parser.expect<std::string>("(");
return; parser.expect<std::string>("define");
parser.expect<std::string>("(");
const auto position = m_context.parser.position(); if (parser.probe<std::string>("domain"))
m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define");
m_context.parser.expect<std::string>("(");
if (m_context.parser.probe<std::string>("domain"))
{ {
if (m_domainPosition != -1) if (m_domainPosition != -1)
throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); throw utils::ParserException(parser, "PDDL description may not contain two domains");
m_domainPosition = position; m_domainPosition = position;
parser.seek(position);
m_domain->findSections();
} }
else if (m_context.parser.probe<std::string>("problem")) else if (m_context.parser.probe<std::string>("problem"))
{ {
if (m_problemPosition != -1) if (m_problemPosition != -1)
throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems"); throw utils::ParserException(parser, "PDDL description may currently not contain two problems");
m_problemPosition = position; m_problemPosition = position;
skipSection(parser);
skipSection(parser);
} }
else else
{ {
const auto sectionIdentifier = m_context.parser.parse<std::string>(); const auto sectionIdentifier = parser.parse<std::string>();
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
} }
skipSection(m_context.parser); m_context.parser.skipWhiteSpace();
skipSection(m_context.parser);
} }
} }

View File

@ -11,6 +11,7 @@
#include <plasp/pddl/expressions/Variable.h> #include <plasp/pddl/expressions/Variable.h>
#include <plasp/utils/IO.h> #include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h> #include <plasp/utils/ParserException.h>
#include <plasp/utils/ParserWarning.h>
namespace plasp namespace plasp
{ {
@ -24,35 +25,129 @@ namespace pddl
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Domain::Domain(Context &context) Domain::Domain(Context &context)
: m_context(context) : m_context(context),
m_requirementsPosition{-1},
m_typesPosition{-1},
m_constantsPosition{-1},
m_predicatesPosition{-1}
{ {
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::readPDDL() void Domain::findSections()
{ {
m_context.parser.expect<std::string>("("); auto &parser = m_context.parser;
m_context.parser.expect<std::string>("define");
m_context.parser.expect<std::string>("("); parser.expect<std::string>("(");
m_context.parser.expect<std::string>("domain"); parser.expect<std::string>("define");
parser.expect<std::string>("(");
parser.expect<std::string>("domain");
m_name = m_context.parser.parseIdentifier(isIdentifier); m_name = m_context.parser.parseIdentifier(isIdentifier);
std::cout << "Found domain " << m_name << std::endl;
parser.expect<std::string>(")");
const auto setSectionPosition =
[&](const std::string &sectionName, auto &sectionPosition, const auto value, bool unique = false)
{
if (unique && sectionPosition != -1)
throw utils::ParserException(parser, "Only one \":" + sectionName + "\" section allowed");
sectionPosition = value;
};
parser.skipWhiteSpace();
// Find sections
while (parser.currentCharacter() != ')')
{
const auto position = parser.position();
parser.expect<std::string>("(");
parser.expect<std::string>(":");
// Save the parser position of the individual sections for later parsing
if (parser.probe<std::string>("requirements"))
setSectionPosition("requirements", m_requirementsPosition, position, true);
else if (parser.probe<std::string>("types"))
setSectionPosition("types", m_typesPosition, position, true);
else if (parser.probe<std::string>("constants"))
setSectionPosition("constants", m_constantsPosition, position, true);
else if (parser.probe<std::string>("predicates"))
setSectionPosition("predicates", m_predicatesPosition, position, true);
else if (parser.probe<std::string>("action"))
{
m_actionPositions.emplace_back(-1);
setSectionPosition("action", m_actionPositions.back(), position);
}
else if (parser.probe<std::string>("functions")
|| parser.probe<std::string>("constraints")
|| parser.probe<std::string>("durative-action")
|| parser.probe<std::string>("derived"))
{
parser.seek(position);
m_context.logger.parserWarning(parser, "Section type currently unsupported");
parser.advance();
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
parser.seek(position);
throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\"");
}
// Skip section for now and parse it later
skipSection(parser);
parser.skipWhiteSpace();
}
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parse()
{
auto &parser = m_context.parser;
std::cout << "Parsing domain " << m_name << std::endl; std::cout << "Parsing domain " << m_name << std::endl;
m_context.parser.expect<std::string>(")"); if (m_requirementsPosition != -1)
while (true)
{ {
m_context.parser.skipWhiteSpace(); parser.seek(m_requirementsPosition);
parseRequirementSection();
if (m_context.parser.probe(')'))
break;
parseSection();
} }
if (m_typesPosition != -1)
{
parser.seek(m_typesPosition);
parseTypeSection();
}
if (m_constantsPosition != -1)
{
parser.seek(m_constantsPosition);
parseConstantSection();
}
if (m_predicatesPosition != -1)
{
parser.seek(m_predicatesPosition);
parsePredicateSection();
}
for (size_t i = 0; i < m_actionPositions.size(); i++)
if (m_actionPositions[i] != -1)
{
parser.seek(m_actionPositions[i]);
parseActionSection();
}
computeDerivedRequirements(); computeDerivedRequirements();
} }
@ -81,14 +176,14 @@ const Requirements &Domain::requirements() const
expressions::PrimitiveTypes &Domain::types() expressions::PrimitiveTypes &Domain::types()
{ {
return m_primitiveTypes; return m_types;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const expressions::PrimitiveTypes &Domain::types() const const expressions::PrimitiveTypes &Domain::types() const
{ {
return m_primitiveTypes; return m_types;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -109,14 +204,14 @@ const expressions::Constants &Domain::constants() const
expressions::PredicateDeclarations &Domain::predicates() expressions::PredicateDeclarations &Domain::predicates()
{ {
return m_predicateDeclarations; return m_predicates;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
const expressions::PredicateDeclarations &Domain::predicates() const const expressions::PredicateDeclarations &Domain::predicates() const
{ {
return m_predicateDeclarations; return m_predicates;
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -135,52 +230,21 @@ const std::vector<std::unique_ptr<Action>> &Domain::actions() const
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection() void Domain::parseRequirementSection()
{ {
auto &parser = m_context.parser; auto &parser = m_context.parser;
parser.expect<std::string>("("); parser.expect<std::string>("(");
parser.expect<std::string>(":"); parser.expect<std::string>(":");
parser.expect<std::string>("requirements");
// TODO: check order of the sections while (parser.currentCharacter() != ')')
if (parser.probe<std::string>("requirements"))
parseRequirementSection();
else if (parser.probe<std::string>("types"))
parseTypeSection();
else if (parser.probe<std::string>("constants"))
parseConstantSection();
else if (parser.probe<std::string>("predicates"))
parsePredicateSection();
else if (parser.probe<std::string>("action"))
parseActionSection();
else if (parser.probe<std::string>("functions")
|| parser.probe<std::string>("constraints")
|| parser.probe<std::string>("durative-action")
|| parser.probe<std::string>("derived"))
{ {
std::cout << "Skipping section" << std::endl; parser.expect<std::string>(":");
skipSection(m_context.parser);
}
else
{
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
throw utils::ParserException(m_context.parser, "Unknown domain section \"" + sectionIdentifier + "\"");
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseRequirementSection()
{
m_context.parser.skipWhiteSpace();
while (m_context.parser.currentCharacter() != ')')
{
m_context.parser.expect<std::string>(":");
m_requirements.emplace_back(Requirement::parse(m_context)); m_requirements.emplace_back(Requirement::parse(m_context));
m_context.parser.skipWhiteSpace(); parser.skipWhiteSpace();
} }
// TODO: do this check only once the problem is parsed // TODO: do this check only once the problem is parsed
@ -188,7 +252,7 @@ void Domain::parseRequirementSection()
if (m_requirements.empty()) if (m_requirements.empty())
m_requirements.emplace_back(Requirement::Type::STRIPS); m_requirements.emplace_back(Requirement::Type::STRIPS);
m_context.parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -258,60 +322,82 @@ void Domain::computeDerivedRequirements()
void Domain::parseTypeSection() void Domain::parseTypeSection()
{ {
auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("types");
checkRequirement(Requirement::Type::Typing); checkRequirement(Requirement::Type::Typing);
m_context.parser.skipWhiteSpace(); parser.skipWhiteSpace();
// Store types and their parent types // Store types and their parent types
while (!m_context.parser.probe(')')) while (parser.currentCharacter() != ')')
{ {
if (m_context.parser.currentCharacter() == '(') if (parser.currentCharacter() == '(')
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section"); throw utils::ParserException(parser, "Only primitive types are allowed in type section");
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this); expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
m_context.parser.skipWhiteSpace(); parser.skipWhiteSpace();
} }
parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseConstantSection() void Domain::parseConstantSection()
{ {
m_context.parser.skipWhiteSpace(); auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("constants");
// Store constants // Store constants
expressions::Constant::parseTypedDeclarations(m_context, *this); expressions::Constant::parseTypedDeclarations(m_context, *this);
m_context.parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parsePredicateSection() void Domain::parsePredicateSection()
{ {
m_context.parser.skipWhiteSpace(); auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("predicates");
parser.skipWhiteSpace();
// Store predicates and their arguments // Store predicates and their arguments
while (m_context.parser.currentCharacter() != ')') while (parser.currentCharacter() != ')')
{ {
expressions::PredicateDeclaration::parse(m_context, *this); expressions::PredicateDeclaration::parse(m_context, *this);
m_context.parser.skipWhiteSpace(); parser.skipWhiteSpace();
} }
m_context.parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseActionSection() void Domain::parseActionSection()
{ {
m_context.parser.skipWhiteSpace(); auto &parser = m_context.parser;
parser.expect<std::string>("(");
parser.expect<std::string>(":");
parser.expect<std::string>("action");
Action::parseDeclaration(m_context, *this); Action::parseDeclaration(m_context, *this);
m_context.parser.expect<std::string>(")"); parser.expect<std::string>(")");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -4,6 +4,7 @@
#include <plasp/pddl/Domain.h> #include <plasp/pddl/Domain.h>
#include <plasp/pddl/ExpressionContext.h> #include <plasp/pddl/ExpressionContext.h>
#include <plasp/pddl/Identifier.h> #include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/And.h> #include <plasp/pddl/expressions/And.h>
#include <plasp/pddl/expressions/Imply.h> #include <plasp/pddl/expressions/Imply.h>
#include <plasp/pddl/expressions/Not.h> #include <plasp/pddl/expressions/Not.h>
@ -33,10 +34,10 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
[[noreturn]] void throwUnsupported(const utils::Parser &parser, inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
const std::string &expressionIdentifier)
{ {
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context"); context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
skipSection(context.parser);
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -58,7 +59,9 @@ ExpressionPointer parsePreconditionExpression(Context &context,
else if (expressionIdentifier == "forall" else if (expressionIdentifier == "forall"
|| expressionIdentifier == "preference") || expressionIdentifier == "preference")
{ {
throwUnsupported(context.parser, expressionIdentifier); warnUnsupported(context, expressionIdentifier);
return nullptr;
} }
else else
expression = parseExpressionContent(expressionIdentifier, context, expressionContext); expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
@ -116,7 +119,9 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
|| expressionIdentifier == ">=" || expressionIdentifier == ">="
|| expressionIdentifier == "<=") || expressionIdentifier == "<=")
{ {
throwUnsupported(context.parser, expressionIdentifier); warnUnsupported(context, expressionIdentifier);
return nullptr;
} }
auto &predicateDeclarations = expressionContext.domain.predicates(); auto &predicateDeclarations = expressionContext.domain.predicates();
@ -132,7 +137,7 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
if (match != predicateDeclarations.cend()) if (match != predicateDeclarations.cend())
return expressions::Predicate::parse(expressionIdentifier, context, expressionContext); return expressions::Predicate::parse(expressionIdentifier, context, expressionContext);
throw utils::ParserException(context.parser, "Expression \"" + expressionIdentifier + "\" not allowed in this context"); throw utils::ParserException(context.parser, "Unknown expression \"" + expressionIdentifier + "\"");
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
@ -150,7 +155,9 @@ ExpressionPointer parseEffectExpression(Context &context, ExpressionContext &exp
else if (expressionIdentifier == "forall" else if (expressionIdentifier == "forall"
|| expressionIdentifier == "when") || expressionIdentifier == "when")
{ {
throwUnsupported(context.parser, expressionIdentifier); warnUnsupported(context, expressionIdentifier);
return nullptr;
} }
else else
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext); expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
@ -177,7 +184,9 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
|| expressionIdentifier == "increase" || expressionIdentifier == "increase"
|| expressionIdentifier == "decrease") || expressionIdentifier == "decrease")
{ {
throwUnsupported(context.parser, expressionIdentifier); warnUnsupported(context, expressionIdentifier);
return nullptr;
} }
const auto &predicateDeclarations = expressionContext.domain.predicates(); const auto &predicateDeclarations = expressionContext.domain.predicates();

View File

@ -0,0 +1,63 @@
#include <plasp/pddl/InitialState.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/IO.h>
#include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/ParserException.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
inline void warnUnsupported(Context &context, const std::string &expressionIdentifier)
{
context.logger.parserWarning(context.parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
skipSection(context.parser);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
std::unique_ptr<InitialState> InitialState::parseDeclaration(Context &context, const Problem &problem)
{
auto initialState = std::make_unique<InitialState>(InitialState());
while (context.parser.currentCharacter() != ')')
{
context.parser.expect<std::string>("(");
ExpressionPointer expression;
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
if (expressionIdentifier == "at"
|| expressionIdentifier == "="
|| expressionIdentifier == "not")
{
warnUnsupported(context, expressionIdentifier);
continue;
}
// If none of the above types apply, the content is a predicate over constants and objects
initialState->m_facts.emplace_back(expressions::Predicate::parse(expressionIdentifier, context, problem));
context.parser.expect<std::string>(")");
context.parser.skipWhiteSpace();
}
return initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -29,7 +29,7 @@ Problem::Problem(Context &context, Domain &domain)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::readPDDL() void Problem::parse()
{ {
m_context.parser.expect<std::string>("("); m_context.parser.expect<std::string>("(");
m_context.parser.expect<std::string>("define"); m_context.parser.expect<std::string>("define");
@ -122,8 +122,9 @@ void Problem::parseSection()
parseRequirementSection(); parseRequirementSection();
else if (parser.probe<std::string>("objects")) else if (parser.probe<std::string>("objects"))
parseObjectSection(); parseObjectSection();
else if (parser.probe<std::string>("init") else if (parser.probe<std::string>("init"))
|| parser.probe<std::string>("goal") parseInitialStateSection();
else if (parser.probe<std::string>("goal")
|| parser.probe<std::string>("constraints") || parser.probe<std::string>("constraints")
|| parser.probe<std::string>("metric") || parser.probe<std::string>("metric")
|| parser.probe<std::string>("length")) || parser.probe<std::string>("length"))
@ -255,6 +256,33 @@ void Problem::parseObjectSection()
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::parseInitialStateSection()
{
m_initialState = InitialState::parseDeclaration(m_context, *this);
m_context.parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
InitialState &Problem::initialState()
{
BOOST_ASSERT(m_initialState);
return *m_initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
const InitialState &Problem::initialState() const
{
BOOST_ASSERT(m_initialState);
return *m_initialState;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Problem::checkConsistency() void Problem::checkConsistency()
{ {
} }

View File

@ -134,24 +134,37 @@ void Constant::parseTypedDeclarations(Context &context, Problem &problem)
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const ExpressionContext &expressionContext) Constant *Constant::parseAndFind(Context &context, const Domain &domain)
{ {
context.parser.skipWhiteSpace(); context.parser.skipWhiteSpace();
const auto constantName = context.parser.parseIdentifier(isIdentifier); const auto constantName = context.parser.parseIdentifier(isIdentifier);
auto *constant = parseAndFind(constantName, expressionContext.domain.constants()); auto *constant = parseAndFind(constantName, domain.constants());
if (constant != nullptr)
return constant;
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Constant *Constant::parseAndFind(Context &context, const Problem &problem)
{
context.parser.skipWhiteSpace();
const auto constantName = context.parser.parseIdentifier(isIdentifier);
auto *constant = parseAndFind(constantName, problem.domain().constants());
if (constant) if (constant)
return constant; return constant;
if (expressionContext.problem) constant = parseAndFind(constantName, problem.objects());
{
constant = parseAndFind(constantName, expressionContext.problem->objects());
if (constant) if (constant)
return constant; return constant;
}
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared"); throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
} }

View File

@ -1,54 +0,0 @@
#include <plasp/pddl/expressions/Type.h>
#include <plasp/pddl/Context.h>
#include <plasp/pddl/Identifier.h>
#include <plasp/pddl/expressions/Predicate.h>
#include <plasp/utils/IO.h>
#include <plasp/utils/ParserException.h>
namespace plasp
{
namespace pddl
{
namespace expressions
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// InitialState
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void throwUnsupported(const utils::Parser &parser, const std::string &expressionIdentifier)
{
throw utils::ParserException(parser, "Expression type \"" + expressionIdentifier + "\" currently unsupported in this context");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ExpressionPointer parseInitialState(Context &context)
{
context.parser.expect<std::string>("(");
const auto expressionIdentifier = context.parser.parseIdentifier(isIdentifier);
ExpressionPointer expression;
if (expressionIdentifier == "at"
|| expressionIdentifier == "=")
{
throwUnsupported(context.parser, expressionIdentifier);
}
// TODO: implement predicate parsing
context.parser.expect<std::string>(")");
return expression;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
}

View File

@ -51,7 +51,9 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
// Parse constants // Parse constants
else else
{ {
const auto *constant = Constant::parseAndFind(context, expressionContext); const auto *constant = (expressionContext.problem == nullptr)
? Constant::parseAndFind(context, expressionContext.domain)
: Constant::parseAndFind(context, *expressionContext.problem);
auto constantReference = std::make_unique<Reference<Constant>>(constant); auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference)); predicate->m_arguments.emplace_back(std::move(constantReference));
} }
@ -66,6 +68,32 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
PredicatePointer Predicate::parse(std::string name, Context &context, const Problem &problem)
{
auto predicate = std::make_unique<Predicate>(Predicate());
predicate->m_name = name;
context.parser.skipWhiteSpace();
while (context.parser.currentCharacter() != ')')
{
if (context.parser.currentCharacter() == '?')
throw utils::ParserException(context.parser, "Variables not allowed in this context");
// Parse objects and constants
const auto *constant = Constant::parseAndFind(context, problem);
auto constantReference = std::make_unique<Reference<Constant>>(constant);
predicate->m_arguments.emplace_back(std::move(constantReference));
}
// TODO: check that signature matches one of the declared ones
return predicate;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Predicate::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const void Predicate::accept(plasp::pddl::ExpressionVisitor &expressionVisitor) const
{ {
expressionVisitor.visit(*this); expressionVisitor.visit(*this);