Started implementing PDDL domain parser.

This commit is contained in:
Patrick Lühne 2016-05-29 16:27:11 +02:00
parent 42fda5925d
commit 40547691a0
9 changed files with 347 additions and 12 deletions

View File

@ -1,7 +1,10 @@
#include <algorithm>
#include <iostream>
#include <string>
#include <boost/program_options.hpp>
#include <plasp/pddl/Description.h>
#include <plasp/sas/Description.h>
#include <plasp/sas/TranslatorASP.h>
@ -13,7 +16,8 @@ int main(int argc, char **argv)
description.add_options()
("help,h", "Display this help message.")
("version,v", "Display version information.")
("input,i", po::value<std::string>(), "Specify the SAS input file.");
("input,i", po::value<std::string>(), "Specify the SAS input file.")
("format,f", po::value<std::string>()->default_value("SAS"), "Specify the file format (SAS or PDDL).");
po::positional_options_description positionalOptionsDescription;
positionalOptionsDescription.add("input", -1);
@ -58,6 +62,11 @@ int main(int argc, char **argv)
}
try
{
auto format = variablesMap["format"].as<std::string>();
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
if (format == "sas")
{
const auto sasDescription = variablesMap.count("input")
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
@ -65,6 +74,14 @@ int main(int argc, char **argv)
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
sasTranslator.translate(std::cout);
}
else if (format == "pddl")
{
const auto pddlDescription = variablesMap.count("input")
? plasp::pddl::Description::fromFile(variablesMap["input"].as<std::string>())
: plasp::pddl::Description::fromStream(std::cin);
//std::cout << pddlDescription << std::endl;
}
}
catch (const std::exception &e)
{
std::cerr << "Error: " << e.what() << std::endl << std::endl;

View File

@ -0,0 +1,43 @@
#ifndef __PLASP__PDDL__DESCRIPTION_H
#define __PLASP__PDDL__DESCRIPTION_H
#include <boost/filesystem/path.hpp>
#include <plasp/pddl/Domain.h>
#include <plasp/utils/Parser.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Description
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Description
{
public:
static Description fromStream(std::istream &istream);
static Description fromFile(const boost::filesystem::path &path);
public:
private:
Description() = default;
void parseContent(utils::Parser &parser);
void parseSection(utils::Parser &parser);
std::unique_ptr<Domain> m_domain;
//std::unique_ptr<Problem> m_problem;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,35 @@
#ifndef __PLASP__PDDL__DOMAIN_H
#define __PLASP__PDDL__DOMAIN_H
#include <plasp/utils/Parser.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Domain
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Domain
{
public:
static Domain fromPDDL(utils::Parser &parser);
private:
Domain() = default;
void parseSection(utils::Parser &parser);
std::string m_name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -0,0 +1,32 @@
#ifndef __PLASP__PDDL__IDENTIFIER_H
#define __PLASP__PDDL__IDENTIFIER_H
#include <cctype>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Identifier
//
////////////////////////////////////////////////////////////////////////////////////////////////////
const auto isIdentifier =
[](const auto character)
{
return character != '?'
&& character != '('
&& character != ')'
&& character != ';'
&& std::isgraph(character);
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -28,12 +28,17 @@ class Parser
size_t column() const;
CharacterType currentCharacter() const;
void advance();
bool atEndOfFile() const;
template<typename Type>
Type parse();
template<class WhiteSpacePredicate, class CharacterPredicate>
std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate);
template<class CharacterPredicate, class WhiteSpacePredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
template<class CharacterPredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate);
template<typename Type>
void expect(const Type &expectedValue);
@ -51,7 +56,6 @@ class Parser
private:
void checkStream() const;
void advance();
bool advanceIf(CharacterType expectedCharacter);
@ -68,8 +72,8 @@ class Parser
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class WhiteSpacePredicate, class CharacterPredicate>
std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate)
template<class CharacterPredicate, class WhiteSpacePredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
{
skipWhiteSpace(whiteSpacePredicate);
@ -89,12 +93,24 @@ std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, Cha
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate)
{
return parseIdentifier(characterPredicate,
[&](const auto character)
{
return std::isspace(character);
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class WhiteSpacePredicate>
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
{
checkStream();
while (whiteSpacePredicate(*m_position))
while (m_position != EndOfFile && whiteSpacePredicate(*m_position))
advance();
}

View File

@ -3,6 +3,9 @@ set(target plasp)
file(GLOB core_sources "plasp/*.cpp")
file(GLOB core_headers "../include/plasp/*.h")
file(GLOB pddl_sources "plasp/pddl/*.cpp")
file(GLOB pddl_headers "../include/plasp/pddl/*.h")
file(GLOB sas_sources "plasp/sas/*.cpp")
file(GLOB sas_headers "../include/plasp/sas/*.h")
@ -21,6 +24,9 @@ set(sources
${core_sources}
${core_headers}
${pddl_sources}
${pddl_headers}
${sas_sources}
${sas_headers}

View File

@ -0,0 +1,87 @@
#include <plasp/pddl/Description.h>
#include <fstream>
#include <sstream>
#include <boost/filesystem.hpp>
#include <plasp/utils/ParserException.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Description
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Description Description::fromStream(std::istream &istream)
{
Description description;
utils::Parser parser(istream);
while (true)
{
parser.skipWhiteSpace();
if (parser.atEndOfFile())
break;
description.parseContent(parser);
}
return description;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Description Description::fromFile(const boost::filesystem::path &path)
{
if (!boost::filesystem::is_regular_file(path))
throw std::runtime_error("File does not exist: \"" + path.string() + "\"");
std::ifstream fileStream(path.string(), std::ios::in);
return Description::fromStream(fileStream);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::parseContent(utils::Parser &parser)
{
std::cout << "Parsing file content" << std::endl;
parser.expect<std::string>("(define");
parseSection(parser);
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Description::parseSection(utils::Parser &parser)
{
// Parse domain/problem identifier
parser.expect<std::string>("(");
const auto sectionIdentifier = parser.parse<std::string>();
std::cout << "Parsing section " << sectionIdentifier << std::endl;
if (sectionIdentifier == "domain")
m_domain = std::make_unique<Domain>(Domain::fromPDDL(parser));
//else if (sectionIdentifier == "problem")
// m_problem = std::make_unique<Problem>(Problem::fromPDDL(parser));
else
throw utils::ParserException(parser.row(), parser.column(), "Unknown PDDL section \"" + sectionIdentifier + "\"");
parser.expect<std::string>(")");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

92
src/plasp/pddl/Domain.cpp Normal file
View File

@ -0,0 +1,92 @@
#include <plasp/pddl/Domain.h>
#include <plasp/pddl/Identifier.h>
namespace plasp
{
namespace pddl
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Domain
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Domain Domain::fromPDDL(utils::Parser &parser)
{
Domain domain;
domain.m_name = parser.parseIdentifier(isIdentifier);
std::cout << "Parsing domain " << domain.m_name << std::endl;
parser.expect<std::string>(")");
while (true)
{
parser.skipWhiteSpace();
std::cout << parser.currentCharacter() << std::endl;
if (parser.currentCharacter() == ')')
break;
domain.parseSection(parser);
}
return domain;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Domain::parseSection(utils::Parser &parser)
{
parser.expect<std::string>("(:");
const auto sectionIdentifier = parser.parseIdentifier(isIdentifier);
const auto skipSection =
[&]()
{
std::cout << "Skipping section " << sectionIdentifier << std::endl;
size_t openParentheses = 1;
while (true)
{
const auto character = parser.currentCharacter();
parser.advance();
if (character == '(')
openParentheses++;
else if (character == ')')
{
openParentheses--;
if (openParentheses == 0)
return;
}
}
};
if (sectionIdentifier == "requirements")
skipSection();
else if (sectionIdentifier == "types")
skipSection();
else if (sectionIdentifier == "constants")
skipSection();
else if (sectionIdentifier == "predicates")
skipSection();
else if (sectionIdentifier == "functions")
skipSection();
else if (sectionIdentifier == "constraints")
skipSection();
else if (sectionIdentifier == "action")
skipSection();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}

View File

@ -63,6 +63,13 @@ Parser::CharacterType Parser::currentCharacter() const
////////////////////////////////////////////////////////////////////////////////////////////////////
bool Parser::atEndOfFile() const
{
return m_position == EndOfFile;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Parser::checkStream() const
{
if (m_position == EndOfFile)