Simplified Parser interface.

This commit is contained in:
Patrick Lühne 2016-05-29 15:08:10 +02:00
parent 2c564f47d3
commit 42fda5925d
3 changed files with 58 additions and 32 deletions

View File

@ -27,15 +27,20 @@ class Parser
size_t row() const; size_t row() const;
size_t column() const; size_t column() const;
CharacterType currentCharacter() const;
template<typename Type> template<typename Type>
Type parse(); Type parse();
template<class CharacterCondition> template<class WhiteSpacePredicate, class CharacterPredicate>
void parseUntil(std::vector<std::string> &container, CharacterCondition characterCondition); std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate);
template<typename Type> template<typename Type>
void expect(const Type &expectedValue); void expect(const Type &expectedValue);
template<class WhiteSpacePredicate>
void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate);
void skipWhiteSpace(); void skipWhiteSpace();
void skipLine(); void skipLine();
@ -63,38 +68,38 @@ class Parser
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterCondition> template<class WhiteSpacePredicate, class CharacterPredicate>
void Parser::parseUntil(std::vector<std::string> &container, CharacterCondition characterCondition) std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate)
{ {
skipWhiteSpace(whiteSpacePredicate);
std::string value;
while (true) while (true)
{ {
skipWhiteSpace(); const auto character = *m_position;
std::string value; if (!characterPredicate(character))
return value;
while (true) value.push_back(character);
{ advance();
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));
} }
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
template<class WhiteSpacePredicate>
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
{
checkStream();
while (whiteSpacePredicate(*m_position))
advance();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
} }
} }

View File

@ -28,10 +28,21 @@ Predicate Predicate::fromSAS(utils::Parser &parser)
predicate.m_name = parser.parse<std::string>(); predicate.m_name = parser.parse<std::string>();
parser.parseUntil(predicate.m_arguments, [](const auto character) while (true)
{ {
return character == '\n'; // 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<std::string>();
predicate.m_arguments.emplace_back(std::move(value));
}
} }
catch (const std::exception &e) catch (const std::exception &e)
{ {

View File

@ -54,6 +54,15 @@ size_t Parser::column() const
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
Parser::CharacterType Parser::currentCharacter() const
{
checkStream();
return *m_position;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Parser::checkStream() const void Parser::checkStream() const
{ {
if (m_position == EndOfFile) if (m_position == EndOfFile)
@ -100,10 +109,11 @@ bool Parser::advanceIf(CharacterType expectedCharacter)
void Parser::skipWhiteSpace() void Parser::skipWhiteSpace()
{ {
checkStream(); return skipWhiteSpace(
[](const auto character)
while (std::isspace(*m_position)) {
advance(); return std::isspace(character);
});
} }
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////