patrick
/
plasp
Archived
1
0
Fork 0
This repository has been archived on 2023-07-19. You can view files and clone it, but cannot push or open issues or pull requests.
plasp/lib/pddlparse/src/pddlparse/detail/parsing/Description.cpp

108 lines
2.8 KiB
C++

#include <pddlparse/detail/parsing/Description.h>
#include <pddlparse/AST.h>
#include <pddlparse/ParserException.h>
#include <pddlparse/detail/parsing/Domain.h>
#include <pddlparse/detail/parsing/Problem.h>
#include <pddlparse/detail/parsing/Utils.h>
namespace pddl
{
namespace detail
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Description
//
////////////////////////////////////////////////////////////////////////////////////////////////////
DescriptionParser::DescriptionParser(Context &context)
: m_context{context},
m_domainPosition{-1},
m_problemPosition{-1}
{
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ast::Description DescriptionParser::parse()
{
auto &tokenizer = m_context.tokenizer;
tokenizer.removeComments(";", "\n", false);
findSections();
if (m_domainPosition == -1)
throw ParserException("no PDDL domain specified");
tokenizer.seek(m_domainPosition);
auto domain = DomainParser(m_context).parse();
// If no problem is given, return just the domain
if (m_problemPosition == -1)
return {std::move(domain), std::experimental::nullopt};
tokenizer.seek(m_problemPosition);
auto problem = ProblemParser(m_context, *domain).parse();
// TODO: check consistency
// * check typing requirement
// * check that typing is used consistently
// * check that constants, variables, and predicates aren't declared twice
// * check section order
// * check that preconditions and effects are well-formed
return {std::move(domain), std::move(problem)};
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void DescriptionParser::findSections()
{
auto &tokenizer = m_context.tokenizer;
tokenizer.skipWhiteSpace();
while (!tokenizer.atEnd())
{
const auto position = tokenizer.position();
tokenizer.expect<std::string>("(");
tokenizer.expect<std::string>("define");
tokenizer.expect<std::string>("(");
if (tokenizer.testAndSkip<std::string>("domain"))
{
if (m_domainPosition != -1)
throw ParserException(tokenizer.location(), "PDDL description may not contain two domains");
m_domainPosition = position;
skipSection(tokenizer);
skipSection(tokenizer);
}
else if (m_context.tokenizer.testAndSkip<std::string>("problem"))
{
if (m_problemPosition != -1)
throw ParserException("PDDL description may not contain two problems currently");
m_problemPosition = position;
skipSection(tokenizer);
skipSection(tokenizer);
}
else
{
const auto sectionIdentifier = tokenizer.get<std::string>();
throw ParserException(tokenizer.location(), "unknown PDDL section “" + sectionIdentifier + "");
}
tokenizer.skipWhiteSpace();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}