blob: 13beec4932b9642f70466e026decdecc8fe5ccf5 (
plain)
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
|
#ifndef GRAMMAR_HH
#define GRAMMAR_HH
#include "errors.hh"
#include "io.hh"
#include <cstdint>
#include <span>
#include <string>
#include <vector>
namespace grammar {
struct Element;
struct Symbol {
enum class Type : uint8_t {
// value == terminal, as UTF-8
kTerminal,
// element != nullptr
kNonTerminal,
// char_class != 0
kCharacterClass,
};
Type type;
enum class Optional : uint8_t {
// Symbol is NOT optional.
kRequired,
// Symbol is optional.
kZeroOrOne,
// Symbol is optional and can repeat.
kZeroOrMore,
// Symbol should be excluded from previous symbol.
// Example: InputCharacter but not * or /
kExcluded,
};
Optional optional{Optional::kRequired};
uint8_t char_class{0};
Element const* element{nullptr};
std::string value;
};
struct Definition {
std::vector<Symbol> symbols;
};
struct Element {
std::string name;
std::vector<Definition> definitions;
};
class Grammar {
public:
virtual ~Grammar() = default;
[[nodiscard]]
virtual Element const& root() const = 0;
protected:
Grammar() = default;
Grammar(Grammar const&) = delete;
Grammar& operator=(Grammar const&) = delete;
};
std::unique_ptr<Grammar> load(std::unique_ptr<io::Reader> reader,
std::vector<std::string> const& character_classes,
src::Errors& errors);
} // namespace grammar
#endif // GRAMMAR_HH
|