patrick
/
plasp
Archived
1
0
Fork 0
This repository has been archived on 2023-07-19. You can view files and clone it, but cannot push or open issues or pull requests.
plasp/include/plasp/utils/Parser.h

166 lines
4.0 KiB
C
Raw Normal View History

2016-05-27 03:58:59 +02:00
#ifndef __PLASP__UTILS__PARSER_H
#define __PLASP__UTILS__PARSER_H
#include <iostream>
#include <iterator>
#include <sstream>
2016-05-28 14:21:05 +02:00
#include <vector>
2016-05-27 03:58:59 +02:00
#include <boost/filesystem.hpp>
2016-05-27 03:58:59 +02:00
namespace plasp
{
namespace utils
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Parser
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Parser
{
public:
using Position = std::stringstream::pos_type;
2016-05-27 03:58:59 +02:00
struct Coordinate
{
std::string sectionName;
size_t row;
size_t column;
};
2016-06-07 15:54:01 +02:00
struct StreamDelimiter
{
Position position;
std::string sectionName;
};
2016-06-07 15:54:01 +02:00
public:
explicit Parser();
explicit Parser(std::string streamName, std::istream &istream);
// Forbid copy construction/assignment
Parser(const Parser &other) = delete;
Parser &operator=(const Parser &other) = delete;
Parser(Parser &&other);
Parser &operator=(Parser &&other);
void readStream(std::string streamName, std::istream &istream);
void readFile(const boost::filesystem::path &path);
void reset();
void seek(Position position);
Position position() const;
Coordinate coordinate() const;
2016-05-27 03:58:59 +02:00
void setCaseSensitive(bool isCaseInsensitive = true);
char currentCharacter() const;
void advance();
bool atEndOfStream() const;
2016-05-29 15:08:10 +02:00
void removeComments(const std::string &startSequence, const std::string &endSequence, bool removeEnd);
2016-05-27 18:39:43 +02:00
template<typename Type>
Type parse();
2016-05-27 03:58:59 +02:00
template<class CharacterPredicate, class WhiteSpacePredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate);
template<class CharacterPredicate>
std::string parseIdentifier(CharacterPredicate characterPredicate);
2016-05-28 14:21:05 +02:00
template<typename Type>
bool probe(const Type &expectedValue);
template<class CharacterPredicate>
bool probeIdentifier(const std::string &identifier, CharacterPredicate characterPredicate);
2016-05-27 18:39:43 +02:00
template<typename Type>
void expect(const Type &expectedValue);
2016-05-27 03:58:59 +02:00
2016-05-29 15:08:10 +02:00
template<class WhiteSpacePredicate>
void skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate);
2016-05-27 03:58:59 +02:00
void skipWhiteSpace();
void skipLine();
std::string getLine();
private:
static const std::istreambuf_iterator<char> EndOfFile;
2016-05-27 03:58:59 +02:00
private:
void checkStream() const;
uint64_t parseIntegerBody();
mutable std::stringstream m_stream;
2016-05-27 03:58:59 +02:00
std::vector<StreamDelimiter> m_streamDelimiters;
2016-05-27 03:58:59 +02:00
bool m_isCaseSensitive;
2016-05-27 03:58:59 +02:00
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate, class WhiteSpacePredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate, WhiteSpacePredicate whiteSpacePredicate)
2016-05-28 14:21:05 +02:00
{
2016-05-29 15:08:10 +02:00
skipWhiteSpace(whiteSpacePredicate);
std::string value;
2016-05-28 14:21:05 +02:00
while (true)
{
const auto character = currentCharacter();
2016-05-28 14:21:05 +02:00
2016-05-29 15:08:10 +02:00
if (!characterPredicate(character))
return value;
2016-05-28 14:21:05 +02:00
2016-05-29 15:08:10 +02:00
value.push_back(character);
advance();
}
}
2016-05-28 14:21:05 +02:00
2016-05-29 15:08:10 +02:00
////////////////////////////////////////////////////////////////////////////////////////////////////
2016-05-28 14:21:05 +02:00
template<class CharacterPredicate>
std::string Parser::parseIdentifier(CharacterPredicate characterPredicate)
{
return parseIdentifier(characterPredicate,
[&](const auto character)
{
return std::isspace(character);
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterPredicate>
bool Parser::probeIdentifier(const std::string &expectedValue, CharacterPredicate characterPredicate)
{
return probe<std::string>(expectedValue) && !characterPredicate(currentCharacter());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
2016-05-29 15:08:10 +02:00
template<class WhiteSpacePredicate>
void Parser::skipWhiteSpace(WhiteSpacePredicate whiteSpacePredicate)
{
checkStream();
2016-05-28 14:21:05 +02:00
while (!atEndOfStream() && whiteSpacePredicate(currentCharacter()))
2016-05-29 15:08:10 +02:00
advance();
2016-05-28 14:21:05 +02:00
}
////////////////////////////////////////////////////////////////////////////////////////////////////
2016-05-27 03:58:59 +02:00
}
}
#endif