diff --git a/include/plasp/utils/Parser.h b/include/plasp/utils/Parser.h index c650d1e..f54991f 100644 --- a/include/plasp/utils/Parser.h +++ b/include/plasp/utils/Parser.h @@ -27,15 +27,20 @@ class Parser size_t row() const; size_t column() const; + CharacterType currentCharacter() const; + template Type parse(); - template - void parseUntil(std::vector &container, CharacterCondition characterCondition); + template + std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate); template void expect(const Type &expectedValue); + template + void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate); + void skipWhiteSpace(); void skipLine(); @@ -63,38 +68,38 @@ class Parser //////////////////////////////////////////////////////////////////////////////////////////////////// -template -void Parser::parseUntil(std::vector &container, CharacterCondition characterCondition) +template +std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate) { + skipWhiteSpace(whiteSpacePredicate); + + std::string value; + while (true) { - skipWhiteSpace(); + const auto character = *m_position; - std::string value; + if (!characterPredicate(character)) + return value; - while (true) - { - const auto character = *m_position; - - if (characterCondition(character)) - { - container.emplace_back(std::move(value)); - return; - } - - if (std::isspace(character)) - break; - - value.push_back(character); - advance(); - } - - container.emplace_back(std::move(value)); + value.push_back(character); + advance(); } } //////////////////////////////////////////////////////////////////////////////////////////////////// +template +void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate) +{ + checkStream(); + + while (whiteSpacePredicate(*m_position)) + advance(); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + } } diff --git a/src/plasp/sas/Predicate.cpp b/src/plasp/sas/Predicate.cpp index 9f4d0c7..db9aae8 100644 --- a/src/plasp/sas/Predicate.cpp +++ b/src/plasp/sas/Predicate.cpp @@ -28,10 +28,21 @@ Predicate Predicate::fromSAS(utils::Parser &parser) predicate.m_name = parser.parse(); - parser.parseUntil(predicate.m_arguments, [](const auto character) - { - return character == '\n'; - }); + while (true) + { + // Parse arguments until reaching newline + parser.skipWhiteSpace( + [&](const auto character) + { + return character != '\n' && std::isspace(character); + }); + + if (parser.currentCharacter() == '\n') + break; + + const auto value = parser.parse(); + predicate.m_arguments.emplace_back(std::move(value)); + } } catch (const std::exception &e) { diff --git a/src/plasp/utils/Parser.cpp b/src/plasp/utils/Parser.cpp index b3df864..55892a8 100644 --- a/src/plasp/utils/Parser.cpp +++ b/src/plasp/utils/Parser.cpp @@ -54,6 +54,15 @@ size_t Parser::column() const //////////////////////////////////////////////////////////////////////////////////////////////////// +Parser::CharacterType Parser::currentCharacter() const +{ + checkStream(); + + return *m_position; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Parser::checkStream() const { if (m_position == EndOfFile) @@ -100,10 +109,11 @@ bool Parser::advanceIf(CharacterType expectedCharacter) void Parser::skipWhiteSpace() { - checkStream(); - - while (std::isspace(*m_position)) - advance(); + return skipWhiteSpace( + [](const auto character) + { + return std::isspace(character); + }); } ////////////////////////////////////////////////////////////////////////////////////////////////////