Started implementing PDDL domain parser.
This commit is contained in:
parent
42fda5925d
commit
40547691a0
@ -1,7 +1,10 @@
|
|||||||
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
|
||||||
|
#include <plasp/pddl/Description.h>
|
||||||
#include <plasp/sas/Description.h>
|
#include <plasp/sas/Description.h>
|
||||||
#include <plasp/sas/TranslatorASP.h>
|
#include <plasp/sas/TranslatorASP.h>
|
||||||
|
|
||||||
@ -13,7 +16,8 @@ int main(int argc, char **argv)
|
|||||||
description.add_options()
|
description.add_options()
|
||||||
("help,h", "Display this help message.")
|
("help,h", "Display this help message.")
|
||||||
("version,v", "Display version information.")
|
("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;
|
po::positional_options_description positionalOptionsDescription;
|
||||||
positionalOptionsDescription.add("input", -1);
|
positionalOptionsDescription.add("input", -1);
|
||||||
@ -59,11 +63,24 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto sasDescription = variablesMap.count("input")
|
auto format = variablesMap["format"].as<std::string>();
|
||||||
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
|
std::transform(format.begin(), format.end(), format.begin(), ::tolower);
|
||||||
: plasp::sas::Description::fromStream(std::cin);
|
|
||||||
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
|
if (format == "sas")
|
||||||
sasTranslator.translate(std::cout);
|
{
|
||||||
|
const auto sasDescription = variablesMap.count("input")
|
||||||
|
? plasp::sas::Description::fromFile(variablesMap["input"].as<std::string>())
|
||||||
|
: plasp::sas::Description::fromStream(std::cin);
|
||||||
|
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)
|
catch (const std::exception &e)
|
||||||
{
|
{
|
||||||
|
43
include/plasp/pddl/Description.h
Normal file
43
include/plasp/pddl/Description.h
Normal 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
|
35
include/plasp/pddl/Domain.h
Normal file
35
include/plasp/pddl/Domain.h
Normal 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
|
32
include/plasp/pddl/Identifier.h
Normal file
32
include/plasp/pddl/Identifier.h
Normal 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
|
@ -28,12 +28,17 @@ class Parser
|
|||||||
size_t column() const;
|
size_t column() const;
|
||||||
|
|
||||||
CharacterType currentCharacter() const;
|
CharacterType currentCharacter() const;
|
||||||
|
void advance();
|
||||||
|
bool atEndOfFile() const;
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
Type parse();
|
Type parse();
|
||||||
|
|
||||||
template<class WhiteSpacePredicate, class CharacterPredicate>
|
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||||
std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate);
|
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
|
||||||
|
|
||||||
|
template<class CharacterPredicate>
|
||||||
|
std::string parseIdentifier(CharacterPredicate characterPredicate);
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
void expect(const Type &expectedValue);
|
void expect(const Type &expectedValue);
|
||||||
@ -51,7 +56,6 @@ class Parser
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void checkStream() const;
|
void checkStream() const;
|
||||||
void advance();
|
|
||||||
|
|
||||||
bool advanceIf(CharacterType expectedCharacter);
|
bool advanceIf(CharacterType expectedCharacter);
|
||||||
|
|
||||||
@ -68,8 +72,8 @@ class Parser
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
template<class WhiteSpacePredicate, class CharacterPredicate>
|
template<class CharacterPredicate, class WhiteSpacePredicate>
|
||||||
std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate)
|
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
|
||||||
{
|
{
|
||||||
skipWhiteSpace(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>
|
template<class WhiteSpacePredicate>
|
||||||
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
|
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
|
||||||
{
|
{
|
||||||
checkStream();
|
checkStream();
|
||||||
|
|
||||||
while (whiteSpacePredicate(*m_position))
|
while (m_position != EndOfFile && whiteSpacePredicate(*m_position))
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ set(target plasp)
|
|||||||
file(GLOB core_sources "plasp/*.cpp")
|
file(GLOB core_sources "plasp/*.cpp")
|
||||||
file(GLOB core_headers "../include/plasp/*.h")
|
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_sources "plasp/sas/*.cpp")
|
||||||
file(GLOB sas_headers "../include/plasp/sas/*.h")
|
file(GLOB sas_headers "../include/plasp/sas/*.h")
|
||||||
|
|
||||||
@ -21,6 +24,9 @@ set(sources
|
|||||||
${core_sources}
|
${core_sources}
|
||||||
${core_headers}
|
${core_headers}
|
||||||
|
|
||||||
|
${pddl_sources}
|
||||||
|
${pddl_headers}
|
||||||
|
|
||||||
${sas_sources}
|
${sas_sources}
|
||||||
${sas_headers}
|
${sas_headers}
|
||||||
|
|
||||||
|
87
src/plasp/pddl/Description.cpp
Normal file
87
src/plasp/pddl/Description.cpp
Normal 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
92
src/plasp/pddl/Domain.cpp
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -63,6 +63,13 @@ Parser::CharacterType Parser::currentCharacter() const
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool Parser::atEndOfFile() const
|
||||||
|
{
|
||||||
|
return m_position == EndOfFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void Parser::checkStream() const
|
void Parser::checkStream() const
|
||||||
{
|
{
|
||||||
if (m_position == EndOfFile)
|
if (m_position == EndOfFile)
|
||||||
|
Reference in New Issue
Block a user