From 2e1a011dcf275d6d80dec2ff5cd23df728eca6bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Fri, 10 Jun 2016 01:23:41 +0200 Subject: [PATCH] Implemented automatic language detection for plasp application. --- apps/plasp-app/main.cpp | 30 +++++++++++++++---- include/plasp/Language.h | 36 ++++++++++++++++++++++ include/plasp/LanguageDetection.h | 40 +++++++++++++++++++++++++ src/plasp/Language.cpp | 50 +++++++++++++++++++++++++++++++ src/plasp/pddl/Description.cpp | 2 ++ src/plasp/sas/Description.cpp | 2 ++ 6 files changed, 154 insertions(+), 6 deletions(-) create mode 100644 include/plasp/Language.h create mode 100644 include/plasp/LanguageDetection.h create mode 100644 src/plasp/Language.cpp diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp index 447d86d..b76f407 100644 --- a/apps/plasp-app/main.cpp +++ b/apps/plasp-app/main.cpp @@ -4,6 +4,7 @@ #include +#include #include #include #include @@ -17,7 +18,7 @@ int main(int argc, char **argv) ("help,h", "Display this help message.") ("version,v", "Display version information.") ("input,i", po::value>(), "Specify the SAS input file.") - ("format,f", po::value()->default_value("SAS"), "Specify the file format (SAS or PDDL)."); + ("language,l", po::value(), "Specify the input language (SAS or PDDL) explicitly (no automatic detection)."); po::positional_options_description positionalOptionsDescription; positionalOptionsDescription.add("input", -1); @@ -78,17 +79,34 @@ int main(int argc, char **argv) else parser.readStream("std::cin", std::cin); - auto format = variablesMap["format"].as(); - std::transform(format.begin(), format.end(), format.begin(), ::tolower); + const auto detectLanguage = + [&]() + { + if (variablesMap.count("language") == 0) + return plasp::detectLanguage(parser); - if (format == "sas") + const auto languageName = variablesMap["language"].as(); + + 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 sasTranslator = plasp::sas::TranslatorASP(sasDescription); sasTranslator.translate(std::cout); } - else if (format == "pddl") - plasp::pddl::Description::fromParser(std::move(parser)); return EXIT_SUCCESS; } diff --git a/include/plasp/Language.h b/include/plasp/Language.h new file mode 100644 index 0000000..7769a0b --- /dev/null +++ b/include/plasp/Language.h @@ -0,0 +1,36 @@ +#ifndef __PLASP__LANGUAGE_H +#define __PLASP__LANGUAGE_H + +#include + +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 diff --git a/include/plasp/LanguageDetection.h b/include/plasp/LanguageDetection.h new file mode 100644 index 0000000..d4ae789 --- /dev/null +++ b/include/plasp/LanguageDetection.h @@ -0,0 +1,40 @@ +#ifndef __PLASP__LANGUAGE_DETECTION_H +#define __PLASP__LANGUAGE_DETECTION_H + +#include +#include + +namespace plasp +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// LanguageDetection +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Language::Type detectLanguage(utils::Parser &parser) +{ + // PDDL contains sections starting with "(define" + if (parser.probe("(") && parser.probe("define")) + { + parser.seek(std::ios::beg); + return Language::Type::PDDL; + } + + // SAS begins with "begin_version" + if (parser.probe("begin")) + { + parser.seek(std::ios::beg); + return Language::Type::SAS; + } + + parser.seek(std::ios::beg); + return Language::Type::Unknown; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} + +#endif diff --git a/src/plasp/Language.cpp b/src/plasp/Language.cpp new file mode 100644 index 0000000..aea5446 --- /dev/null +++ b/src/plasp/Language.cpp @@ -0,0 +1,50 @@ +#include + +#include +#include + +namespace plasp +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Language +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +using LanguageNames = boost::bimap; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const LanguageNames languageNames = boost::assign::list_of + (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; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index 5d08814..d44b719 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -33,6 +33,8 @@ Description::Description() Description Description::fromParser(utils::Parser &&parser) { + parser.setCaseSensitive(false); + Description description; description.m_parser = std::move(parser); diff --git a/src/plasp/sas/Description.cpp b/src/plasp/sas/Description.cpp index 1d5c3fa..385a63c 100644 --- a/src/plasp/sas/Description.cpp +++ b/src/plasp/sas/Description.cpp @@ -30,6 +30,8 @@ Description::Description() Description Description::fromParser(utils::Parser &&parser) { + parser.setCaseSensitive(true); + Description description; description.parseContent(parser);