diff --git a/include/plasp/utils/Parser.h b/include/plasp/utils/Parser.h index 871715b..00ecfe5 100644 --- a/include/plasp/utils/Parser.h +++ b/include/plasp/utils/Parser.h @@ -53,7 +53,6 @@ class Parser char currentCharacter() const; void advance(); - bool advanceIf(char expectedCharacter); bool atEndOfStream() const; template @@ -65,6 +64,9 @@ class Parser template std::string parseIdentifier(CharacterPredicate characterPredicate); + template + bool probe(const Type &expectedValue); + template void expect(const Type &expectedValue); diff --git a/src/plasp/pddl/expressions/Constant.cpp b/src/plasp/pddl/expressions/Constant.cpp index 5e26d3b..ac23a2a 100644 --- a/src/plasp/pddl/expressions/Constant.cpp +++ b/src/plasp/pddl/expressions/Constant.cpp @@ -80,7 +80,7 @@ void Constant::parseTypedDeclaration(Context &context, Domain &domain, Constants context.parser.skipWhiteSpace(); // Check for typing information - if (!context.parser.advanceIf('-')) + if (!context.parser.probe('-')) return; // If existing, parse and store parent type diff --git a/src/plasp/pddl/expressions/PrimitiveType.cpp b/src/plasp/pddl/expressions/PrimitiveType.cpp index 6ed8f59..a73b7e0 100644 --- a/src/plasp/pddl/expressions/PrimitiveType.cpp +++ b/src/plasp/pddl/expressions/PrimitiveType.cpp @@ -82,7 +82,7 @@ void PrimitiveType::parseTypedDeclaration(Context &context, Domain &domain) context.parser.skipWhiteSpace(); // Check for type inheritance - if (!context.parser.advanceIf('-')) + if (!context.parser.probe('-')) return; // If existing, parse and store parent type diff --git a/src/plasp/pddl/expressions/Variable.cpp b/src/plasp/pddl/expressions/Variable.cpp index c55d02e..e2eaaa9 100644 --- a/src/plasp/pddl/expressions/Variable.cpp +++ b/src/plasp/pddl/expressions/Variable.cpp @@ -64,7 +64,7 @@ void Variable::parseTypedDeclaration(Context &context, ExpressionContext &expres context.parser.skipWhiteSpace(); // Check if the variable has a type declaration - if (!context.parser.advanceIf('-')) + if (!context.parser.probe('-')) return; // TODO: do not allow nested either expressions diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index 60dc7e5..455f61d 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -179,20 +179,6 @@ void Parser::advance() //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Parser::advanceIf(char expectedCharacter) -{ - checkStream(); - - if (currentCharacter() != expectedCharacter) - return false; - - advance(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - void Parser::skipWhiteSpace() { return skipWhiteSpace( @@ -265,22 +251,78 @@ std::string Parser::parse() //////////////////////////////////////////////////////////////////////////////////////////////////// template<> -void Parser::expect(const std::string &expectedValue) +bool Parser::probe(const std::string &expectedValue) { BOOST_ASSERT(!std::isspace(expectedValue[0])); skipWhiteSpace(); - std::for_each(expectedValue.cbegin(), expectedValue.cend(), + const auto previousPosition = position(); + + const auto match = std::find_if(expectedValue.cbegin(), expectedValue.cend(), [&](const auto &expectedCharacter) { const auto character = static_cast(this->currentCharacter()); if (character != expectedCharacter) - throw ParserException(*this, "Unexpected string, expected \"" + expectedValue + "\" (expected character '" + expectedCharacter + "', got '" + character + "')"); + return true; this->advance(); + + return false; }); + + const auto differs = (match != expectedValue.cend()); + + if (!differs) + return true; + + seek(previousPosition); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +void Parser::expect(const std::string &expectedValue) +{ + if (!probe(expectedValue)) + throw ParserException(*this, "Unexpected value, expected \"" + expectedValue + "\""); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +char Parser::parse() +{ + const auto value = currentCharacter(); + + advance(); + + return value; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +bool Parser::probe(const char &expectedValue) +{ + if (currentCharacter() != expectedValue) + return false; + + advance(); + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +void Parser::expect(const char &expectedValue) +{ + if (!probe(expectedValue)) + throw ParserException(*this, std::string("Unexpected value, expected \"") + expectedValue + "\""); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -317,7 +359,7 @@ int64_t Parser::parse() { skipWhiteSpace(); - bool positive = advanceIf('+') || !advanceIf('-'); + bool positive = probe('+') || !probe('-'); const auto value = parseIntegerBody(); @@ -340,12 +382,42 @@ uint64_t Parser::parse() //////////////////////////////////////////////////////////////////////////////////////////////////// template<> -void Parser::expect(const int64_t &expectedValue) +bool Parser::probe(const int64_t &expectedValue) { + const auto previousPosition = position(); const auto value = parse(); - if (value != expectedValue) - throw ParserException(*this, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue)); + if (value == expectedValue) + return true; + + seek(previousPosition); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +bool Parser::probe(const uint64_t &expectedValue) +{ + const auto previousPosition = position(); + const auto value = parse(); + + if (value == expectedValue) + return true; + + seek(previousPosition); + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +void Parser::expect(const int64_t &expectedValue) +{ + if (!probe(expectedValue)) + throw ParserException(*this, "Unexpected value, expected \"" + std::to_string(expectedValue) + "\""); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -353,10 +425,8 @@ void Parser::expect(const int64_t &expectedValue) template<> void Parser::expect(const uint64_t &expectedValue) { - const auto value = parse(); - - if (value != expectedValue) - throw ParserException(*this, "Unexpected value " + std::to_string(value) + ", expected " + std::to_string(expectedValue)); + if (!probe(expectedValue)) + throw ParserException(*this, "Unexpected value, expected \"" + std::to_string(expectedValue) + "\""); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -377,6 +447,22 @@ uint32_t Parser::parse() //////////////////////////////////////////////////////////////////////////////////////////////////// +template<> +bool Parser::probe(const int32_t &expectedValue) +{ + return probe(static_cast(expectedValue)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template<> +bool Parser::probe(const uint32_t &expectedValue) +{ + return probe(static_cast(expectedValue)); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + template<> void Parser::expect(const int32_t &expectedValue) { @@ -393,79 +479,15 @@ void Parser::expect(const uint32_t &expectedValue) //////////////////////////////////////////////////////////////////////////////////////////////////// -template<> -int16_t Parser::parse() -{ - return static_cast(parse()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -uint16_t Parser::parse() -{ - return static_cast(parse()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -void Parser::expect(const int16_t &expectedValue) -{ - expect(static_cast(expectedValue)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -void Parser::expect(const uint16_t &expectedValue) -{ - expect(static_cast(expectedValue)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -int8_t Parser::parse() -{ - return static_cast(parse()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -uint8_t Parser::parse() -{ - return static_cast(parse()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -void Parser::expect(const int8_t &expectedValue) -{ - expect(static_cast(expectedValue)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -template<> -void Parser::expect(const uint8_t &expectedValue) -{ - expect(static_cast(expectedValue)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - template<> bool Parser::parse() { skipWhiteSpace(); - if (advanceIf('0')) + if (probe('0')) return false; - if (advanceIf('1')) + if (probe('1')) return true; throw ParserException(*this, "Could not parse Boolean value");