PlaceholderParser: Implemented one_of() matching function:
1st parameter is the text to match against, the rest of the parameters are pattern to be matched: either strings, then the match is exact, or regex enclosed in // or regex string starting with ~ For example one_of("a", "a", "b") finds a in "a", "b" one_of("abc", /.*a.*/) matches "abc" using regular expression /.*a.*/
This commit is contained in:
parent
d152b67ce5
commit
7afabcde95
@ -587,7 +587,7 @@ namespace client
|
|||||||
param1.set_s(buf);
|
param1.set_s(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void regex_op(expr &lhs, boost::iterator_range<Iterator> &rhs, char op)
|
static void regex_op(const expr &lhs, boost::iterator_range<Iterator> &rhs, char op, expr &out)
|
||||||
{
|
{
|
||||||
const std::string *subject = nullptr;
|
const std::string *subject = nullptr;
|
||||||
if (lhs.type() == TYPE_STRING) {
|
if (lhs.type() == TYPE_STRING) {
|
||||||
@ -601,7 +601,7 @@ namespace client
|
|||||||
bool result = SLIC3R_REGEX_NAMESPACE::regex_match(*subject, SLIC3R_REGEX_NAMESPACE::regex(pattern));
|
bool result = SLIC3R_REGEX_NAMESPACE::regex_match(*subject, SLIC3R_REGEX_NAMESPACE::regex(pattern));
|
||||||
if (op == '!')
|
if (op == '!')
|
||||||
result = ! result;
|
result = ! result;
|
||||||
lhs.set_b(result);
|
out.set_b(result);
|
||||||
} catch (SLIC3R_REGEX_NAMESPACE::regex_error &ex) {
|
} catch (SLIC3R_REGEX_NAMESPACE::regex_error &ex) {
|
||||||
// Syntax error in the regular expression
|
// Syntax error in the regular expression
|
||||||
boost::throw_exception(qi::expectation_failure<Iterator>(
|
boost::throw_exception(qi::expectation_failure<Iterator>(
|
||||||
@ -609,8 +609,37 @@ namespace client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void regex_matches (expr &lhs, boost::iterator_range<Iterator> &rhs) { return regex_op(lhs, rhs, '='); }
|
static void regex_matches (expr &lhs, boost::iterator_range<Iterator> &rhs) { return regex_op(lhs, rhs, '=', lhs); }
|
||||||
static void regex_doesnt_match(expr &lhs, boost::iterator_range<Iterator> &rhs) { return regex_op(lhs, rhs, '!'); }
|
static void regex_doesnt_match(expr &lhs, boost::iterator_range<Iterator> &rhs) { return regex_op(lhs, rhs, '!', lhs); }
|
||||||
|
|
||||||
|
static void one_of_test_init(expr &out) {
|
||||||
|
out.set_b(false);
|
||||||
|
}
|
||||||
|
template<bool RegEx>
|
||||||
|
static void one_of_test(const expr &match, const expr &pattern, expr &out) {
|
||||||
|
if (! out.b()) {
|
||||||
|
if (match.type() != TYPE_STRING)
|
||||||
|
match.throw_exception("one_of(): First parameter (the string to match against) has to be a string value");
|
||||||
|
if (pattern.type() != TYPE_STRING)
|
||||||
|
match.throw_exception("one_of(): Pattern has to be a string value");
|
||||||
|
if (RegEx) {
|
||||||
|
try {
|
||||||
|
out.set_b(SLIC3R_REGEX_NAMESPACE::regex_match(match.s(), SLIC3R_REGEX_NAMESPACE::regex(pattern.s())));
|
||||||
|
} catch (SLIC3R_REGEX_NAMESPACE::regex_error &) {
|
||||||
|
// Syntax error in the regular expression
|
||||||
|
pattern.throw_exception("Regular expression compilation failed");
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
out.set_b(match.s() == pattern.s());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void one_of_test_regex(const expr &match, boost::iterator_range<Iterator> &pattern, expr &out) {
|
||||||
|
if (! out.b()) {
|
||||||
|
if (match.type() != TYPE_STRING)
|
||||||
|
match.throw_exception("one_of(): First parameter (the string to match against) has to be a string value");
|
||||||
|
regex_op(match, pattern, '=', out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void logical_op(expr &lhs, expr &rhs, char op)
|
static void logical_op(expr &lhs, expr &rhs, char op)
|
||||||
{
|
{
|
||||||
@ -1101,6 +1130,7 @@ namespace client
|
|||||||
{ "multiplicative_expression", "Expecting an expression." },
|
{ "multiplicative_expression", "Expecting an expression." },
|
||||||
{ "unary_expression", "Expecting an expression." },
|
{ "unary_expression", "Expecting an expression." },
|
||||||
{ "optional_parameter", "Expecting a closing brace or an optional parameter." },
|
{ "optional_parameter", "Expecting a closing brace or an optional parameter." },
|
||||||
|
{ "one_of_list", "Expecting a list of string patterns (simple text or rexep)" },
|
||||||
{ "variable_reference", "Expecting a variable reference."},
|
{ "variable_reference", "Expecting a variable reference."},
|
||||||
{ "is_nil_test", "Expecting a scalar variable reference."},
|
{ "is_nil_test", "Expecting a scalar variable reference."},
|
||||||
{ "variable", "Expecting a variable name."},
|
{ "variable", "Expecting a variable name."},
|
||||||
@ -1221,6 +1251,7 @@ namespace client
|
|||||||
qi::_a_type _a;
|
qi::_a_type _a;
|
||||||
qi::_b_type _b;
|
qi::_b_type _b;
|
||||||
qi::_r1_type _r1;
|
qi::_r1_type _r1;
|
||||||
|
qi::_r2_type _r2;
|
||||||
|
|
||||||
// Starting symbol of the grammer.
|
// Starting symbol of the grammer.
|
||||||
// The leading eps is required by the "expectation point" operator ">".
|
// The leading eps is required by the "expectation point" operator ">".
|
||||||
@ -1395,7 +1426,8 @@ namespace client
|
|||||||
[ px::bind(&expr<Iterator>::template digits<true>, _val, _2, _3) ]
|
[ px::bind(&expr<Iterator>::template digits<true>, _val, _2, _3) ]
|
||||||
| (kw["int"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::to_int, _1, _val) ]
|
| (kw["int"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::to_int, _1, _val) ]
|
||||||
| (kw["round"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::round, _1, _val) ]
|
| (kw["round"] > '(' > conditional_expression(_r1) > ')') [ px::bind(&FactorActions::round, _1, _val) ]
|
||||||
| (kw["is_nil"] > '(' > is_nil_test(_r1) > ')') [_val = _1]
|
| (kw["is_nil"] > '(' > is_nil_test(_r1) > ')') [ _val = _1 ]
|
||||||
|
| (kw["one_of"] > '(' > one_of(_r1) > ')') [ _val = _1 ]
|
||||||
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
|
| (strict_double > iter_pos) [ px::bind(&FactorActions::double_, _1, _2, _val) ]
|
||||||
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
|
| (int_ > iter_pos) [ px::bind(&FactorActions::int_, _1, _2, _val) ]
|
||||||
| (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]
|
| (kw[bool_] > iter_pos) [ px::bind(&FactorActions::bool_, _1, _2, _val) ]
|
||||||
@ -1404,6 +1436,20 @@ namespace client
|
|||||||
);
|
);
|
||||||
unary_expression.name("unary_expression");
|
unary_expression.name("unary_expression");
|
||||||
|
|
||||||
|
one_of = (unary_expression(_r1)[_a = _1] > one_of_list(_r1, _a))[_val = _2];
|
||||||
|
one_of.name("one_of");
|
||||||
|
one_of_list =
|
||||||
|
eps[px::bind(&expr<Iterator>::one_of_test_init, _val)] >
|
||||||
|
( ',' > *(
|
||||||
|
(
|
||||||
|
unary_expression(_r1)[px::bind(&expr<Iterator>::template one_of_test<false>, _r2, _1, _val)]
|
||||||
|
| (lit('~') > unary_expression(_r1))[px::bind(&expr<Iterator>::template one_of_test<true>, _r2, _1, _val)]
|
||||||
|
| regular_expression[px::bind(&expr<Iterator>::one_of_test_regex, _r2, _1, _val)]
|
||||||
|
) >> -lit(','))
|
||||||
|
| eps
|
||||||
|
);
|
||||||
|
one_of_list.name("one_of_list");
|
||||||
|
|
||||||
optional_parameter = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> (
|
optional_parameter = iter_pos[px::bind(&FactorActions::set_start_pos, _1, _val)] >> (
|
||||||
lit(')') [ px::bind(&FactorActions::noexpr, _val) ]
|
lit(')') [ px::bind(&FactorActions::noexpr, _val) ]
|
||||||
| (lit(',') > conditional_expression(_r1) > ')') [ _val = _1 ]
|
| (lit(',') > conditional_expression(_r1) > ')') [ _val = _1 ]
|
||||||
@ -1445,6 +1491,7 @@ namespace client
|
|||||||
("random")
|
("random")
|
||||||
("round")
|
("round")
|
||||||
("not")
|
("not")
|
||||||
|
("one_of")
|
||||||
("or")
|
("or")
|
||||||
("true");
|
("true");
|
||||||
|
|
||||||
@ -1466,6 +1513,8 @@ namespace client
|
|||||||
debug(additive_expression);
|
debug(additive_expression);
|
||||||
debug(multiplicative_expression);
|
debug(multiplicative_expression);
|
||||||
debug(unary_expression);
|
debug(unary_expression);
|
||||||
|
debug(one_of);
|
||||||
|
debug(one_of_list);
|
||||||
debug(optional_parameter);
|
debug(optional_parameter);
|
||||||
debug(variable_reference);
|
debug(variable_reference);
|
||||||
debug(variable);
|
debug(variable);
|
||||||
@ -1517,6 +1566,9 @@ namespace client
|
|||||||
qi::rule<Iterator, OptWithPos<Iterator>(const MyContext*), spirit_encoding::space_type> variable;
|
qi::rule<Iterator, OptWithPos<Iterator>(const MyContext*), spirit_encoding::space_type> variable;
|
||||||
// Evaluating whether a nullable variable is nil.
|
// Evaluating whether a nullable variable is nil.
|
||||||
qi::rule<Iterator, expr<Iterator>(const MyContext*), spirit_encoding::space_type> is_nil_test;
|
qi::rule<Iterator, expr<Iterator>(const MyContext*), spirit_encoding::space_type> is_nil_test;
|
||||||
|
// Evaluating "one of" list of patterns.
|
||||||
|
qi::rule<Iterator, expr<Iterator>(const MyContext*), qi::locals<expr<Iterator>>, spirit_encoding::space_type> one_of;
|
||||||
|
qi::rule<Iterator, expr<Iterator>(const MyContext*, const expr<Iterator> ¶m), spirit_encoding::space_type> one_of_list;
|
||||||
|
|
||||||
qi::rule<Iterator, std::string(const MyContext*), qi::locals<bool, bool>, spirit_encoding::space_type> if_else_output;
|
qi::rule<Iterator, std::string(const MyContext*), qi::locals<bool, bool>, spirit_encoding::space_type> if_else_output;
|
||||||
qi::rule<Iterator, std::string(const MyContext*), qi::locals<OptWithPos<Iterator>, int>, spirit_encoding::space_type> assignment_statement;
|
qi::rule<Iterator, std::string(const MyContext*), qi::locals<OptWithPos<Iterator>, int>, spirit_encoding::space_type> assignment_statement;
|
||||||
|
@ -113,6 +113,18 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
|
|||||||
SECTION("boolean expression parser: greater than or equal - false") { REQUIRE(! boolean_expression("12 >= 22")); }
|
SECTION("boolean expression parser: greater than or equal - false") { REQUIRE(! boolean_expression("12 >= 22")); }
|
||||||
SECTION("boolean expression parser: lower than or equal (same values) - true") { REQUIRE(boolean_expression("12 <= 12")); }
|
SECTION("boolean expression parser: lower than or equal (same values) - true") { REQUIRE(boolean_expression("12 <= 12")); }
|
||||||
SECTION("boolean expression parser: greater than or equal (same values) - true") { REQUIRE(boolean_expression("12 >= 12")); }
|
SECTION("boolean expression parser: greater than or equal (same values) - true") { REQUIRE(boolean_expression("12 >= 12")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"a\", \"a\", \"b\", \"c\")") { REQUIRE(boolean_expression("one_of(\"a\", \"a\", \"b\", \"c\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"b\", \"a\", \"b\", \"c\")") { REQUIRE(boolean_expression("one_of(\"b\", \"a\", \"b\", \"c\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"c\", \"a\", \"b\", \"c\")") { REQUIRE(boolean_expression("one_of(\"c\", \"a\", \"b\", \"c\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"d\", \"a\", \"b\", \"c\")") { REQUIRE(! boolean_expression("one_of(\"d\", \"a\", \"b\", \"c\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"a\")") { REQUIRE(! boolean_expression("one_of(\"a\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"a\", \"a\")") { REQUIRE(boolean_expression("one_of(\"a\", \"a\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"b\", \"a\")") { REQUIRE(! boolean_expression("one_of(\"b\", \"a\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"abcdef\", /.*c.*/)") { REQUIRE(boolean_expression("one_of(\"abcdef\", /.*c.*/)")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"abcdef\", /.*f.*/, /.*c.*/)") { REQUIRE(boolean_expression("one_of(\"abcdef\", /.*f.*/, /.*c.*/)")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"abcdef\", ~\".*f.*\", ~\".*c.*\")") { REQUIRE(boolean_expression("one_of(\"abcdef\", ~\".*f.*\", ~\".*c.*\")")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"ghij\", /.*f.*/, /.*c.*/)") { REQUIRE(! boolean_expression("one_of(\"ghij\", /.*f.*/, /.*c.*/)")); }
|
||||||
|
SECTION("boolean expression parser: one_of(\"ghij\", ~\".*f.*\", ~\".*c.*\")") { REQUIRE(! boolean_expression("one_of(\"ghij\", ~\".*f.*\", ~\".*c.*\")")); }
|
||||||
SECTION("complex expression") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1")); }
|
SECTION("complex expression") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VENDOR_PRUSA3D.*/ and printer_notes=~/.*PRINTER_MODEL_MK2.*/ and nozzle_diameter[0]==0.6 and num_extruders>1")); }
|
||||||
SECTION("complex expression2") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.6 and num_extruders>1)")); }
|
SECTION("complex expression2") { REQUIRE(boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.6 and num_extruders>1)")); }
|
||||||
SECTION("complex expression3") { REQUIRE(! boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.3 and num_extruders>1)")); }
|
SECTION("complex expression3") { REQUIRE(! boolean_expression("printer_notes=~/.*PRINTER_VEwerfNDOR_PRUSA3D.*/ or printer_notes=~/.*PRINTertER_MODEL_MK2.*/ or (nozzle_diameter[0]==0.3 and num_extruders>1)")); }
|
||||||
|
Loading…
Reference in New Issue
Block a user