codex
Loading...
Searching...
No Matches
parser.hpp
Go to the documentation of this file.
1#ifndef CODEX_LUA_PARSER_H
2#define CODEX_LUA_PARSER_H
3
4#include "lua.hpp"
5#include "lexer.hpp"
6
7struct state {
8 struct item {
10 std::size_t level, str_b, str_e;
11 constexpr std::string_view name(std::string_view s) const;
12 };
13 std::string_view s, orig_s;
14 std::size_t n, level;
15 bool ok;
16 std::array<item, MAX> v;
17 constexpr state push(node n, std::string_view s);
18 constexpr state push(node n, std::string_view name, std::string_view s);
19};
20
21inline constexpr std::string_view state::item::name(std::string_view s) const {
22 return s.substr(this->str_b, this->str_e - this->str_b);
23}
24
25inline constexpr state state::push(node n_, std::string_view s_) {
26 return this->push(n_, this->orig_s.substr(0, 0), s_);
27}
28
29inline constexpr state state::push(
30 node n_, std::string_view name, std::string_view s_)
31{
32 state ret = *this;
33 ret.s = s_;
34 const auto b = begin(this->orig_s);
35 ret.v[ret.n] = {
36 .n = n_,
37 .level = this->level,
38 .str_b = static_cast<std::size_t>(std::distance(b, begin(name))),
39 .str_e = static_cast<std::size_t>(std::distance(b, end(name))),
40 };
41 ++ret.n;
42 return ret;
43}
44
45constexpr state parse_expression(state s);
46constexpr state parse_ident(state s, std::string_view v = "");
47constexpr state parse_number(state s);
48constexpr state parse_string(state s);
49constexpr state parse_table(state s);
50constexpr state parse_table_item(state s);
51
52constexpr state parse_ident(state s, std::string_view v) {
53 s.s = ignore_interm(s.s);
54 const auto i = std::ranges::find_if_not(s.s, set_contains<IDENT1>);
55 if(i == begin(s.s))
56 throw "invalid identifier";
57 const auto name = std::string_view{begin(s.s), i};
58 if(!v.empty() && v != name)
59 throw "unexpected identifier";
60 return s.push(node::identifier, name, {i, end(s.s)});
61}
62
64 s.s = ignore_interm(s.s);
65 std::string_view name = s.s;
66 s.s = consume_set<DIGITS>(s.s);
67 name = {begin(name), begin(s.s)};
68 return s.push(node::number, name, s.s);
69}
70
72 s.s = ignore_interm(s.s);
73 s.s = consume(s.s, "\"");
74 std::string_view name = s.s;
75 s.s = consume_set_comp<"\"">(s.s);
76 name = {begin(name), begin(s.s)};
77 s.s = consume(s.s, "\"");
78 return s.push(node::string, name, s.s);
79}
80
82 s.s = ignore_interm(s.s);
83// while(!s.s.empty()) {
84 if(const char c = s.s[0]; set_contains<IDENT0>(c))
85 s = parse_ident(s);
86 else if(set_contains<DIGITS>(c))
87 s = parse_number(s);
88 else if(c == '"')
89 s = parse_string(s);
90 else if(c == '{')
91 s = parse_table(s);
92 else
93 throw "invalid expression";
94// }
95 return s;
96}
97
99 s = s.push(node::table_begin, s.s);
100 ++s.level;
101 s.s = ignore_interm(s.s);
102 s.s = consume(s.s, "{");
103 do {
105 s.s = ignore_interm(s.s);
106 } while(s.s[0] != '}');
107 --s.level;
108 s.s = consume(s.s, "}");
109 s = s.push(node::table_end, s.s);
110 return s;
111}
112
114 s = s.push(node::table_key, s.s);
115 ++s.level;
116 s.s = ignore_interm(s.s);
117 if(s.s[0] == '}')
118 return s;
119 s = parse_ident(s);
120 --s.level;
121 s.s = ignore_interm(s.s);
122 if(const char c = s.s[0]; c == '}')
123 return s;
124 else if(c == ',') {
125 s.s = consume(s.s, ",");
126 return s;
127 }
128 s.s = consume(ignore_interm(s.s), "=");
129 s = s.push(node::table_value, s.s);
130 ++s.level;
132 --s.level;
133 s.s = ignore_interm(s.s);
134 if(s.s[0] == ',')
135 s.s = s.s.substr(1);
136 return s;
137}
138
139template<fixed_string s>
140struct parser {
141 static constexpr auto input = s;
142 struct output {
143 std::size_t n;
144 std::array<state::item, MAX> v;
145 } output;
146 bool ok;
147};
148
149template<fixed_string s>
150constexpr auto parse(void) {
151 state state = {.s = s, .orig_s = s, .ok = true};
152 state = parse_ident(state, "return");
155 if(!state.s.empty())
156 throw "trailing content";
157 parser<s> ret = {.output = {.n = state.n}, .ok = state.ok};
158 std::ranges::copy(state.v, begin(ret.output.v));
159 return ret;
160}
161
162#endif
constexpr std::string_view consume_set(std::string_view s)
Definition lexer.hpp:47
constexpr bool set_contains(char c)
Definition lexer.hpp:36
constexpr std::string_view ignore_interm(std::string_view s)
Definition lexer.hpp:17
constexpr std::string_view consume(std::string_view s, std::string_view c)
Definition lexer.hpp:29
constexpr std::string_view consume_set_comp(std::string_view s)
Definition lexer.hpp:52
constexpr state parse_expression(state s)
Definition parser.hpp:81
constexpr state parse_string(state s)
Definition parser.hpp:71
constexpr state parse_table(state s)
Definition parser.hpp:98
constexpr state parse_table_item(state s)
Definition parser.hpp:113
constexpr state parse_ident(state s, std::string_view v="")
Definition parser.hpp:52
constexpr state parse_number(state s)
Definition parser.hpp:63
constexpr auto parse(void)
Definition parser.hpp:150
Definition mult_inh.c:26
Definition mult_inh.c:27
Definition list.h:6
Definition parser.hpp:142
std::array< state::item, MAX > v
Definition parser.hpp:144
std::size_t n
Definition parser.hpp:143
Definition parser.hpp:140
struct parser::output output
bool ok
Definition parser.hpp:146
Definition parser.hpp:8
node n
Definition parser.hpp:9
constexpr std::string_view name(std::string_view s) const
Definition parser.hpp:21
std::size_t str_e
Definition parser.hpp:10
std::size_t level
Definition parser.hpp:10
std::size_t str_b
Definition parser.hpp:10
Definition parser.hpp:7
std::size_t n
Definition parser.hpp:14
constexpr state push(node n, std::string_view s)
Definition parser.hpp:25
bool ok
Definition parser.hpp:15
std::size_t level
Definition parser.hpp:14
std::array< item, MAX > v
Definition parser.hpp:16
std::string_view s
Definition parser.hpp:13
std::string_view orig_s
Definition parser.hpp:13
constexpr fixed_string s
Definition test.cpp:6