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 column() const;
CharacterType currentCharacter() const;
template<typename Type>
Type parse();
template<class CharacterCondition>
void parseUntil(std::vector<std::string> &container, CharacterCondition characterCondition);
template<class WhiteSpacePredicate, class CharacterPredicate>
std::string parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate);
template<typename Type>
void expect(const Type &expectedValue);
template<class WhiteSpacePredicate>
void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate);
void skipWhiteSpace();
void skipLine();
@ -63,12 +68,10 @@ class Parser
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterCondition>
void Parser::parseUntil(std::vector<std::string> &container, CharacterCondition characterCondition)
template<class WhiteSpacePredicate, class CharacterPredicate>
std::string Parser::parseIdentifier(WhiteSpacePredicate whiteSpacePredicate, CharacterPredicate characterPredicate)
{
while (true)
{
skipWhiteSpace();
skipWhiteSpace(whiteSpacePredicate);
std::string value;
@ -76,21 +79,23 @@ void Parser::parseUntil(std::vector<std::string> &container, CharacterCondition
{
const auto character = *m_position;
if (characterCondition(character))
{
container.emplace_back(std::move(value));
return;
}
if (std::isspace(character))
break;
if (!characterPredicate(character))
return value;
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>();
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)
{

View File

@ -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);
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////