Parsing domains in two passes and continued working on parsing the initial state.
This commit is contained in:
parent
ff7a6b8c8f
commit
8428c20bd4
@ -26,7 +26,8 @@ class Domain
|
||||
Domain(Context &context);
|
||||
|
||||
public:
|
||||
void readPDDL();
|
||||
void findSections();
|
||||
void parse();
|
||||
|
||||
void setName(std::string name);
|
||||
const std::string &name() const;
|
||||
@ -66,10 +67,20 @@ class Domain
|
||||
Context &m_context;
|
||||
|
||||
std::string m_name;
|
||||
|
||||
utils::Parser::Position m_requirementsPosition;
|
||||
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::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;
|
||||
};
|
||||
|
||||
|
@ -7,20 +7,27 @@ namespace plasp
|
||||
{
|
||||
namespace pddl
|
||||
{
|
||||
namespace expressions
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// InitialState
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class InitialState
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<InitialState> parseDeclaration(Context &context, const Problem &problem);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Type
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
public:
|
||||
const Expressions &facts() const;
|
||||
|
||||
ExpressionPointer parseInitialState(Context &context);
|
||||
private:
|
||||
Expressions m_facts;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <plasp/pddl/Context.h>
|
||||
#include <plasp/pddl/Expression.h>
|
||||
#include <plasp/pddl/InitialState.h>
|
||||
#include <plasp/pddl/Requirement.h>
|
||||
|
||||
namespace plasp
|
||||
@ -21,7 +22,7 @@ class Problem
|
||||
public:
|
||||
Problem(Context &context, Domain &domain);
|
||||
|
||||
void readPDDL();
|
||||
void parse();
|
||||
|
||||
bool isDeclared() const;
|
||||
|
||||
@ -37,6 +38,9 @@ class Problem
|
||||
expressions::Constants &objects();
|
||||
const expressions::Constants &objects() const;
|
||||
|
||||
InitialState &initialState();
|
||||
const InitialState &initialState() const;
|
||||
|
||||
void checkConsistency();
|
||||
|
||||
private:
|
||||
@ -49,6 +53,8 @@ class Problem
|
||||
|
||||
void parseObjectSection();
|
||||
|
||||
void parseInitialStateSection();
|
||||
|
||||
Context &m_context;
|
||||
Domain &m_domain;
|
||||
bool m_isDeclared;
|
||||
@ -57,6 +63,8 @@ class Problem
|
||||
Requirements m_requirements;
|
||||
|
||||
expressions::Constants m_objects;
|
||||
|
||||
std::unique_ptr<InitialState> m_initialState;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -27,7 +27,8 @@ class Constant: public Expression
|
||||
static void parseTypedDeclaration(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:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
@ -21,6 +21,7 @@ class Predicate: public Expression
|
||||
public:
|
||||
static PredicatePointer parse(std::string name, Context &context,
|
||||
ExpressionContext &expressionContext);
|
||||
static PredicatePointer parse(std::string name, Context &context, const Problem &problem);
|
||||
|
||||
public:
|
||||
void accept(ExpressionVisitor &expressionVisitor) const override;
|
||||
|
@ -106,12 +106,12 @@ void Description::parseContent()
|
||||
throw ConsistencyException("No PDDL domain specified");
|
||||
|
||||
m_context.parser.seek(m_domainPosition);
|
||||
m_domain->readPDDL();
|
||||
m_domain->parse();
|
||||
|
||||
if (m_problemPosition != -1)
|
||||
{
|
||||
m_context.parser.seek(m_problemPosition);
|
||||
m_problem->readPDDL();
|
||||
m_problem->parse();
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,41 +119,45 @@ void Description::parseContent()
|
||||
|
||||
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())
|
||||
return;
|
||||
parser.expect<std::string>("(");
|
||||
parser.expect<std::string>("define");
|
||||
parser.expect<std::string>("(");
|
||||
|
||||
const auto position = m_context.parser.position();
|
||||
|
||||
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 (parser.probe<std::string>("domain"))
|
||||
{
|
||||
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;
|
||||
|
||||
parser.seek(position);
|
||||
m_domain->findSections();
|
||||
}
|
||||
else if (m_context.parser.probe<std::string>("problem"))
|
||||
{
|
||||
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;
|
||||
|
||||
skipSection(parser);
|
||||
skipSection(parser);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto sectionIdentifier = m_context.parser.parse<std::string>();
|
||||
throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
|
||||
const auto sectionIdentifier = parser.parse<std::string>();
|
||||
throw utils::ParserException(parser, "Unknown PDDL section \"" + sectionIdentifier + "\"");
|
||||
}
|
||||
|
||||
skipSection(m_context.parser);
|
||||
skipSection(m_context.parser);
|
||||
m_context.parser.skipWhiteSpace();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <plasp/pddl/expressions/Variable.h>
|
||||
#include <plasp/utils/IO.h>
|
||||
#include <plasp/utils/ParserException.h>
|
||||
#include <plasp/utils/ParserWarning.h>
|
||||
|
||||
namespace plasp
|
||||
{
|
||||
@ -24,33 +25,127 @@ namespace pddl
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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>("(");
|
||||
m_context.parser.expect<std::string>("define");
|
||||
m_context.parser.expect<std::string>("(");
|
||||
m_context.parser.expect<std::string>("domain");
|
||||
auto &parser = m_context.parser;
|
||||
|
||||
parser.expect<std::string>("(");
|
||||
parser.expect<std::string>("define");
|
||||
parser.expect<std::string>("(");
|
||||
parser.expect<std::string>("domain");
|
||||
|
||||
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 §ionName, auto §ionPosition, 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;
|
||||
|
||||
m_context.parser.expect<std::string>(")");
|
||||
|
||||
while (true)
|
||||
if (m_requirementsPosition != -1)
|
||||
{
|
||||
m_context.parser.skipWhiteSpace();
|
||||
parser.seek(m_requirementsPosition);
|
||||
parseRequirementSection();
|
||||
}
|
||||
|
||||
if (m_context.parser.probe(')'))
|
||||
break;
|
||||
if (m_typesPosition != -1)
|
||||
{
|
||||
parser.seek(m_typesPosition);
|
||||
parseTypeSection();
|
||||
}
|
||||
|
||||
parseSection();
|
||||
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();
|
||||
@ -81,14 +176,14 @@ const Requirements &Domain::requirements() const
|
||||
|
||||
expressions::PrimitiveTypes &Domain::types()
|
||||
{
|
||||
return m_primitiveTypes;
|
||||
return m_types;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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()
|
||||
{
|
||||
return m_predicateDeclarations;
|
||||
return m_predicates;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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;
|
||||
|
||||
parser.expect<std::string>("(");
|
||||
parser.expect<std::string>(":");
|
||||
parser.expect<std::string>("requirements");
|
||||
|
||||
// TODO: check order of the sections
|
||||
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"))
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
std::cout << "Skipping section" << std::endl;
|
||||
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>(":");
|
||||
parser.expect<std::string>(":");
|
||||
|
||||
m_requirements.emplace_back(Requirement::parse(m_context));
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
// TODO: do this check only once the problem is parsed
|
||||
@ -188,7 +252,7 @@ void Domain::parseRequirementSection()
|
||||
if (m_requirements.empty())
|
||||
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()
|
||||
{
|
||||
auto &parser = m_context.parser;
|
||||
|
||||
parser.expect<std::string>("(");
|
||||
parser.expect<std::string>(":");
|
||||
parser.expect<std::string>("types");
|
||||
|
||||
checkRequirement(Requirement::Type::Typing);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
parser.skipWhiteSpace();
|
||||
|
||||
// Store types and their parent types
|
||||
while (!m_context.parser.probe(')'))
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
if (m_context.parser.currentCharacter() == '(')
|
||||
throw utils::ParserException(m_context.parser, "Only primitive types are allowed in type section");
|
||||
if (parser.currentCharacter() == '(')
|
||||
throw utils::ParserException(parser, "Only primitive types are allowed in type section");
|
||||
|
||||
expressions::PrimitiveType::parseTypedDeclaration(m_context, *this);
|
||||
|
||||
m_context.parser.skipWhiteSpace();
|
||||
parser.skipWhiteSpace();
|
||||
}
|
||||
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
expressions::Constant::parseTypedDeclarations(m_context, *this);
|
||||
|
||||
m_context.parser.expect<std::string>(")");
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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
|
||||
while (m_context.parser.currentCharacter() != ')')
|
||||
while (parser.currentCharacter() != ')')
|
||||
{
|
||||
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()
|
||||
{
|
||||
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);
|
||||
|
||||
m_context.parser.expect<std::string>(")");
|
||||
parser.expect<std::string>(")");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <plasp/pddl/Domain.h>
|
||||
#include <plasp/pddl/ExpressionContext.h>
|
||||
#include <plasp/pddl/Identifier.h>
|
||||
#include <plasp/pddl/IO.h>
|
||||
#include <plasp/pddl/expressions/And.h>
|
||||
#include <plasp/pddl/expressions/Imply.h>
|
||||
#include <plasp/pddl/expressions/Not.h>
|
||||
@ -33,10 +34,10 @@ ExpressionPointer parsePredicate(Context &context, ExpressionContext &expression
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
[[noreturn]] void throwUnsupported(const utils::Parser &parser,
|
||||
const std::string &expressionIdentifier)
|
||||
inline void warnUnsupported(Context &context, 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"
|
||||
|| expressionIdentifier == "preference")
|
||||
{
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
warnUnsupported(context, expressionIdentifier);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
expression = parseExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
@ -116,7 +119,9 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
|
||||
|| expressionIdentifier == ">="
|
||||
|| expressionIdentifier == "<=")
|
||||
{
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
warnUnsupported(context, expressionIdentifier);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
@ -132,7 +137,7 @@ ExpressionPointer parseExpressionContent(const std::string &expressionIdentifier
|
||||
if (match != predicateDeclarations.cend())
|
||||
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"
|
||||
|| expressionIdentifier == "when")
|
||||
{
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
warnUnsupported(context, expressionIdentifier);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
expression = parseEffectBodyExpressionContent(expressionIdentifier, context, expressionContext);
|
||||
@ -177,7 +184,9 @@ ExpressionPointer parseEffectBodyExpressionContent(const std::string &expression
|
||||
|| expressionIdentifier == "increase"
|
||||
|| expressionIdentifier == "decrease")
|
||||
{
|
||||
throwUnsupported(context.parser, expressionIdentifier);
|
||||
warnUnsupported(context, expressionIdentifier);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto &predicateDeclarations = expressionContext.domain.predicates();
|
||||
|
63
src/plasp/pddl/InitialState.cpp
Normal file
63
src/plasp/pddl/InitialState.cpp
Normal 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
@ -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>("define");
|
||||
@ -122,8 +122,9 @@ void Problem::parseSection()
|
||||
parseRequirementSection();
|
||||
else if (parser.probe<std::string>("objects"))
|
||||
parseObjectSection();
|
||||
else if (parser.probe<std::string>("init")
|
||||
|| parser.probe<std::string>("goal")
|
||||
else if (parser.probe<std::string>("init"))
|
||||
parseInitialStateSection();
|
||||
else if (parser.probe<std::string>("goal")
|
||||
|| parser.probe<std::string>("constraints")
|
||||
|| parser.probe<std::string>("metric")
|
||||
|| 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()
|
||||
{
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
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)
|
||||
return constant;
|
||||
|
||||
if (expressionContext.problem)
|
||||
{
|
||||
constant = parseAndFind(constantName, expressionContext.problem->objects());
|
||||
constant = parseAndFind(constantName, problem.objects());
|
||||
|
||||
if (constant)
|
||||
return constant;
|
||||
}
|
||||
|
||||
throw utils::ParserException(context.parser, "Constant \"" + constantName + "\" used but never declared");
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -51,7 +51,9 @@ PredicatePointer Predicate::parse(std::string name, Context &context,
|
||||
// Parse constants
|
||||
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);
|
||||
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
|
||||
{
|
||||
expressionVisitor.visit(*this);
|
||||
|
Reference in New Issue
Block a user