Implemented two-pass parsing for PDDL problems.
This commit is contained in:
parent
fb15a131ac
commit
87889f5efe
@ -61,8 +61,6 @@ int main(int argc, char **argv)
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto format = variablesMap["format"].as<std::string>();
|
auto format = variablesMap["format"].as<std::string>();
|
||||||
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
||||||
|
|
||||||
@ -102,13 +100,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
//std::cout << pddlDescription << std::endl;
|
//std::cout << pddlDescription << std::endl;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
std::cerr << "Error: " << e.what() << std::endl << std::endl;
|
|
||||||
printHelp();
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,9 @@ class Problem
|
|||||||
public:
|
public:
|
||||||
Problem(Context &context, Domain &domain);
|
Problem(Context &context, Domain &domain);
|
||||||
|
|
||||||
|
void findSections();
|
||||||
void parse();
|
void parse();
|
||||||
|
|
||||||
bool isDeclared() const;
|
|
||||||
|
|
||||||
Domain &domain();
|
Domain &domain();
|
||||||
const Domain &domain() const;
|
const Domain &domain() const;
|
||||||
|
|
||||||
@ -44,8 +43,6 @@ class Problem
|
|||||||
void checkConsistency();
|
void checkConsistency();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseSection();
|
|
||||||
|
|
||||||
void parseRequirementSection();
|
void parseRequirementSection();
|
||||||
void computeDerivedRequirements();
|
void computeDerivedRequirements();
|
||||||
|
|
||||||
@ -57,13 +54,18 @@ class Problem
|
|||||||
|
|
||||||
Context &m_context;
|
Context &m_context;
|
||||||
Domain &m_domain;
|
Domain &m_domain;
|
||||||
bool m_isDeclared;
|
|
||||||
|
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
|
||||||
|
utils::Parser::Position m_domainPosition;
|
||||||
|
|
||||||
|
utils::Parser::Position m_requirementsPosition;
|
||||||
Requirements m_requirements;
|
Requirements m_requirements;
|
||||||
|
|
||||||
|
utils::Parser::Position m_objectsPosition;
|
||||||
expressions::Constants m_objects;
|
expressions::Constants m_objects;
|
||||||
|
|
||||||
|
utils::Parser::Position m_initialStatePosition;
|
||||||
std::unique_ptr<InitialState> m_initialState;
|
std::unique_ptr<InitialState> m_initialState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -148,8 +148,8 @@ void Description::findSections()
|
|||||||
|
|
||||||
m_problemPosition = position;
|
m_problemPosition = position;
|
||||||
|
|
||||||
skipSection(parser);
|
parser.seek(position);
|
||||||
skipSection(parser);
|
m_problem->findSections();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -69,6 +69,8 @@ void Domain::findSections()
|
|||||||
parser.expect<std::string>("(");
|
parser.expect<std::string>("(");
|
||||||
parser.expect<std::string>(":");
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
// Save the parser position of the individual sections for later parsing
|
// Save the parser position of the individual sections for later parsing
|
||||||
if (parser.probe<std::string>("requirements"))
|
if (parser.probe<std::string>("requirements"))
|
||||||
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
@ -88,9 +90,13 @@ void Domain::findSections()
|
|||||||
|| parser.probe<std::string>("durative-action")
|
|| parser.probe<std::string>("durative-action")
|
||||||
|| parser.probe<std::string>("derived"))
|
|| parser.probe<std::string>("derived"))
|
||||||
{
|
{
|
||||||
parser.seek(position);
|
parser.seek(sectionIdentifierPosition);
|
||||||
m_context.logger.parserWarning(parser, "Section type currently unsupported");
|
|
||||||
parser.advance();
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -23,45 +23,118 @@ namespace pddl
|
|||||||
Problem::Problem(Context &context, Domain &domain)
|
Problem::Problem(Context &context, Domain &domain)
|
||||||
: m_context(context),
|
: m_context(context),
|
||||||
m_domain(domain),
|
m_domain(domain),
|
||||||
m_isDeclared{false}
|
m_domainPosition{-1},
|
||||||
|
m_requirementsPosition{-1},
|
||||||
|
m_objectsPosition{-1},
|
||||||
|
m_initialStatePosition{-1}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void Problem::findSections()
|
||||||
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("define");
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>("problem");
|
||||||
|
|
||||||
|
m_name = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
std::cout << "Found problem " << 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();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
|
{
|
||||||
|
const auto position = parser.position();
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
|
||||||
|
const auto sectionIdentifierPosition = parser.position();
|
||||||
|
|
||||||
|
// TODO: check order of the sections
|
||||||
|
if (parser.probe<std::string>("domain"))
|
||||||
|
setSectionPosition("domain", m_domainPosition, position, true);
|
||||||
|
else if (parser.probe<std::string>("requirements"))
|
||||||
|
setSectionPosition("requirements", m_requirementsPosition, position, true);
|
||||||
|
else if (parser.probe<std::string>("objects"))
|
||||||
|
setSectionPosition("objects", m_objectsPosition, position, true);
|
||||||
|
else if (parser.probe<std::string>("init"))
|
||||||
|
setSectionPosition("init", m_initialStatePosition, position, true);
|
||||||
|
else if (parser.probe<std::string>("goal")
|
||||||
|
|| parser.probe<std::string>("constraints")
|
||||||
|
|| parser.probe<std::string>("metric")
|
||||||
|
|| parser.probe<std::string>("length"))
|
||||||
|
{
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
m_context.logger.parserWarning(parser, "Section type \"" + sectionIdentifier + "\" currently unsupported");
|
||||||
|
|
||||||
|
parser.seek(sectionIdentifierPosition);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
|
parser.seek(position);
|
||||||
|
throw utils::ParserException(m_context.parser, "Unknown problem section \"" + sectionIdentifier + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip section for now and parse it later
|
||||||
|
skipSection(parser);
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.expect<std::string>(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Problem::parse()
|
void Problem::parse()
|
||||||
{
|
{
|
||||||
m_context.parser.expect<std::string>("(");
|
auto &parser = m_context.parser;
|
||||||
m_context.parser.expect<std::string>("define");
|
|
||||||
m_context.parser.expect<std::string>("(");
|
|
||||||
m_context.parser.expect<std::string>("problem");
|
|
||||||
|
|
||||||
m_name = m_context.parser.parseIdentifier(isIdentifier);
|
if (m_domainPosition == -1)
|
||||||
|
throw ConsistencyException("Problem description does not specify the corresponding domain");
|
||||||
|
|
||||||
std::cout << "Parsing problem " << m_name << std::endl;
|
parser.seek(m_domainPosition);
|
||||||
|
parseDomainSection();
|
||||||
|
|
||||||
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.currentCharacter() == ')')
|
|
||||||
break;
|
|
||||||
|
|
||||||
parseSection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
computeDerivedRequirements();
|
if (m_objectsPosition != -1)
|
||||||
|
{
|
||||||
m_isDeclared = true;
|
parser.seek(m_objectsPosition);
|
||||||
|
parseObjectSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
if (m_initialStatePosition == -1)
|
||||||
|
throw ConsistencyException("Problem description does not specify an initial state");
|
||||||
|
|
||||||
bool Problem::isDeclared() const
|
parser.seek(m_initialStatePosition);
|
||||||
{
|
parseInitialStateSection();
|
||||||
return m_isDeclared;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -108,64 +181,43 @@ const expressions::Constants &Problem::objects() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Problem::parseSection()
|
void Problem::parseDomainSection()
|
||||||
{
|
{
|
||||||
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>("domain");
|
||||||
|
|
||||||
// TODO: check order of the sections
|
parser.skipWhiteSpace();
|
||||||
if (parser.probe<std::string>("domain"))
|
|
||||||
parseDomainSection();
|
|
||||||
else if (parser.probe<std::string>("requirements"))
|
|
||||||
parseRequirementSection();
|
|
||||||
else if (parser.probe<std::string>("objects"))
|
|
||||||
parseObjectSection();
|
|
||||||
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"))
|
|
||||||
{
|
|
||||||
std::cout << "Skipping section" << std::endl;
|
|
||||||
skipSection(m_context.parser);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
|
|
||||||
throw utils::ParserException(m_context.parser, "Unknown problem section \"" + sectionIdentifier + "\"");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
const auto domainName = parser.parseIdentifier(isIdentifier);
|
||||||
|
|
||||||
void Problem::parseDomainSection()
|
|
||||||
{
|
|
||||||
m_context.parser.skipWhiteSpace();
|
|
||||||
|
|
||||||
const auto domainName = m_context.parser.parseIdentifier(isIdentifier);
|
|
||||||
|
|
||||||
if (m_domain.name() != domainName)
|
if (m_domain.name() != domainName)
|
||||||
throw utils::ParserException(m_context.parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")");
|
throw utils::ParserException(parser, "Domains do not match (\"" + m_domain.name() + "\" and \"" + domainName + "\")");
|
||||||
|
|
||||||
m_context.parser.expect<std::string>(")");
|
parser.expect<std::string>(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Problem::parseRequirementSection()
|
void Problem::parseRequirementSection()
|
||||||
{
|
{
|
||||||
m_context.parser.skipWhiteSpace();
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
while (m_context.parser.currentCharacter() != ')')
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("requirements");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
|
while (parser.currentCharacter() != ')')
|
||||||
{
|
{
|
||||||
m_context.parser.expect<std::string>(":");
|
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 domain is parsed
|
// TODO: do this check only once the domain is parsed
|
||||||
@ -173,7 +225,7 @@ void Problem::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>(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -246,21 +298,33 @@ void Problem::computeDerivedRequirements()
|
|||||||
|
|
||||||
void Problem::parseObjectSection()
|
void Problem::parseObjectSection()
|
||||||
{
|
{
|
||||||
m_context.parser.skipWhiteSpace();
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("objects");
|
||||||
|
|
||||||
|
parser.skipWhiteSpace();
|
||||||
|
|
||||||
// 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 Problem::parseInitialStateSection()
|
void Problem::parseInitialStateSection()
|
||||||
{
|
{
|
||||||
|
auto &parser = m_context.parser;
|
||||||
|
|
||||||
|
parser.expect<std::string>("(");
|
||||||
|
parser.expect<std::string>(":");
|
||||||
|
parser.expect<std::string>("init");
|
||||||
|
|
||||||
m_initialState = InitialState::parseDeclaration(m_context, *this);
|
m_initialState = InitialState::parseDeclaration(m_context, *this);
|
||||||
|
|
||||||
m_context.parser.expect<std::string>(")");
|
parser.expect<std::string>(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Reference in New Issue
Block a user