Skip to content

Bugfix: Update for regex 20 lookbehind test. #1407

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
286 changes: 286 additions & 0 deletions regression-tests/pure2-regex_20_lookbehind.cpp2
Original file line number Diff line number Diff line change
@@ -0,0 +1,286 @@
create_result: (resultExpr: std::string, r) -> std::string = {
result: std::string = "";

get_next := :(iter) -> _ = {
start := std::distance(resultExpr&$*.cbegin(), iter);
firstDollar := resultExpr&$*.find("$", start);
firstAt := resultExpr&$*.find("@", start);

end := std::min(firstDollar, firstAt);
if end != std::string::npos {
return resultExpr&$*.cbegin() + end;
}
else {
return resultExpr&$*.cend();
}
};
extract_group_and_advance := :(inout iter) -> _ = {
start := iter;

while std::isdigit(iter*) next iter++ {}

return std::stoi(std::string(start, iter));
};
extract_until := :(inout iter, to: char) -> _ = {
start := iter;

while (to != iter*) next iter++ {} // TODO: Without bracket: error: postfix unary * (dereference) cannot be immediately followed by a (, identifier, or literal - add whitespace before * here if you meant binary * (multiplication)

return std::string(start, iter);
};

iter := resultExpr.begin();

while iter != resultExpr.end() {
next := get_next(iter);

if next != iter {
result += std::string(iter, next);
}
if next != resultExpr.end() {
if next* == '$' {
next++;

if next* == '&' {
next++;
result += r.group(0);
}
else if next* == '-' || next* == '+' {
is_start := next* == '-';
next++;
if next* == '{' {
next++; // Skip {
group := extract_until(next, '}');
next++; // Skip }
result += r.group(group);
}
else if next* == '[' {
next++; // Skip [
group := extract_group_and_advance(next);
next++; // Skip ]

if is_start {
result += std::to_string(r.group_start(group));
}
else {
result += std::to_string(r.group_end(group));
}
}
else {
// Return max group
result += r.group(r.group_number() - 1);
}
}
else if std::isdigit(next*) {
group := extract_group_and_advance(next);
result += r.group(group);
}
else {
std::cerr << "Not implemented";
}
}
else if next* == '@' {
next++;

if next* == '-' || next* == '+' {
i := 0;
while i < cpp2::unchecked_narrow<int>(r.group_number()) next i++ {
pos := 0;
if next* == '-' {
pos = r.group_start(i);
}
else {
pos = r.group_end(i);
}
result += std::to_string(pos);
}
next++;
}
else {
std::cerr << "Not implemented";
}
}
else {
std::cerr << "Not implemented.";
}
}
iter = next;
}

return result;
}

sanitize: (copy str: std::string) -> std::string =
{
str = cpp2::string_util::replace_all(str, "\a", "\\a");
str = cpp2::string_util::replace_all(str, "\f", "\\f");
str = cpp2::string_util::replace_all(str, "\x1b", "\\e");
str = cpp2::string_util::replace_all(str, "\n", "\\n");
str = cpp2::string_util::replace_all(str, "\r", "\\r");
str = cpp2::string_util::replace_all(str, "\t", "\\t");

return str;
}

test: <M> (regex: M, id: std::string, regex_str: std::string, str: std::string, kind: std::string, resultExpr: std::string,
resultExpected: std::string) = {

warning: std::string = "";
if regex.to_string() != regex_str {
warning = "Warning: Parsed regex does not match.";
}

status: std::string = "OK";

r := regex.search(str);

if "y" == kind || "yM" == kind || "yS" == kind || "yB" == kind {
if !r.matched {
status = "Failure: Regex should apply.";
}
else {
// Have a match check the result

result := create_result(resultExpr, r);

if result != resultExpected {
status = "Failure: Result is wrong. (is: (sanitize(result))$)";
}
}
}
else if "n" == kind {
if r.matched {
status = "Failure: Regex should not apply. Result is '(r.group(0))$'";
}
} else {
status = "Unknown kind '(kind)$'";
}

if !warning.empty() {
warning += " ";
}
std::cout << "(id)$_(kind)$: (status)$ (warning)$regex: (regex_str)$ parsed_regex: (regex.to_string())$ str: (sanitize(str))$ result_expr: (resultExpr)$ expected_results (sanitize(resultExpected))$" << std::endl;
}


test_tests_20_lookbehind: @regex type = {
regex_01 := R"((?<=a)b)";
regex_02 := R"((?<=af?)b)";
regex_03 := R"((?<=a)b)";
regex_04 := R"((?<=a(?:fo)?)b)";
regex_05 := R"((?<=a)b)";
regex_06 := R"((?<=a(?:foo)?)b)";
regex_07 := R"((?<!c)b)";
regex_08 := R"((?<!c(?:foob)?)b)";
regex_09 := R"((?<!c)b)";
regex_10 := R"((?<!c(?:fooba)?)b)";
regex_11 := R"((?<!c)b)";
regex_12 := R"((?<!c(?:foobar)?)b)";
regex_13 := R"((?<!c)b)";
regex_14 := R"((?<!c(?:foobarb)?)b)";
regex_15 := R"((?<![cd])b)";
regex_16 := R"((?<![cd]e{0,254})b)";
regex_17 := R"((?<![cd])[ab])";
regex_18 := R"((?<![cd]{1,2})[ab])";
regex_19 := R"((?<![cd]{1,3})[ab])";
regex_20 := R"((?<!(c|d))b)";
regex_21 := R"((?<!(c|d))[ab])";
regex_22 := R"((?<!cd)[ab])";
regex_23 := R"($(?<=^(a)))";
regex_24 := R"((.*)c)";
regex_25 := R"((.*)(?<=b))";
regex_26 := R"((.*)(?<=b)c)";
regex_27 := R"((.*)(?<=b|c))";
regex_28 := R"((.*)(?<=b|c)c)";
regex_29 := R"((.*)(?<=c|b))";
regex_30 := R"((.*)(?<=c|b)c)";
regex_31 := R"((.*)(?<=[bc]))";
regex_32 := R"((.*)(?<=[bc])c)";
regex_33 := R"((.*?)c)";
regex_34 := R"((.*?)(?<=b))";
regex_35 := R"((.*?)(?<=b)c)";
regex_36 := R"((.*?)(?<=b|c))";
regex_37 := R"((.*?)(?<=b|c)c)";
regex_38 := R"((.*?)(?<=c|b))";
regex_39 := R"((.*?)(?<=c|b)c)";
regex_40 := R"((.*?)(?<=[bc]))";
regex_41 := R"((.*?)(?<=[bc])c)";
regex_42 := R"((?<=foo))";
regex_43 := R"((?<=foo))";
regex_44 := R"(.*(?<=foo))";
regex_45 := R"(.*(?<=foo))";
regex_46 := R"((?<=foo)Y)";
regex_47 := R"(o(?<=foo)Y)";
regex_48 := R"(X(?<=foo.)[YZ])";
regex_49 := R"((?<=bar>)foo)";
regex_50 := R"((?<!bar>)foo)";
regex_51 := R"((?<=bar>ABC)foo)";
regex_52 := R"((?<!bar>ABC)foo)";
regex_53 := R"((?<=abcd(?<=(aaaabcd))))";
regex_54 := R"((?=xy(?<=(aaxy))))";
regex_55 := R"((?=xy(?<=(aaxyz?))))";
regex_56 := R"((?<=(?=(aaxy))aa))";
run: (this) = {
std::cout << "Running tests_20_lookbehind:"<< std::endl;
test(regex_01, "01", R"((?<=a)b)", "ab", "y", R"($&)", "b");
test(regex_02, "02", R"((?<=af?)b)", "ab", "y", R"($&)", "b");
test(regex_03, "03", R"((?<=a)b)", "cb", "n", R"(-)", "-");
test(regex_04, "04", R"((?<=a(?:fo)?)b)", "cb", "n", R"(-)", "-");
test(regex_05, "05", R"((?<=a)b)", "b", "n", R"(-)", "-");
test(regex_06, "06", R"((?<=a(?:foo)?)b)", "b", "n", R"(-)", "-");
test(regex_07, "07", R"((?<!c)b)", "ab", "y", R"($&)", "b");
test(regex_08, "08", R"((?<!c(?:foob)?)b)", "ab", "y", R"($&)", "b");
test(regex_09, "09", R"((?<!c)b)", "cb", "n", R"(-)", "-");
test(regex_10, "10", R"((?<!c(?:fooba)?)b)", "cb", "n", R"(-)", "-");
test(regex_11, "11", R"((?<!c)b)", "b", "y", R"(-)", "-");
test(regex_12, "12", R"((?<!c(?:foobar)?)b)", "b", "y", R"(-)", "-");
test(regex_13, "13", R"((?<!c)b)", "b", "y", R"($&)", "b");
test(regex_14, "14", R"((?<!c(?:foobarb)?)b)", "b", "y", R"($&)", "b");
test(regex_15, "15", R"((?<![cd])b)", "dbcb", "n", R"(-)", "-");
test(regex_16, "16", R"((?<![cd]e{0,254})b)", "dbcb", "n", R"(-)", "-");
test(regex_17, "17", R"((?<![cd])[ab])", "dbaacb", "y", R"($&)", "a");
test(regex_18, "18", R"((?<![cd]{1,2})[ab])", "dbaacb", "y", R"($&)", "a");
test(regex_19, "19", R"((?<![cd]{1,3})[ab])", "dbaacb", "y", R"($&)", "a");
test(regex_20, "20", R"((?<!(c|d))b)", "dbcb", "n", R"(-)", "-");
test(regex_21, "21", R"((?<!(c|d))[ab])", "dbaacb", "y", R"($&)", "a");
test(regex_22, "22", R"((?<!cd)[ab])", "cdaccb", "y", R"($&)", "b");
test(regex_23, "23", R"($(?<=^(a)))", "a", "y", R"($1)", "a");
test(regex_24, "24", R"((.*)c)", "abcd", "y", R"($1)", "ab");
test(regex_25, "25", R"((.*)(?<=b))", "abcd", "y", R"($1)", "ab");
test(regex_26, "26", R"((.*)(?<=b)c)", "abcd", "y", R"($1)", "ab");
test(regex_27, "27", R"((.*)(?<=b|c))", "abcd", "y", R"($1)", "abc");
test(regex_28, "28", R"((.*)(?<=b|c)c)", "abcd", "y", R"($1)", "ab");
test(regex_29, "29", R"((.*)(?<=c|b))", "abcd", "y", R"($1)", "abc");
test(regex_30, "30", R"((.*)(?<=c|b)c)", "abcd", "y", R"($1)", "ab");
test(regex_31, "31", R"((.*)(?<=[bc]))", "abcd", "y", R"($1)", "abc");
test(regex_32, "32", R"((.*)(?<=[bc])c)", "abcd", "y", R"($1)", "ab");
test(regex_33, "33", R"((.*?)c)", "abcd", "y", R"($1)", "ab");
test(regex_34, "34", R"((.*?)(?<=b))", "abcd", "y", R"($1)", "ab");
test(regex_35, "35", R"((.*?)(?<=b)c)", "abcd", "y", R"($1)", "ab");
test(regex_36, "36", R"((.*?)(?<=b|c))", "abcd", "y", R"($1)", "ab");
test(regex_37, "37", R"((.*?)(?<=b|c)c)", "abcd", "y", R"($1)", "ab");
test(regex_38, "38", R"((.*?)(?<=c|b))", "abcd", "y", R"($1)", "ab");
test(regex_39, "39", R"((.*?)(?<=c|b)c)", "abcd", "y", R"($1)", "ab");
test(regex_40, "40", R"((.*?)(?<=[bc]))", "abcd", "y", R"($1)", "ab");
test(regex_41, "41", R"((.*?)(?<=[bc])c)", "abcd", "y", R"($1)", "ab");
test(regex_42, "42", R"((?<=foo))", "foo", "y", R"(@+)", "3");
test(regex_43, "43", R"((?<=foo))", "XfooY", "y", R"(@+)", "4");
test(regex_44, "44", R"(.*(?<=foo))", "foo", "y", R"(@+)", "3");
test(regex_45, "45", R"(.*(?<=foo))", "XfooY", "y", R"(@+)", "4");
test(regex_46, "46", R"((?<=foo)Y)", "XfooY", "y", R"(@+)", "5");
test(regex_47, "47", R"(o(?<=foo)Y)", "..XfooY..", "y", R"(@+)", "7");
test(regex_48, "48", R"(X(?<=foo.)[YZ])", "..XfooXY..", "y", R"(@+)", "8");
test(regex_49, "49", R"((?<=bar>)foo)", "bar>foo", "y", R"($&)", "foo");
test(regex_50, "50", R"((?<!bar>)foo)", "bar>foo", "n", R"(-)", "-");
test(regex_51, "51", R"((?<=bar>ABC)foo)", "bar>ABCfoo", "y", R"($&)", "foo");
test(regex_52, "52", R"((?<!bar>ABC)foo)", "bar>ABCfoo", "n", R"(-)", "-");
test(regex_53, "53", R"((?<=abcd(?<=(aaaabcd))))", "..aaaabcd..", "y", R"($1)", "aaaabcd");
test(regex_54, "54", R"((?=xy(?<=(aaxy))))", "..aaxy..", "y", R"($1)", "aaxy");
test(regex_55, "55", R"((?=xy(?<=(aaxyz?))))", "..aaxy..", "y", R"($1)", "aaxy");
test(regex_56, "56", R"((?<=(?=(aaxy))aa))", "..aaxy..", "y", R"($1)", "aaxy");
std::cout << std::endl;
}
}
main: () = {
test_tests_20_lookbehind().run();
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,59 +77,59 @@ pure2-expected-is-as.cpp2:34:24: error: use of undeclared identifier 'ex1'; did
__MATHCALL_VEC (exp,, (_Mdouble_ __x));
^
In file included from pure2-expected-is-as.cpp:7:
../../../include/cpp2util.h:469:72: error: invalid application of 'sizeof' to a function type
../../../include/cpp2util.h:475:72: error: invalid application of 'sizeof' to a function type
(std::is_floating_point_v<From> && std::is_floating_point_v<To> && sizeof(From) > sizeof(To)) || // NOLINT(misc-redundant-expression)
^~~~~~~~~~~~
../../../include/cpp2util.h:2924:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here
../../../include/cpp2util.h:2929:19: note: in instantiation of variable template specialization 'cpp2::impl::is_narrowing_v' requested here
if constexpr (is_narrowing_v<C, CPP2_TYPEOF(x)>) {
^
pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_<int, double (&)(double) noexcept>' requested here
auto val1 {cpp2::impl::as_<int>(ex1)};
^
In file included from pure2-expected-is-as.cpp:7:
../../../include/cpp2util.h:2944:12: error: no matching function for call to 'as'
../../../include/cpp2util.h:2949:12: error: no matching function for call to 'as'
return as<C>(CPP2_FORWARD(x));
^~~~~
pure2-expected-is-as.cpp2:39:28: note: in instantiation of function template specialization 'cpp2::impl::as_<int, double (&)(double) noexcept>' requested here
auto val1 {cpp2::impl::as_<int>(ex1)};
^
../../../include/cpp2util.h:1902:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept]
../../../include/cpp2util.h:1907:16: note: candidate template ignored: constraints not satisfied [with C = int, x:auto = double (&)(double) noexcept]
constexpr auto as(auto&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
^
../../../include/cpp2util.h:1908:18: note: because 'std::is_scalar_v<std::remove_cvref_t<decltype(x)> >' evaluated to false
../../../include/cpp2util.h:1913:18: note: because 'std::is_scalar_v<std::remove_cvref_t<decltype(x)> >' evaluated to false
(std::is_scalar_v<CPP2_TYPEOF(x)> && !std::is_enum_v<CPP2_TYPEOF(x)>)
^
../../../include/cpp2util.h:1909:17: note: and 'std::is_floating_point_v<std::remove_cvref_t<decltype(x)> >' evaluated to false
../../../include/cpp2util.h:1914:17: note: and 'std::is_floating_point_v<std::remove_cvref_t<decltype(x)> >' evaluated to false
|| std::is_floating_point_v<CPP2_TYPEOF(x)>
^
../../../include/cpp2util.h:1910:17: note: and 'std::is_base_of_v<int, std::remove_cvref_t<decltype(x)> >' evaluated to false
../../../include/cpp2util.h:1915:17: note: and 'std::is_base_of_v<int, std::remove_cvref_t<decltype(x)> >' evaluated to false
|| std::is_base_of_v<C, CPP2_TYPEOF(x)>
^
../../../include/cpp2util.h:1911:17: note: and 'std::is_base_of_v<std::remove_cvref_t<decltype(x)>, int>' evaluated to false
../../../include/cpp2util.h:1916:17: note: and 'std::is_base_of_v<std::remove_cvref_t<decltype(x)>, int>' evaluated to false
|| std::is_base_of_v<CPP2_TYPEOF(x), C>
^
../../../include/cpp2util.h:1912:30: note: and 'C({std::forward<decltype(x)>(x)})' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept'
../../../include/cpp2util.h:1917:30: note: and 'C({std::forward<decltype(x)>(x)})' would be invalid: cannot initialize a value of type 'int' with an lvalue of type 'double (double) noexcept'
|| requires { C{CPP2_FORWARD(x)}; }
^
../../../include/cpp2util.h:327:37: note: expanded from macro 'CPP2_FORWARD'
../../../include/cpp2util.h:333:37: note: expanded from macro 'CPP2_FORWARD'
#define CPP2_FORWARD(x) std::forward<decltype(x)>(x)
^
../../../include/cpp2util.h:2041:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept]
../../../include/cpp2util.h:2046:6: note: candidate template ignored: constraints not satisfied [with C = int, X = double (&)(double) noexcept]
auto as(X&& x CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT_AS) -> decltype(auto)
^
../../../include/cpp2util.h:2040:23: note: because 'specialization_of_template<double (&)(double) noexcept, std::variant>' evaluated to false
../../../include/cpp2util.h:2045:23: note: because 'specialization_of_template<double (&)(double) noexcept, std::variant>' evaluated to false
template< typename C, specialization_of_template<std::variant> X >
^
../../../include/cpp2util.h:892:7: note: because 'specialization_of_template_helper<C>(std::forward<X>(x))' would be invalid: no matching function for call to 'specialization_of_template_helper'
../../../include/cpp2util.h:897:7: note: because 'specialization_of_template_helper<C>(std::forward<X>(x))' would be invalid: no matching function for call to 'specialization_of_template_helper'
{ specialization_of_template_helper<C>(std::forward<X>(x)) } -> std::same_as<std::true_type>;
^
../../../include/cpp2util.h:2088:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept]
../../../include/cpp2util.h:2093:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept]
constexpr auto as( X && x ) -> decltype(auto) {
^
../../../include/cpp2util.h:2087:22: note: because 'same_type_as<double (&)(double) noexcept, std::any>' evaluated to false
../../../include/cpp2util.h:2092:22: note: because 'same_type_as<double (&)(double) noexcept, std::any>' evaluated to false
template<typename T, same_type_as<std::any> X>
^
../../../include/cpp2util.h:922:29: note: because 'std::same_as<std::remove_cvref_t<double (&)(double) noexcept>, std::remove_cvref_t<any> >' evaluated to false
../../../include/cpp2util.h:927:29: note: because 'std::same_as<std::remove_cvref_t<double (&)(double) noexcept>, std::remove_cvref_t<any> >' evaluated to false
concept same_type_as = std::same_as<std::remove_cvref_t<X>, std::remove_cvref_t<C>>;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:63:19: note: because '__detail::__same_as<double (double) noexcept, std::any>' evaluated to false
Expand All @@ -138,19 +138,19 @@ concept same_type_as = std::same_as<std::remove_cvref_t<X>, std::remove_cvref_t<
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/concepts:57:27: note: because 'std::is_same_v<double (double) noexcept, std::any>' evaluated to false
concept __same_as = std::is_same_v<_Tp, _Up>;
^
../../../include/cpp2util.h:2131:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept]
../../../include/cpp2util.h:2136:16: note: candidate template ignored: constraints not satisfied [with T = int, X = double (&)(double) noexcept]
constexpr auto as( X&& x ) -> decltype(auto) {
^
../../../include/cpp2util.h:2130:22: note: because 'specialization_of_template<double (&)(double) noexcept, std::optional>' evaluated to false
../../../include/cpp2util.h:2135:22: note: because 'specialization_of_template<double (&)(double) noexcept, std::optional>' evaluated to false
template<typename T, specialization_of_template<std::optional> X>
^
../../../include/cpp2util.h:892:7: note: because 'specialization_of_template_helper<C>(std::forward<X>(x))' would be invalid: no matching function for call to 'specialization_of_template_helper'
../../../include/cpp2util.h:897:7: note: because 'specialization_of_template_helper<C>(std::forward<X>(x))' would be invalid: no matching function for call to 'specialization_of_template_helper'
{ specialization_of_template_helper<C>(std::forward<X>(x)) } -> std::same_as<std::true_type>;
^
../../../include/cpp2util.h:1877:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided
../../../include/cpp2util.h:1882:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided
constexpr auto as() -> auto
^
../../../include/cpp2util.h:1888:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided
../../../include/cpp2util.h:1893:16: note: candidate function template not viable: requires 0 arguments, but 1 was provided
constexpr auto as() -> auto
^
pure2-expected-is-as.cpp2:39:37: error: use of undeclared identifier 'ex1'
Expand Down
Loading
Loading