From 31fb8ba79bd41ce97ef4de3ad4724c49c09b8c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Wed, 8 Jun 2016 00:34:59 +0200 Subject: [PATCH] Started parsing in a two-pass approach. --- include/plasp/pddl/Description.h | 4 +- src/plasp/pddl/Description.cpp | 93 +++++++++++++++++--------------- src/plasp/pddl/Domain.cpp | 7 ++- 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/include/plasp/pddl/Description.h b/include/plasp/pddl/Description.h index bc2d279..8712d8e 100644 --- a/include/plasp/pddl/Description.h +++ b/include/plasp/pddl/Description.h @@ -31,14 +31,16 @@ class Description Description(); void parseContent(); - void parseSection(); + void findSections(); void checkConsistency(); utils::Parser m_parser; Context m_context; + utils::Parser::Position m_domainPosition; std::unique_ptr m_domain; + utils::Parser::Position m_problemPosition; std::unique_ptr m_problem; }; diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index f1d2779..02a8ae7 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -5,6 +5,7 @@ #include +#include #include namespace plasp @@ -20,7 +21,9 @@ namespace pddl Description::Description() : m_context(m_parser), + m_domainPosition{-1}, m_domain{std::make_unique(Domain(m_context))}, + m_problemPosition{-1}, m_problem{std::make_unique(Problem(m_context, *m_domain))} { m_parser.setCaseSensitive(false); @@ -72,6 +75,26 @@ const Domain &Description::domain() const //////////////////////////////////////////////////////////////////////////////////////////////////// void Description::parseContent() +{ + // First, determine the locations of domain and problem + findSections(); + + if (m_domainPosition == -1) + throw ConsistencyException("No PDDL domain specified"); + + m_context.parser.seek(m_domainPosition); + m_domain->readPDDL(); + + if (m_problemPosition != -1) + { + m_context.parser.seek(m_problemPosition); + m_problem->readPDDL(); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Description::findSections() { while (true) { @@ -80,57 +103,43 @@ void Description::parseContent() if (m_context.parser.atEndOfStream()) return; + const auto position = m_context.parser.position(); + m_context.parser.expect("("); m_context.parser.expect("define"); - parseSection(); - m_context.parser.expect(")"); + m_context.parser.expect("("); + + if (m_context.parser.probe("domain")) + { + std::cout << "Found domain at " << position << std::endl; + + if (m_domainPosition != -1) + throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); + + m_domainPosition = position; + } + else if (m_context.parser.probe("problem")) + { + if (m_problemPosition != -1) + throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems"); + + m_problemPosition = position; + } + else + { + const auto sectionIdentifier = m_context.parser.parse(); + throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); + } + + skipSection(m_context.parser); + skipSection(m_context.parser); } } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseSection() -{ - // Parse domain/problem identifier - m_context.parser.expect("("); - - const auto sectionIdentifier = m_context.parser.parse(); - - if (sectionIdentifier == "domain") - { - BOOST_ASSERT(m_domain); - - if (m_domain->isDeclared()) - throw utils::ParserException(m_context.parser, "PDDL description may not contain two domains"); - - m_domain->readPDDL(); - } - else if (sectionIdentifier == "problem") - { - BOOST_ASSERT(m_problem); - - if (m_problem->isDeclared()) - throw utils::ParserException(m_context.parser, "PDDL description may currently not contain two problems"); - - m_problem->readPDDL(); - } - else - throw utils::ParserException(m_context.parser, "Unknown PDDL section \"" + sectionIdentifier + "\""); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - void Description::checkConsistency() { - if (!m_domain->isDeclared()) - throw ConsistencyException("No PDDL domain specified"); - - if (m_problem->hasRequirement(Requirement::Type::Typing) - && !m_domain->hasRequirement(Requirement::Type::Typing)) - { - throw ConsistencyException("PDDL problems may not add the \"typing\" requirement"); - } - m_domain->checkConsistency(); m_problem->checkConsistency(); } diff --git a/src/plasp/pddl/Domain.cpp b/src/plasp/pddl/Domain.cpp index 5296870..6f8f764 100644 --- a/src/plasp/pddl/Domain.cpp +++ b/src/plasp/pddl/Domain.cpp @@ -33,6 +33,11 @@ Domain::Domain(Context &context) void Domain::readPDDL() { + m_context.parser.expect("("); + m_context.parser.expect("define"); + m_context.parser.expect("("); + m_context.parser.expect("domain"); + const auto domainName = m_context.parser.parseIdentifier(isIdentifier); if (m_name.empty()) @@ -49,7 +54,7 @@ void Domain::readPDDL() { m_context.parser.skipWhiteSpace(); - if (m_context.parser.currentCharacter() == ')') + if (m_context.parser.probe(')')) break; parseSection();