diff --git a/include/plasp/LanguageDetection.h b/include/plasp/LanguageDetection.h index d4ae789..4dd6c9e 100644 --- a/include/plasp/LanguageDetection.h +++ b/include/plasp/LanguageDetection.h @@ -15,12 +15,8 @@ namespace plasp 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; - } + parser.setCaseSensitive(false); + parser.skipWhiteSpace(); // SAS begins with "begin_version" if (parser.probe("begin")) @@ -29,6 +25,20 @@ Language::Type detectLanguage(utils::Parser &parser) return Language::Type::SAS; } + // Skip potential PDDL comments + while (parser.currentCharacter() == ';') + { + parser.skipLine(); + parser.skipWhiteSpace(); + } + + // PDDL contains sections starting with "(define" + if (parser.probe("(") && parser.probe("define")) + { + parser.seek(std::ios::beg); + return Language::Type::PDDL; + } + parser.seek(std::ios::beg); return Language::Type::Unknown; } diff --git a/include/plasp/utils/Parser.h b/include/plasp/utils/Parser.h index 2f82ff3..78db6dd 100644 --- a/include/plasp/utils/Parser.h +++ b/include/plasp/utils/Parser.h @@ -62,6 +62,8 @@ class Parser void advance(); bool atEndOfStream() const; + void removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd); + template Type parse(); diff --git a/src/plasp/pddl/Description.cpp b/src/plasp/pddl/Description.cpp index d44b719..d4f564d 100644 --- a/src/plasp/pddl/Description.cpp +++ b/src/plasp/pddl/Description.cpp @@ -26,17 +26,17 @@ Description::Description() m_problemPosition{-1}, m_problem{std::make_unique(Problem(m_context, *m_domain))} { - m_parser.setCaseSensitive(false); } //////////////////////////////////////////////////////////////////////////////////////////////////// Description Description::fromParser(utils::Parser &&parser) { - parser.setCaseSensitive(false); - Description description; + parser.setCaseSensitive(false); + parser.removeComments(";", "\n", false); + description.m_parser = std::move(parser); description.parseContent(); @@ -53,6 +53,9 @@ Description Description::fromStream(std::istream &istream) description.m_parser.readStream("std::cin", istream); + description.m_parser.setCaseSensitive(false); + description.m_parser.removeComments(";", "\n", false); + description.parseContent(); description.checkConsistency(); @@ -67,6 +70,9 @@ Description Description::fromFile(const std::string &path) description.m_parser.readFile(path); + description.m_parser.setCaseSensitive(false); + description.m_parser.removeComments(";", "\n", false); + description.parseContent(); description.checkConsistency(); @@ -87,6 +93,9 @@ Description Description::fromFiles(const std::vector &paths) description.m_parser.readFile(path); }); + description.m_parser.setCaseSensitive(false); + description.m_parser.removeComments(";", "\n", false); + description.parseContent(); description.checkConsistency(); diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index db05e76..98f461d 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -276,11 +276,10 @@ std::string Parser::parse() template<> bool Parser::probe(const std::string &expectedValue) { - BOOST_ASSERT(!std::isspace(expectedValue[0])); - const auto previousPosition = position(); - skipWhiteSpace(); + if (!std::iswspace(expectedValue.front())) + skipWhiteSpace(); const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(), [&](const auto &expectedCharacter) @@ -529,5 +528,75 @@ void Parser::expect(const bool &expectedValue) //////////////////////////////////////////////////////////////////////////////////////////////////// +void Parser::removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd) +{ + const auto inPosition = m_stream.tellg(); + const auto outPosition = m_stream.tellp(); + + m_stream.seekg(0); + + const auto removeRange = + [&](const auto &start, const auto &end) + { + BOOST_ASSERT(start != -1); + + m_stream.clear(); + m_stream.seekp(start); + m_stream.seekg(start); + + auto position = start; + + while (end == -1 || position < end) + { + m_stream.ignore(1); + + if (atEndOfStream()) + return; + + m_stream.put(' '); + position += static_cast(1); + } + }; + + while (!atEndOfStream()) + { + Position startPosition = m_stream.tellg(); + + while (!atEndOfStream()) + { + startPosition = m_stream.tellg(); + + if (probe(startSequence)) + break; + + advance(); + } + + Position endPosition = m_stream.tellg(); + + while (!atEndOfStream()) + { + endPosition = m_stream.tellg(); + + if (probe(endSequence)) + break; + + advance(); + } + + if (removeEnd) + endPosition = m_stream.tellg(); + + removeRange(startPosition, endPosition); + } + + m_stream.clear(); + + m_stream.seekg(inPosition); + m_stream.seekp(outPosition); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/tests/TestUtils.cpp b/tests/TestUtils.cpp index 89b3a48..7f5fbba 100644 --- a/tests/TestUtils.cpp +++ b/tests/TestUtils.cpp @@ -177,6 +177,57 @@ TEST(UtilsTests, ParserPosition) //////////////////////////////////////////////////////////////////////////////////////////////////// +TEST(UtilsTests, ParserRemoveComments) +{ + std::stringstream s1("; comment at beginning\ntest1; comment in between\ntest2; comment at end"); + plasp::utils::Parser p1("input", s1); + + p1.removeComments(";", "\n", false); + + plasp::utils::Parser::Coordinate c; + + ASSERT_NO_THROW(p1.expect("test1")); + + c = p1.coordinate(); + ASSERT_EQ(c.row, 2u); + ASSERT_EQ(c.column, 6u); + + ASSERT_NO_THROW(p1.expect("test2")); + + c = p1.coordinate(); + ASSERT_EQ(c.row, 3u); + ASSERT_EQ(c.column, 6u); + + p1.skipWhiteSpace(); + + ASSERT_TRUE(p1.atEndOfStream()); + + std::stringstream s2("test;"); + plasp::utils::Parser p2("input", s2); + + p2.removeComments(";", "\n", false); + + ASSERT_NO_THROW(p2.expect("test")); + + p2.skipWhiteSpace(); + + ASSERT_TRUE(p2.atEndOfStream()); + + std::stringstream s3("/* comment at start */ test1 /* comment in between */ test2 /*"); + plasp::utils::Parser p3("input", s3); + + p3.removeComments("/*", "*/", true); + + ASSERT_NO_THROW(p3.expect("test1")); + ASSERT_NO_THROW(p3.expect("test2")); + + p3.skipWhiteSpace(); + + ASSERT_TRUE(p3.atEndOfStream()); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + TEST(UtilsTests, EscapeASP) { const std::string predicate = "action(stack_on(block-1, block-2, value@3, value@4))";