Implemented automatic language detection for plasp application.

This commit is contained in:
Patrick Lühne 2016-06-10 01:23:41 +02:00
parent 8ef874eb22
commit 2e1a011dcf
6 changed files with 154 additions and 6 deletions

View File

@ -4,6 +4,7 @@
#include <boost/program_options.hpp> #include <boost/program_options.hpp>
#include <plasp/LanguageDetection.h>
#include <plasp/pddl/Description.h> #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>
@ -17,7 +18,7 @@ int main(int argc, char **argv)
("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::vector<std::string>>(), "Specify the SAS input file.") ("input,i", po::value<std::vector<std::string>>(), "Specify the SAS input file.")
("format,f", po::value<std::string>()->default_value("SAS"), "Specify the file format (SAS or PDDL)."); ("language,l", po::value<std::string>(), "Specify the input language (SAS or PDDL) explicitly (no automatic detection).");
po::positional_options_description positionalOptionsDescription; po::positional_options_description positionalOptionsDescription;
positionalOptionsDescription.add("input", -1); positionalOptionsDescription.add("input", -1);
@ -78,17 +79,34 @@ int main(int argc, char **argv)
else else
parser.readStream("std::cin", std::cin); parser.readStream("std::cin", std::cin);
auto format = variablesMap["format"].as<std::string>(); const auto detectLanguage =
std::transform(format.begin(), format.end(), format.begin(), ::tolower); [&]()
{
if (variablesMap.count("language") == 0)
return plasp::detectLanguage(parser);
if (format == "sas") const auto languageName = variablesMap["language"].as<std::string>();
return plasp::Language::fromString(languageName);
};
const auto language = detectLanguage();
if (language == plasp::Language::Type::Unknown)
{
std::cerr << "Error: Unknown input language" << std::endl << std::endl;
printHelp();
return EXIT_FAILURE;
}
if (language == plasp::Language::Type::PDDL)
plasp::pddl::Description::fromParser(std::move(parser));
else if (language == plasp::Language::Type::SAS)
{ {
const auto sasDescription = plasp::sas::Description::fromParser(std::move(parser)); const auto sasDescription = plasp::sas::Description::fromParser(std::move(parser));
const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription); const auto sasTranslator = plasp::sas::TranslatorASP(sasDescription);
sasTranslator.translate(std::cout); sasTranslator.translate(std::cout);
} }
else if (format == "pddl")
plasp::pddl::Description::fromParser(std::move(parser));
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

36
include/plasp/Language.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef __PLASP__LANGUAGE_H
#define __PLASP__LANGUAGE_H
#include <plasp/utils/Parser.h>
namespace plasp
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Language
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Language
{
public:
enum class Type
{
Unknown,
PDDL,
SAS
};
static std::string toString(Type language);
static Language::Type fromString(const std::string &languageName);
public:
Language() = delete;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
#endif

View File

@ -0,0 +1,40 @@
#ifndef __PLASP__LANGUAGE_DETECTION_H
#define __PLASP__LANGUAGE_DETECTION_H
#include <plasp/Language.h>
#include <plasp/utils/Parser.h>
namespace plasp
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LanguageDetection
//
////////////////////////////////////////////////////////////////////////////////////////////////////
Language::Type detectLanguage(utils::Parser &parser)
{
// PDDL contains sections starting with "(define"
if (parser.probe<std::string>("(") && parser.probe<std::string>("define"))
{
parser.seek(std::ios::beg);
return Language::Type::PDDL;
}
// SAS begins with "begin_version"
if (parser.probe<std::string>("begin"))
{
parser.seek(std::ios::beg);
return Language::Type::SAS;
}
parser.seek(std::ios::beg);
return Language::Type::Unknown;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
#endif

50
src/plasp/Language.cpp Normal file
View File

@ -0,0 +1,50 @@
#include <plasp/Language.h>
#include <boost/assign.hpp>
#include <boost/bimap.hpp>
namespace plasp
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Language
//
////////////////////////////////////////////////////////////////////////////////////////////////////
using LanguageNames = boost::bimap<Language::Type, std::string>;
////////////////////////////////////////////////////////////////////////////////////////////////////
const LanguageNames languageNames = boost::assign::list_of<LanguageNames::relation>
(Language::Type::PDDL, "PDDL")
(Language::Type::SAS, "SAS")
(Language::Type::Unknown, "Unknown");
////////////////////////////////////////////////////////////////////////////////////////////////////
std::string Language::toString(Language::Type language)
{
const auto match = languageNames.left.find(language);
if (match != languageNames.left.end())
return "Unknown";
return match->second;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
Language::Type Language::fromString(const std::string &languageName)
{
const auto match = languageNames.right.find(languageName);
if (match != languageNames.right.end())
return Language::Type::Unknown;
return match->second;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}

View File

@ -33,6 +33,8 @@ Description::Description()
Description Description::fromParser(utils::Parser &&parser) Description Description::fromParser(utils::Parser &&parser)
{ {
parser.setCaseSensitive(false);
Description description; Description description;
description.m_parser = std::move(parser); description.m_parser = std::move(parser);

View File

@ -30,6 +30,8 @@ Description::Description()
Description Description::fromParser(utils::Parser &&parser) Description Description::fromParser(utils::Parser &&parser)
{ {
parser.setCaseSensitive(true);
Description description; Description description;
description.parseContent(parser); description.parseContent(parser);