1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#pragma once
#include "tokens.hpp"
#include "hocon/config_exception.hpp"
#include <hocon/config_syntax.hpp>
#include <boost/nowide/fstream.hpp>
#include <vector>
#include <queue>
#include <string>
namespace hocon {
// This exception should not leave this file
class problem_exception : std::runtime_error {
public:
problem_exception(problem prob);
problem const& get_problem() const;
private:
problem _problem;
};
class iterator {
public:
virtual bool has_next() = 0;
virtual shared_token next() = 0;
};
template <typename iter>
class iterator_wrapper : public iterator {
public:
iterator_wrapper(iter begin, iter end)
: _cur(begin), _end(end) { }
bool has_next() override {
return _cur != _end;
}
shared_token next() override {
return *_cur++;
}
private:
iter _cur;
iter _end;
};
class token_iterator : public iterator {
public:
token_iterator(shared_origin origin, std::unique_ptr<std::istream> input, bool allow_comments);
token_iterator(shared_origin origin, std::unique_ptr<std::istream> input, config_syntax flavor);
bool has_next() override;
shared_token next() override;
static std::string render(token_list tokens);
private:
class whitespace_saver {
public:
whitespace_saver();
void add(char c);
shared_token check(token_type type, shared_origin base_origin, int line_number);
private:
shared_token next_is_not_simple_value(shared_origin base_origin, int line_number);
shared_token next_is_simple_value(shared_origin origin, int line_number);
shared_token create_whitespace_token(shared_origin base_origin, int line_number);
std::string _whitespace;
bool _last_token_was_simple_value;
};
bool start_of_comment(char c);
shared_token pull_comment(char first_char);
/** Get next char, skipping newline whitespace */
char next_char_after_whitespace(whitespace_saver& saver);
/**
* The rules here are intended to maximize convenience while
* avoiding confusion with real valid JSON. Basically anything
* that parses as JSON is treated the JSON way and otherwise
* we assume it's a string and let the parser sort it out.
*/
shared_token pull_unquoted_text();
shared_token pull_number(char first_char);
/**
* @param parsed The string with the escape sequence parsed.
* @param original The string with the escape sequence left as in the original text
*/
void pull_escape_sequence(std::string& parsed, std::string& original);
void append_triple_quoted_string(std::string& parsed, std::string& original);
shared_token pull_quoted_string();
shared_token const& pull_plus_equals();
shared_token pull_substitution();
shared_token pull_next_token(whitespace_saver& saver);
void queue_next_token();
static bool is_simple_value(token_type type);
static std::string as_string(char c);
static shared_origin line_origin(shared_origin base_origin, int line_number);
shared_origin _origin;
std::unique_ptr<std::istream> _input;
bool _allow_comments;
int _line_number;
shared_origin _line_origin;
std::queue<shared_token> _tokens;
whitespace_saver _whitespace_saver;
};
class single_token_iterator : public iterator {
public:
single_token_iterator(shared_token token);
bool has_next() override;
shared_token next() override;
private:
shared_token _token;
bool _has_next;
};
class token_list_iterator : public iterator {
public:
token_list_iterator(token_list tokens);
bool has_next() override;
shared_token next() override;
private:
token_list _tokens;
int _index;
};
} // namespace hocon
|