File: tokenizer.hpp

package info (click to toggle)
cpp-hocon 0.3.0-1.2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,320 kB
  • sloc: cpp: 12,223; makefile: 4
file content (143 lines) | stat: -rw-r--r-- 4,162 bytes parent folder | download | duplicates (4)
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