1 #include <utils/messageException.h>
2 #include <symbol/turingStyleMixedSymbolPatternParser.h>
6 std::set<char> symbols{left, right, separator};
7 if(symbols.size() != 3) {
9 "Left, right and separator should be distinct",
10 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
13 if(symbols.count(i) > 0) {
15 "Left, right and separator should not be ignore characters",
16 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
19 for(
char c: variablePrefix) {
20 if(symbols.count(c) > 0) {
22 "variablePrefix should not contain delimiters and separators",
23 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
25 if(ignore.count(c) > 0) {
27 "variablePrefix should not contain ignore characters",
28 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
31 if(variablePrefix.empty()) {
33 "variablePrefix should not be empty",
34 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
36 for(
char c: escapePrefix) {
37 if(symbols.count(c) > 0) {
39 "escapePrefix should not contain delimiters and separators",
40 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
42 if(ignore.count(c) > 0) {
44 "escapePrefix should not contain ignore characters",
45 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
48 if(escapePrefix.empty()) {
50 "escapePrefix should not be empty",
51 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
53 if(variablePrefix.substr(0, std::min(variablePrefix.size(), escapePrefix.size())) == escapePrefix.substr(0, std::min(variablePrefix.size(), escapePrefix.size()))) {
55 "variablePrefix should not be a prefix of escapePrefix, or conversely.",
56 left, right, separator, blank, ignore, variablePrefix, escapePrefix);
66 left(left), right(right), separator(separator), blank(blank), ignore(ignore), variablePrefix(variablePrefix), escapePrefix(escapePrefix) {
71 std::vector <Token> tokens =
tokenize(pattern);
74 if(tokens.size() == 1 && std::get<TokenKind>(tokens[0]) ==
TokenKind::EOS) {
77 if(tokens.size() == 2 && std::get<TokenKind>(tokens[0]) ==
TokenKind::ANY &&
81 if(tokens.size() == 2 && std::get<TokenKind>(tokens[0]) ==
TokenKind::TRUE &&
86 typedef std::function<std::pair<SymbolPattern, size_t>(
void)> parser;
87 parser parse_pattern =
89 ?
static_cast<parser
>([
this, &pattern, &tokens = std::as_const(
91 :
static_cast<parser
>([
this, &pattern, &tokens = std::as_const(
94 auto[parsed, position] = parse_pattern();
96 if(position != tokens.size() - 1) {
97 using Utils::Debug::operator<<;
99 ss <<
"parsed:" << parsed;
103 using Utils::Debug::operator<<;
104 std::stringstream ss;
105 ss <<
"parsed:" << parsed;
113 size_t nodeLen = variablePrefix.size();
114 size_t prefixLen = variablePrefix.size();
115 if(nodeLen < prefixLen) {
116 return {
false, node};
118 if(variablePrefix == node.substr(0, prefixLen)) {
119 return {
true, node.substr(prefixLen)};
121 return {
false, node};
125 std::vector <std::string> symbols;
126 std::vector <std::string> keys;
128 std::function<void()> push_ident = [
this, &pattern, &tokens, &keys, &symbols, &position]() {
129 std::string ident =
sub(pattern, tokens[position]);
132 keys.push_back(content);
134 symbols.push_back(content);
140 using Utils::Debug::operator<<;
141 std::stringstream ss;
148 throw make_exception(
"Expected left parenthesis.");
155 symbols.push_back(blank);
157 std::stringstream ss;
158 ss <<
"Expected first identifier or none in negative pattern. Got " << tokens[position];
159 throw make_exception(ss.str());
167 throw make_exception(
"Expected separator.");
172 symbols.push_back(blank);
174 throw make_exception(
"Expected identifier or none after a separator in a negative pattern.");
179 throw make_exception(
"Expected right parenthesis.");
183 throw make_exception(
"Expected EOS.");
185 if(symbols.empty() && keys.empty())
186 throw make_exception(
"This should not happen. At least one identifier is required.");
188 return std::make_pair(
190 std::set < std::string > {symbols.begin(), symbols.end()},
191 std::set < std::string > {keys.begin(), keys.end()},
198 std::vector <std::string> symbols;
199 std::vector <std::string> keys;
201 std::function<void()> push_ident = [
this, &pattern, &tokens, &keys, &symbols, &position]() {
202 std::string ident =
sub(pattern, tokens[position]);
205 keys.push_back(content);
207 symbols.push_back(content);
213 using Utils::Debug::operator<<;
214 std::stringstream ss;
215 ss << message << std::endl;
224 symbols.push_back(blank);
226 std::stringstream ss;
227 ss <<
"Expected first identifier or none in positive pattern. Got " << tokens[position];
228 throw make_exception(ss.str());
235 throw make_exception(
"Expected separator.");
240 symbols.push_back(blank);
242 throw make_exception(
"Expected identifier or none after separator in positive pattern.");
247 throw make_exception(
"Expected EOS.");
249 if(symbols.empty() && keys.empty())
250 throw make_exception(
"This should not happen. At least one identifier is required.");
253 return std::make_pair(
255 std::set < std::string > {symbols.begin(), symbols.end()},
256 std::set < std::string > {keys.begin(), keys.end()},
264 std::tie(std::ignore, begin, end) = token;
265 size_t len = end - begin + 1;
266 return pattern.substr(begin, len);
270 std::vector <Token> tokens;
277 start = std::get<2>(t) + 1;
283 for(; start < pattern.size() && ignore.count(pattern[start]) != 0; ++start);
284 if(start == pattern.size())
286 if(pattern[start] == left)
288 if(pattern[start] == right)
290 if(pattern[start] == separator)
293 for(end = start; end < pattern.size() && ignore.count(pattern[end]) == 0 && pattern[end] != left &&
294 pattern[end] != right && pattern[end] != separator; ++end);
300 return std::optional<Token>(std::nullopt);
302 std::string name =
sub(pattern, token);
303 if(name.size() >= escapePrefix.size() && name.substr(0, escapePrefix.size()) == escapePrefix) {
304 return std::make_optional(std::make_tuple(
TokenKind::IDENT, std::get<1>(token) + escapePrefix.size(), std::get<2>(token)));
308 return std::make_optional(std::make_tuple(
TokenKind::NONE, std::get<1>(token), std::get<2>(token)));
310 return std::make_optional(std::make_tuple(
TokenKind::NON, std::get<1>(token), std::get<2>(token)));
312 return std::make_optional(std::make_tuple(
TokenKind::ANY, std::get<1>(token), std::get<2>(token)));
314 return std::make_optional(std::make_tuple(
TokenKind::TRUE, std::get<1>(token), std::get<2>(token)));
315 return std::optional<Token>(std::nullopt);
319 for(
size_t i = 0; i < tokens.size(); ++i) {
320 const Token &token = tokens[i];
323 tokens[i] = new_token.value();