#pragma once #include #include #include #include #include struct BBBParseError: std::exception { BBBParseError(std::string msg): message(msg) {} std::string message; const char *what() const noexcept override { return message.c_str(); } }; class BBBParser { public: using Variables = std::unordered_map>; static const int FLAG_NONE = 0; static const int FLAG_ONE_LINE = 1 << 0; BBBParser(std::istream &stream, int flags, int line = 1, int ch = 1): flags_(flags), line_(line), ch_(ch), stream_(stream) {} void parse(Variables &vars); int peek() { return stream_.peek(); } int peek2() { stream_.get(); int ch = peek(); stream_.unget(); return ch; } int get(); void skip(char); void skip() { get(); } int line() const { return line_; } int ch() const { return ch_; } private: enum class Operator { COLON_EQUALS, PLUS_EQUALS, EQUALS_PLUS, NONE, }; [[noreturn]] void error(std::string); Operator readOperator(); void skipWhitespaceLine(); void skipWhitespace(); char parseEscape(); void parseExpansion(const Variables &vars, std::vector &values); void parseQuotedExpansion(const Variables &vars, std::string &content); void parseQuotedString(const Variables &vars, std::string &content); bool parseString(const Variables &vars, std::string &content, int sep = -1); bool parseIdentifier(std::string &content); int flags_; int line_; int ch_; std::istream &stream_; };