You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.5 KiB
115 lines
3.5 KiB
#include <protocol/token.hpp>
|
|
#include <util.hpp>
|
|
|
|
using namespace std;
|
|
using namespace util;
|
|
|
|
const bool debug = false;
|
|
|
|
namespace protocol::token {
|
|
|
|
std::string compose(const list_t& tokens) {
|
|
return join(tokens, '|');
|
|
}
|
|
|
|
list_t decompose(const std::string& input, size_t max_tokens) {
|
|
return split(input, '|', max_tokens);
|
|
}
|
|
|
|
pattern_t::pattern_t() {}
|
|
|
|
pattern_t::pattern_t(list_t tokens, bool wildcard) : wildcard(wildcard) {
|
|
for(auto index = 0; index < tokens.size(); ++index) {
|
|
auto token = tokens[index];
|
|
if(!wildcard || token != "*") {
|
|
this->emplace(index, tokens[index]);
|
|
}
|
|
}
|
|
}
|
|
|
|
pattern_t::pattern_t(string input, bool wildcard) : pattern_t(split(input, '|'), wildcard) {}
|
|
|
|
list_t pattern_t::token_list() const {
|
|
list_t output;
|
|
for(auto element = begin(); element != end(); ++element) {
|
|
output.push_back(element->second);
|
|
}
|
|
return output;
|
|
}
|
|
|
|
ostream& operator<<(typeof(cout)& out, const pattern_t& pattern) {
|
|
return out << join(pattern.token_list(), '|') << "<wildcard=" << pattern.wildcard << ">";
|
|
}
|
|
|
|
bool operator<(const pattern_t& l, const pattern_t& r) {
|
|
debug && cerr << "Checking if " << l << " < " << r << endl;
|
|
|
|
if(l == r) {
|
|
debug && cerr << "Not less because left equals right" << endl;
|
|
return false;
|
|
}
|
|
|
|
if(l.size() < r.size()) {
|
|
debug && cerr << "Less because right has more elements" << endl;
|
|
return true;
|
|
}
|
|
|
|
for(auto le = l.begin(); le != l.end(); ++le) {
|
|
if(r.count(le->first) == 0) {
|
|
debug && cerr << "Not less because right is missing " << le->first << " -> " << le->second << endl;
|
|
return false;
|
|
}
|
|
|
|
if(le->second < r.at(le->first)) {
|
|
debug && cerr << "Not less because " << le->second << " < " << r.at(le->first) << endl;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool operator==(const pattern_t& l, const pattern_t& r) {
|
|
debug && cerr << "Checking if " << l << " == " << r << endl;
|
|
|
|
const pattern_t *subset, *superset;
|
|
if(r.wildcard == l.wildcard) {
|
|
debug && cerr << "Left and right are both (not) wildcards" << endl;
|
|
if(l.size() != r.size()) {
|
|
debug && cerr << "Not equal because sizes are unequal" << endl;
|
|
return false;
|
|
} else {
|
|
subset = &l;
|
|
superset = &r;
|
|
}
|
|
} else if(l.wildcard) {
|
|
debug && cerr << "Left is wildcard" << endl;
|
|
subset = &l;
|
|
superset = &r;
|
|
} else {
|
|
debug && cerr << "Right is wildcard" << endl;
|
|
subset = &r;
|
|
superset = &l;
|
|
}
|
|
|
|
for(auto le : *subset) {
|
|
if(superset->count(le.first) == 0) {
|
|
debug && cerr << "Not equal because " << le.first << " -> " << le.second << " is missing in superset" << endl;
|
|
return false;
|
|
}
|
|
|
|
auto rv = superset->at(le.first);
|
|
|
|
if(rv != le.second) {
|
|
debug && cerr << "Not equal because " << le.first << " -> " << le.second << " != " << rv << " in superset" << endl;
|
|
return false;
|
|
}
|
|
|
|
debug && cerr << le.first << " -> " << le.second << " == " << rv << " in superset" << endl;
|
|
}
|
|
|
|
debug && cerr << "Patterns match" << endl;
|
|
|
|
return true;
|
|
}
|
|
} |