From 5c3ea28e48cd959c081345b99287007fef6a6a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Mon, 13 Jun 2016 14:45:31 +0200 Subject: [PATCH] Added command-line option for treating warnings as errors or completely ignoring them. --- apps/plasp-app/main.cpp | 39 +++++++++++++------ include/plasp/pddl/Context.h | 36 +++++++++++++++-- include/plasp/pddl/Description.h | 8 ++-- include/plasp/utils/Logger.h | 18 ++++++++- src/plasp/pddl/Description.cpp | 67 ++++++++++++++++---------------- src/plasp/utils/Logger.cpp | 45 +++++++++++++++++++-- 6 files changed, 157 insertions(+), 56 deletions(-) diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp index 1ed4ad2..b0086f4 100644 --- a/apps/plasp-app/main.cpp +++ b/apps/plasp-app/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include int main(int argc, char **argv) @@ -20,7 +21,8 @@ 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.") - ("language,l", po::value(), "Specify the input language (SAS or PDDL). Omit for automatic detection."); + ("language,l", po::value(), "Specify the input language (SAS or PDDL). Omit for automatic detection.") + ("warning-level", po::value()->default_value("normal"), "Specify whether to output warnings normally (normal), to treat them as critical errors (error), or to ignore them (ignore)."); po::positional_options_description positionalOptionsDescription; positionalOptionsDescription.add("input", -1); @@ -64,6 +66,14 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } + const auto handleException = + [&](const auto &messagePrefix, const auto &exception) + { + std::cerr << messagePrefix << ": " << exception.what() << std::endl << std::endl; + printHelp(); + return EXIT_FAILURE; + }; + try { plasp::utils::Parser parser; @@ -105,7 +115,16 @@ int main(int argc, char **argv) if (language == plasp::Language::Type::PDDL) { - const auto description = plasp::pddl::Description::fromParser(std::move(parser)); + auto context = plasp::pddl::Context(std::move(parser)); + + const auto warningLevel = variablesMap["warning-level"].as(); + + if (warningLevel == "error") + context.logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Error); + else if (warningLevel == "ignore") + context.logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Ignore); + + const auto description = plasp::pddl::Description::fromContext(std::move(context)); const auto translator = plasp::pddl::TranslatorASP(description, std::cout); translator.translate(); } @@ -118,21 +137,19 @@ int main(int argc, char **argv) } catch (const plasp::utils::ParserException &e) { - std::cerr << "Parser error: " << e.what() << std::endl << std::endl; - printHelp(); - return EXIT_FAILURE; + handleException("Parser error", e); + } + catch (const plasp::utils::ParserWarning &e) + { + handleException("Parser warning", e); } catch (const plasp::utils::TranslatorException &e) { - std::cerr << "Translation error: " << e.what() << std::endl << std::endl; - printHelp(); - return EXIT_FAILURE; + handleException("Translation error", e); } catch (const std::exception &e) { - std::cerr << "Error: " << e.what() << std::endl << std::endl; - printHelp(); - return EXIT_FAILURE; + handleException("Error", e); } return EXIT_SUCCESS; diff --git a/include/plasp/pddl/Context.h b/include/plasp/pddl/Context.h index f71426d..76d5ca2 100644 --- a/include/plasp/pddl/Context.h +++ b/include/plasp/pddl/Context.h @@ -21,12 +21,42 @@ namespace pddl class Context { public: - Context(utils::Parser &parser) - : parser(parser) + Context() = default; + + explicit Context(utils::Parser &&parser) + : parser{std::move(parser)} { } - utils::Parser &parser; + explicit Context(utils::Logger &&logger) + : logger{std::move(logger)} + { + } + + explicit Context(utils::Parser &&parser, utils::Logger &&logger) + : parser{std::move(parser)}, + logger{std::move(logger)} + { + } + + Context(const Context &other) = delete; + Context &operator=(const Context &other) = delete; + + Context(Context &&other) + : parser(std::move(other.parser)), + logger(std::move(other.logger)) + { + } + + Context &operator=(Context &&other) + { + parser = std::move(other.parser); + logger = std::move(other.logger); + + return *this; + } + + utils::Parser parser; utils::Logger logger; }; diff --git a/include/plasp/pddl/Description.h b/include/plasp/pddl/Description.h index cfdbdaf..50a1687 100644 --- a/include/plasp/pddl/Description.h +++ b/include/plasp/pddl/Description.h @@ -21,12 +21,15 @@ namespace pddl class Description { public: - static Description fromParser(utils::Parser &&parser); + static Description fromContext(Context &&context); static Description fromStream(std::istream &istream); static Description fromFile(const std::string &path); static Description fromFiles(const std::vector &paths); public: + Context &context(); + const Context &context() const; + const Domain &domain() const; bool containsProblem() const; @@ -35,12 +38,11 @@ class Description private: Description(); - void parseContent(); + void parse(); void findSections(); void checkConsistency(); - utils::Parser m_parser; Context m_context; utils::Parser::Position m_domainPosition; diff --git a/include/plasp/utils/Logger.h b/include/plasp/utils/Logger.h index 1dfc106..60b5503 100644 --- a/include/plasp/utils/Logger.h +++ b/include/plasp/utils/Logger.h @@ -18,15 +18,29 @@ namespace utils class Logger { + public: + enum class WarningLevel + { + Normal, + Error, + Ignore + }; + public: Logger(); - void setPedantic(bool isPedantic = true); + Logger(const Logger &other); + Logger &operator=(const Logger &other); + + Logger(Logger &&other); + Logger &operator=(Logger &&other); + + void setWarningLevel(WarningLevel warningLevel); void parserWarning(const Parser &parser, const std::string &message); private: - bool m_isPedantic; + WarningLevel m_warningLevel; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index 54610bc..104b8af 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -20,8 +20,7 @@ namespace pddl //////////////////////////////////////////////////////////////////////////////////////////////////// Description::Description() -: m_context(m_parser), - m_domainPosition{-1}, +: m_domainPosition{-1}, m_domain{std::make_unique(Domain(m_context))}, m_problemPosition{-1} { @@ -29,17 +28,12 @@ Description::Description() //////////////////////////////////////////////////////////////////////////////////////////////////// -Description Description::fromParser(utils::Parser &&parser) +Description Description::fromContext(Context &&context) { Description description; - parser.setCaseSensitive(false); - parser.removeComments(";", "\n", false); - - description.m_parser = std::move(parser); - - description.parseContent(); - description.checkConsistency(); + description.m_context = std::move(context); + description.parse(); return description; } @@ -50,13 +44,8 @@ Description Description::fromStream(std::istream &istream) { Description description; - description.m_parser.readStream("std::cin", istream); - - description.m_parser.setCaseSensitive(false); - description.m_parser.removeComments(";", "\n", false); - - description.parseContent(); - description.checkConsistency(); + description.m_context.parser.readStream("std::cin", istream); + description.parse(); return description; } @@ -67,13 +56,8 @@ Description Description::fromFile(const std::string &path) { Description description; - description.m_parser.readFile(path); - - description.m_parser.setCaseSensitive(false); - description.m_parser.removeComments(";", "\n", false); - - description.parseContent(); - description.checkConsistency(); + description.m_context.parser.readFile(path); + description.parse(); return description; } @@ -89,20 +73,30 @@ Description Description::fromFiles(const std::vector &paths) std::for_each(paths.cbegin(), paths.cend(), [&](const auto &path) { - description.m_parser.readFile(path); + description.m_context.parser.readFile(path); }); - description.m_parser.setCaseSensitive(false); - description.m_parser.removeComments(";", "\n", false); - - description.parseContent(); - description.checkConsistency(); + description.parse(); return description; } //////////////////////////////////////////////////////////////////////////////////////////////////// +Context &Description::context() +{ + return m_context; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +const Context &Description::context() const +{ + return m_context; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + const Domain &Description::domain() const { BOOST_ASSERT(m_domain); @@ -128,22 +122,29 @@ const Problem &Description::problem() const //////////////////////////////////////////////////////////////////////////////////////////////////// -void Description::parseContent() +void Description::parse() { + auto &parser = m_context.parser; + + parser.setCaseSensitive(false); + parser.removeComments(";", "\n", false); + // 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); + parser.seek(m_domainPosition); m_domain->parse(); if (m_problemPosition != -1) { - m_context.parser.seek(m_problemPosition); + parser.seek(m_problemPosition); m_problem->parse(); } + + checkConsistency(); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/plasp/utils/Logger.cpp b/src/plasp/utils/Logger.cpp index cef7941..96caf0b 100644 --- a/src/plasp/utils/Logger.cpp +++ b/src/plasp/utils/Logger.cpp @@ -14,22 +14,59 @@ namespace utils //////////////////////////////////////////////////////////////////////////////////////////////////// Logger::Logger() -: m_isPedantic{false} +: m_warningLevel{Logger::WarningLevel::Normal} { } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Logger::setPedantic(bool isPedantic) +Logger::Logger(const Logger &other) +: m_warningLevel{other.m_warningLevel} { - m_isPedantic = isPedantic; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger &Logger::operator=(const Logger &other) +{ + m_warningLevel = other.m_warningLevel; + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger::Logger(Logger &&other) +: m_warningLevel{other.m_warningLevel} +{ + other.m_warningLevel = WarningLevel::Normal; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +Logger &Logger::operator=(Logger &&other) +{ + m_warningLevel = other.m_warningLevel; + other.m_warningLevel = WarningLevel::Normal; + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void Logger::setWarningLevel(WarningLevel warningLevel) +{ + m_warningLevel = warningLevel; } //////////////////////////////////////////////////////////////////////////////////////////////////// void Logger::parserWarning(const Parser &parser, const std::string &message) { - if (m_isPedantic) + if (m_warningLevel == WarningLevel::Ignore) + return; + + if (m_warningLevel == WarningLevel::Error) throw ParserWarning(parser, message); const auto coordinate = parser.coordinate();