mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-21 01:42:15 -07:00
Update peglib.h
This commit is contained in:
parent
c19d0355eb
commit
4288cd0703
4 changed files with 3722 additions and 2454 deletions
|
|
@ -65,13 +65,13 @@ std::once_flag init;
|
||||||
|
|
||||||
static void setupParserRules()
|
static void setupParserRules()
|
||||||
{
|
{
|
||||||
auto passthru = [](const peg::SemanticValues &sv) -> Filter { return !sv.empty() ? sv[0].get<Filter>() : nullptr; };
|
auto passthru = [](const peg::SemanticValues &sv) -> Filter { return !sv.empty() ? std::any_cast<Filter>(sv[0]) : nullptr; };
|
||||||
|
|
||||||
search["Start"] = passthru;
|
search["Start"] = passthru;
|
||||||
search["QueryPartList"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["QueryPartList"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
return [=](CardData x) {
|
return [=](CardData x) {
|
||||||
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
||||||
if (!sv[i].get<Filter>()(x))
|
if (!std::any_cast<Filter>(sv[i])(x))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -80,7 +80,7 @@ static void setupParserRules()
|
||||||
search["ComplexQueryPart"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["ComplexQueryPart"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
return [=](CardData x) {
|
return [=](CardData x) {
|
||||||
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
||||||
if (sv[i].get<Filter>()(x))
|
if (std::any_cast<Filter>(sv[i])(x))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -89,15 +89,15 @@ static void setupParserRules()
|
||||||
search["SomewhatComplexQueryPart"] = passthru;
|
search["SomewhatComplexQueryPart"] = passthru;
|
||||||
search["QueryPart"] = passthru;
|
search["QueryPart"] = passthru;
|
||||||
search["NotQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["NotQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
Filter dependent = sv[0].get<Filter>();
|
Filter dependent = std::any_cast<Filter>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return !dependent(x); };
|
return [=](CardData x) -> bool { return !dependent(x); };
|
||||||
};
|
};
|
||||||
search["TypeQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["TypeQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
StringMatcher matcher = sv[0].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return matcher(x->getCardType()); };
|
return [=](CardData x) -> bool { return matcher(x->getCardType()); };
|
||||||
};
|
};
|
||||||
search["SetQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["SetQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
StringMatcher matcher = sv[0].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||||
return [=](CardData x) -> bool {
|
return [=](CardData x) -> bool {
|
||||||
for (const auto &set : x->getSets().keys()) {
|
for (const auto &set : x->getSets().keys()) {
|
||||||
if (matcher(set))
|
if (matcher(set))
|
||||||
|
|
@ -107,29 +107,27 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
search["RarityQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["RarityQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
StringMatcher matcher = sv[0].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||||
return [=](const CardData &x) -> bool {
|
return [=](CardData x) -> bool {
|
||||||
for (const auto &cardInfoPerSetList : x->getSets().values()) {
|
for (const auto &set : x->getSets().values()) {
|
||||||
for (const auto &set : cardInfoPerSetList) {
|
if (matcher(set.getProperty("rarity")))
|
||||||
if (matcher(set.getProperty("rarity")))
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
search["FormatQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["FormatQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
if (sv.choice() == 0) {
|
if (sv.choice() == 0) {
|
||||||
QString format = sv[0].get<QString>();
|
QString format = std::any_cast<QString>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return x->getProperty(QString("format-%1").arg(format)) == "legal"; };
|
return [=](CardData x) -> bool { return x->getProperty(QString("format-%1").arg(format)) == "legal"; };
|
||||||
} else {
|
} else {
|
||||||
QString format = sv[1].get<QString>();
|
QString format = std::any_cast<QString>(sv[1]);
|
||||||
QString legality = sv[0].get<QString>();
|
QString legality = std::any_cast<QString>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return x->getProperty(QString("format-%1").arg(format)) == legality; };
|
return [=](CardData x) -> bool { return x->getProperty(QString("format-%1").arg(format)) == legality; };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search["Legality"] = [](const peg::SemanticValues &sv) -> QString {
|
search["Legality"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
switch (tolower(sv.str()[0])) {
|
switch (tolower(std::string(sv.sv())[0])) {
|
||||||
case 'l':
|
case 'l':
|
||||||
return "legal";
|
return "legal";
|
||||||
case 'b':
|
case 'b':
|
||||||
|
|
@ -142,8 +140,8 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
|
|
||||||
search["Format"] = [](const peg::SemanticValues &sv) -> QString {
|
search["Format"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
if (sv.length() == 1) {
|
if (sv.size() == 1) {
|
||||||
switch (tolower(sv.str()[0])) {
|
switch (tolower(std::string(sv.sv())[0])) {
|
||||||
case 'm':
|
case 'm':
|
||||||
return "modern";
|
return "modern";
|
||||||
case 's':
|
case 's':
|
||||||
|
|
@ -160,15 +158,15 @@ static void setupParserRules()
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return QString::fromStdString(sv.str()).toLower();
|
return QString::fromStdString(std::string(sv.sv())).toLower();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search["StringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
search["StringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
||||||
if (sv.choice() == 0) {
|
if (sv.choice() == 0) {
|
||||||
auto target = sv[0].get<QString>();
|
auto target = std::any_cast<QString>(sv[0]);
|
||||||
return [=](const QString &s) { return s.split(" ").contains(target, Qt::CaseInsensitive); };
|
return [=](const QString &s) { return s.split(" ").contains(target, Qt::CaseInsensitive); };
|
||||||
} else {
|
} else {
|
||||||
auto target = sv[0].get<QStringList>();
|
auto target = std::any_cast<QStringList>(sv[0]);
|
||||||
return [=](const QString &s) {
|
return [=](const QString &s) {
|
||||||
for (const QString &str : target) {
|
for (const QString &str : target) {
|
||||||
if (s.split(" ").contains(str, Qt::CaseInsensitive)) {
|
if (s.split(" ").contains(str, Qt::CaseInsensitive)) {
|
||||||
|
|
@ -182,14 +180,14 @@ static void setupParserRules()
|
||||||
|
|
||||||
search["String"] = [](const peg::SemanticValues &sv) -> QString {
|
search["String"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
if (sv.choice() == 0) {
|
if (sv.choice() == 0) {
|
||||||
return QString::fromStdString(sv.str());
|
return QString::fromStdString(std::string(sv.sv()));
|
||||||
} else {
|
} else {
|
||||||
return QString::fromStdString(sv.token(0));
|
return QString::fromStdString(std::string(sv.token(0)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search["FlexStringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
search["FlexStringValue"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
||||||
if (sv.choice() != 1) {
|
if (sv.choice() != 1) {
|
||||||
auto target = sv[0].get<QStringList>();
|
auto target = std::any_cast<QStringList>(sv[0]);
|
||||||
return [=](const QString &s) {
|
return [=](const QString &s) {
|
||||||
for (const QString &str : target) {
|
for (const QString &str : target) {
|
||||||
if (s.split(" ").contains(str, Qt::CaseInsensitive)) {
|
if (s.split(" ").contains(str, Qt::CaseInsensitive)) {
|
||||||
|
|
@ -199,24 +197,31 @@ static void setupParserRules()
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
auto target = sv[0].get<QString>();
|
auto target = std::any_cast<QString>(sv[0]);
|
||||||
return [=](const QString &s) { return s.split(" ").contains(target, Qt::CaseInsensitive); };
|
return [=](const QString &s) { return s.split(" ").contains(target, Qt::CaseInsensitive); };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search["CompactStringSet"] = search["StringList"] = [](const peg::SemanticValues &sv) -> QStringList {
|
search["CompactStringSet"] = [](const peg::SemanticValues &sv) -> QStringList {
|
||||||
QStringList result;
|
QStringList result;
|
||||||
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
||||||
result.append(sv[i].get<QString>());
|
result.append(std::any_cast<QString>(sv[i]));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
search["StringList"] = [](const peg::SemanticValues &sv) -> QStringList {
|
||||||
|
QStringList result;
|
||||||
|
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
||||||
|
result.append(std::any_cast<QString>(sv[i]));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
search["StringListString"] = [](const peg::SemanticValues &sv) -> QString {
|
search["StringListString"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
return QString::fromStdString(sv.str());
|
return QString::fromStdString(std::string(sv.sv()));
|
||||||
};
|
};
|
||||||
|
|
||||||
search["NumericExpression"] = [](const peg::SemanticValues &sv) -> NumberMatcher {
|
search["NumericExpression"] = [](const peg::SemanticValues &sv) -> NumberMatcher {
|
||||||
auto arg = sv[1].get<int>();
|
auto arg = std::any_cast<int>(sv[1]);
|
||||||
auto op = sv[0].get<QString>();
|
auto op = std::any_cast<QString>(sv[0]);
|
||||||
|
|
||||||
if (op == ">")
|
if (op == ">")
|
||||||
return [=](int s) { return s > arg; };
|
return [=](int s) { return s > arg; };
|
||||||
|
|
@ -236,15 +241,15 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
|
|
||||||
search["NumericValue"] = [](const peg::SemanticValues &sv) -> int {
|
search["NumericValue"] = [](const peg::SemanticValues &sv) -> int {
|
||||||
return QString::fromStdString(sv.str()).toInt();
|
return QString::fromStdString(std::string(sv.sv())).toInt();
|
||||||
};
|
};
|
||||||
|
|
||||||
search["NumericOperator"] = [](const peg::SemanticValues &sv) -> QString {
|
search["NumericOperator"] = [](const peg::SemanticValues &sv) -> QString {
|
||||||
return QString::fromStdString(sv.str());
|
return QString::fromStdString(std::string(sv.sv()));
|
||||||
};
|
};
|
||||||
|
|
||||||
search["RegexString"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
search["RegexString"] = [](const peg::SemanticValues &sv) -> StringMatcher {
|
||||||
auto target = sv[0].get<QString>();
|
auto target = std::any_cast<QString>(sv[0]);
|
||||||
return [=](const QString &s) {
|
return [=](const QString &s) {
|
||||||
auto sanitizedTarget = QString(target);
|
auto sanitizedTarget = QString(target);
|
||||||
sanitizedTarget.replace("\\\"", "\"");
|
sanitizedTarget.replace("\\\"", "\"");
|
||||||
|
|
@ -254,17 +259,17 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
|
|
||||||
search["OracleQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["OracleQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
StringMatcher matcher = sv[0].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||||
return [=](CardData x) { return matcher(x->getText()); };
|
return [=](CardData x) { return matcher(x->getText()); };
|
||||||
};
|
};
|
||||||
|
|
||||||
search["ColorQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["ColorQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
QString parts;
|
QString parts;
|
||||||
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
for (int i = 0; i < static_cast<int>(sv.size()); ++i) {
|
||||||
parts += sv[i].get<char>();
|
parts += std::any_cast<char>(sv[i]);
|
||||||
}
|
}
|
||||||
bool idenity = sv.tokens[0].first[0] != 'i';
|
bool idenity = sv.tokens[0][0] != 'i';
|
||||||
if (sv.tokens[1].first[0] == ':') {
|
if (sv.tokens[1][0] == ':') {
|
||||||
return [=](CardData x) {
|
return [=](CardData x) {
|
||||||
QString match = idenity ? x->getColors() : x->getProperty("coloridentity");
|
QString match = idenity ? x->getColors() : x->getProperty("coloridentity");
|
||||||
if (parts.contains("m") && match.length() < 2) {
|
if (parts.contains("m") && match.length() < 2) {
|
||||||
|
|
@ -306,40 +311,40 @@ static void setupParserRules()
|
||||||
};
|
};
|
||||||
|
|
||||||
search["CMCQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["CMCQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
NumberMatcher matcher = sv[0].get<NumberMatcher>();
|
NumberMatcher matcher = std::any_cast<NumberMatcher>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return matcher(x->getProperty("cmc").toInt()); };
|
return [=](CardData x) -> bool { return matcher(x->getProperty("cmc").toInt()); };
|
||||||
};
|
};
|
||||||
search["PowerQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["PowerQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
NumberMatcher matcher = sv[0].get<NumberMatcher>();
|
NumberMatcher matcher = std::any_cast<NumberMatcher>(sv[0]);
|
||||||
return [=](CardData x) -> bool { return matcher(x->getPowTough().split("/")[0].toInt()); };
|
return [=](CardData x) -> bool { return matcher(x->getPowTough().split("/")[0].toInt()); };
|
||||||
};
|
};
|
||||||
search["ToughnessQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["ToughnessQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
NumberMatcher matcher = sv[0].get<NumberMatcher>();
|
NumberMatcher matcher = std::any_cast<NumberMatcher>(sv[0]);
|
||||||
return [=](CardData x) -> bool {
|
return [=](CardData x) -> bool {
|
||||||
auto parts = x->getPowTough().split("/");
|
auto parts = x->getPowTough().split("/");
|
||||||
return matcher(parts.length() == 2 ? parts[1].toInt() : 0);
|
return matcher(parts.length() == 2 ? parts[1].toInt() : 0);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
search["FieldQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["FieldQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
QString field = sv[0].get<QString>();
|
QString field = std::any_cast<QString>(sv[0]);
|
||||||
if (sv.choice() == 0) {
|
if (sv.choice() == 0) {
|
||||||
StringMatcher matcher = sv[1].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[1]);
|
||||||
return [=](CardData x) -> bool { return x->hasProperty(field) ? matcher(x->getProperty(field)) : false; };
|
return [=](CardData x) -> bool { return x->hasProperty(field) ? matcher(x->getProperty(field)) : false; };
|
||||||
} else {
|
} else {
|
||||||
NumberMatcher matcher = sv[1].get<NumberMatcher>();
|
NumberMatcher matcher = std::any_cast<NumberMatcher>(sv[1]);
|
||||||
return [=](CardData x) -> bool {
|
return [=](CardData x) -> bool {
|
||||||
return x->hasProperty(field) ? matcher(x->getProperty(field).toInt()) : false;
|
return x->hasProperty(field) ? matcher(x->getProperty(field).toInt()) : false;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
search["GenericQuery"] = [](const peg::SemanticValues &sv) -> Filter {
|
||||||
StringMatcher matcher = sv[0].get<StringMatcher>();
|
StringMatcher matcher = std::any_cast<StringMatcher>(sv[0]);
|
||||||
return [=](CardData x) { return matcher(x->getName()); };
|
return [=](CardData x) { return matcher(x->getName()); };
|
||||||
};
|
};
|
||||||
|
|
||||||
search["Color"] = [](const peg::SemanticValues &sv) -> char { return "WUBRGU"[sv.choice()]; };
|
search["Color"] = [](const peg::SemanticValues &sv) -> char { return "WUBRGU"[sv.choice()]; };
|
||||||
search["ColorEx"] = [](const peg::SemanticValues &sv) -> char {
|
search["ColorEx"] = [](const peg::SemanticValues &sv) -> char {
|
||||||
return sv.choice() == 0 ? sv[0].get<char>() : *sv.c_str();
|
return sv.choice() == 0 ? std::any_cast<char>(sv[0]) : *std::string(sv.sv()).c_str();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -362,9 +367,9 @@ FilterString::FilterString(const QString &expr)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
search.log = [&](size_t /*ln*/, size_t col, const std::string &msg) {
|
search.set_logger([&](size_t /*ln*/, size_t col, const std::string &msg) {
|
||||||
_error = QString("Error at position %1: %2").arg(col).arg(QString::fromStdString(msg));
|
_error = QString("Error at position %1: %2").arg(col).arg(QString::fromStdString(msg));
|
||||||
};
|
});
|
||||||
|
|
||||||
if (!search.parse(ba.data(), result)) {
|
if (!search.parse(ba.data(), result)) {
|
||||||
qDebug().nospace() << "FilterString error for " << expr << "; " << qPrintable(_error);
|
qDebug().nospace() << "FilterString error for " << expr << "; " << qPrintable(_error);
|
||||||
|
|
|
||||||
|
|
@ -51,9 +51,9 @@ double Expression::eval(const peg::Ast &ast)
|
||||||
{
|
{
|
||||||
const auto &nodes = ast.nodes;
|
const auto &nodes = ast.nodes;
|
||||||
if (ast.name == "NUMBER") {
|
if (ast.name == "NUMBER") {
|
||||||
return stod(ast.token);
|
return stod(std::string(ast.token));
|
||||||
} else if (ast.name == "FUNCTION") {
|
} else if (ast.name == "FUNCTION") {
|
||||||
QString name = QString::fromStdString(nodes[0]->token);
|
QString name = QString::fromStdString(std::string(nodes[0]->token));
|
||||||
if (!fns.contains(name))
|
if (!fns.contains(name))
|
||||||
return 0;
|
return 0;
|
||||||
return fns[name](eval(*nodes[1]));
|
return fns[name](eval(*nodes[1]));
|
||||||
|
|
|
||||||
5688
common/lib/peglib.h
5688
common/lib/peglib.h
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue