diff --git a/include/plasp/utils/Parser.h b/include/plasp/utils/Parser.h index c6e9481..e65c13b 100644 --- a/include/plasp/utils/Parser.h +++ b/include/plasp/utils/Parser.h @@ -18,16 +18,13 @@ namespace utils class Parser { - public: - using CharacterType = unsigned char; - public: explicit Parser(std::istream &istream); size_t row() const; size_t column() const; - CharacterType currentCharacter() const; + char currentCharacter() const; void advance(); bool atEndOfFile() const; @@ -52,17 +49,17 @@ class Parser std::string getLine(); private: - static const std::istream_iterator EndOfFile; + static const std::istreambuf_iterator EndOfFile; private: void checkStream() const; - bool advanceIf(CharacterType expectedCharacter); + bool advanceIf(char expectedCharacter); uint64_t parseIntegerBody(); std::istream &m_istream; - std::istream_iterator m_position; + std::istreambuf_iterator m_position; size_t m_row; size_t m_column; @@ -81,7 +78,7 @@ std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, White while (true) { - const auto character = *m_position; + const auto character = currentCharacter(); if (!characterPredicate(character)) return value; @@ -110,7 +107,7 @@ void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate) { checkStream(); - while (m_position != EndOfFile && whiteSpacePredicate(*m_position)) + while (!atEndOfFile() && whiteSpacePredicate(currentCharacter())) advance(); } diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index 94f091e..edc4ebd 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -17,7 +17,7 @@ namespace utils // //////////////////////////////////////////////////////////////////////////////////////////////////// -const std::istream_iterator Parser::EndOfFile = std::istream_iterator(); +const std::istreambuf_iterator Parser::EndOfFile = std::istreambuf_iterator(); //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -30,10 +30,9 @@ Parser::Parser(std::istream &istream) { std::setlocale(LC_NUMERIC, "C"); - istream.exceptions(std::istream::badbit); - // Don’t skip whitespace istream >> std::noskipws; + istream.exceptions(std::istream::badbit); checkStream(); } @@ -54,7 +53,7 @@ size_t Parser::column() const //////////////////////////////////////////////////////////////////////////////////////////////////// -Parser::CharacterType Parser::currentCharacter() const +char Parser::currentCharacter() const { checkStream(); @@ -65,14 +64,14 @@ Parser::CharacterType Parser::currentCharacter() const bool Parser::atEndOfFile() const { - return m_position == EndOfFile; + return m_position.equal(EndOfFile); } //////////////////////////////////////////////////////////////////////////////////////////////////// void Parser::checkStream() const { - if (m_position == EndOfFile) + if (atEndOfFile()) throw ParserException(m_row, m_column, "Reading past end of file"); if (m_istream.fail()) @@ -85,7 +84,7 @@ void Parser::advance() { checkStream(); - const auto character = *m_position; + const auto character = currentCharacter(); if (character == '\n') { @@ -100,11 +99,11 @@ void Parser::advance() //////////////////////////////////////////////////////////////////////////////////////////////////// -bool Parser::advanceIf(CharacterType expectedCharacter) +bool Parser::advanceIf(char expectedCharacter) { checkStream(); - if (*m_position != expectedCharacter) + if (currentCharacter() != expectedCharacter) return false; advance(); @@ -129,7 +128,7 @@ void Parser::skipLine() { checkStream(); - while (*m_position != '\n') + while (currentCharacter() != '\n') advance(); advance(); @@ -145,7 +144,7 @@ std::string Parser::getLine() while (true) { - const auto character = *m_position; + const auto character = currentCharacter(); advance(); @@ -171,7 +170,7 @@ std::string Parser::parse() while (true) { - const auto character = *m_position; + const auto character = currentCharacter(); if (std::isspace(character)) break; @@ -195,10 +194,10 @@ void Parser::expect(const std::string &expectedValue) std::for_each(expectedValue.cbegin(), expectedValue.cend(), [&](const auto &expectedCharacter) { - const auto character = *m_position; + const auto character = static_cast(this->currentCharacter()); if (character != expectedCharacter) - throw ParserException(m_row, m_column, "Unexpected string, expected " + expectedValue); + throw ParserException(m_row, m_column, "Unexpected string, expected " + expectedValue + " (expected " + expectedCharacter + ", got " + character + ")"); this->advance(); }); @@ -210,14 +209,14 @@ uint64_t Parser::parseIntegerBody() { checkStream(); - if (!std::isdigit(*m_position)) + if (!std::isdigit(currentCharacter())) throw ParserException(m_row, m_column, "Could not parse integer value"); uint64_t value = 0; - while (m_position != std::istream_iterator()) + while (!atEndOfFile()) { - const auto character = *m_position; + const auto character = currentCharacter(); if (!std::isdigit(character)) break; @@ -252,7 +251,7 @@ uint64_t Parser::parse() { skipWhiteSpace(); - if (*m_position == '-') + if (currentCharacter() == '-') throw ParserException(m_row, m_column, "Expected unsigned integer, got signed one"); return parseIntegerBody();