diff --git a/src/libre/ast_rewrite.c b/src/libre/ast_rewrite.c index 0bb1c3fbe..95891fdcf 100644 --- a/src/libre/ast_rewrite.c +++ b/src/libre/ast_rewrite.c @@ -397,48 +397,14 @@ rewrite_repeat(struct ast_expr *n, enum re_flags flags) return 1; } - if (h == 0 || h == 1) { - dead = n->u.repeat.e; - - n->u.repeat.min = v; - n->u.repeat.max = w; - n->u.repeat.e = n->u.repeat.e->u.repeat.e; - - dead->type = AST_EXPR_EMPTY; - ast_expr_free(dead); - - return 1; - } - /* * a{h,i}{j,k} is equivalent to a{h*j,i*k} if it's possible to combine, - * and it's possible iff the range of the result is not more than - * the sum of the ranges of the two inputs. - */ - if (i != AST_COUNT_UNBOUNDED && k != AST_COUNT_UNBOUNDED) { - /* I don't know why this is true */ - assert(w - v > i - h + k - j); - } - - /* - * a{h,}{j,} - * a{h,i}{j,} - * a{h,}{j,k} + * and it's possible to combine unless h > 1, i is finite or j is 0, + * and j < k: in that case, the replacement would contain a{i*j+1}, but + * the original might not. */ - if ((i == AST_COUNT_UNBOUNDED || k == AST_COUNT_UNBOUNDED) && h <= 1 && j <= 1) { - dead = n->u.repeat.e; - - n->u.repeat.min = v; - n->u.repeat.max = w; - n->u.repeat.e = n->u.repeat.e->u.repeat.e; - - dead->type = AST_EXPR_EMPTY; - ast_expr_free(dead); - - return 1; - } - if (h > 1 && i == AST_COUNT_UNBOUNDED && j > 0) { + if (h <= 1 || (i == AST_COUNT_UNBOUNDED && j > 0) || j == k) { dead = n->u.repeat.e; n->u.repeat.min = v; diff --git a/tests/pcre-repeat/in55.re b/tests/pcre-repeat/in55.re new file mode 100644 index 000000000..8645a29d6 --- /dev/null +++ b/tests/pcre-repeat/in55.re @@ -0,0 +1 @@ +^a{2}{2}$ \ No newline at end of file diff --git a/tests/pcre-repeat/out55.fsm b/tests/pcre-repeat/out55.fsm new file mode 100644 index 000000000..f5f31a725 --- /dev/null +++ b/tests/pcre-repeat/out55.fsm @@ -0,0 +1,7 @@ +0 -> 1 'a'; +1 -> 2 'a'; +2 -> 3 'a'; +3 -> 4 'a'; + +start: 0; +end: 4;