aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorK.Kosako <kkosako0@gmail.com>2020-01-19 00:00:31 +0900
committerK.Kosako <kkosako0@gmail.com>2020-01-19 00:00:31 +0900
commitc27eba57c03cbaa6efa74b69f6b4053f7d2e28c3 (patch)
tree4b905fc5f3a9c19159e2d5049f954b825e98c0fb
parentc4522d7781c40678c856c68278028a9ce1d4b356 (diff)
downloadoniguruma-develop.zip
oniguruma-develop.tar.gz
oniguruma-develop.tar.bz2
optimize look-behind by reducing upper range of quantifier for simple repetitiondevelop
-rw-r--r--src/regcomp.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/regcomp.c b/src/regcomp.c
index b291edf..1290d44 100644
--- a/src/regcomp.c
+++ b/src/regcomp.c
@@ -4287,6 +4287,49 @@ divide_look_behind_alternatives(Node* node)
return 0;
}
+static int
+quant_reduce_in_look_behind(Node* node)
+{
+ NodeType type;
+ Node* body;
+
+ if (NODE_TYPE(node) != NODE_QUANT) return 0;
+
+ body = NODE_BODY(node);
+ type = NODE_TYPE(body);
+ if (type == NODE_STRING || type == NODE_CTYPE ||
+ type == NODE_CCLASS || type == NODE_BACKREF) {
+ QuantNode* qn = QUANT_(node);
+ qn->upper = qn->lower;
+ }
+
+ return 0;
+}
+
+static int
+tree_reduce_in_look_behind(Node* node, regex_t* reg, ScanEnv* env)
+{
+ int r;
+
+ switch (NODE_TYPE(node)) {
+ case NODE_QUANT:
+ r = quant_reduce_in_look_behind(node);
+ break;
+
+ case NODE_ALT:
+ do {
+ r = quant_reduce_in_look_behind(NODE_CAR(node));
+ } while (r == 0 && IS_NOT_NULL(node = NODE_CDR(node)));
+ break;
+
+ default:
+ r = 0;
+ break;
+ }
+
+ return r;
+}
+
static int tune_tree(Node* node, regex_t* reg, int state, ScanEnv* env);
static int
@@ -4308,6 +4351,9 @@ tune_look_behind(Node* node, regex_t* reg, int state, ScanEnv* env)
r = tune_tree(NODE_ANCHOR_BODY(an), reg, state1, env);
if (r != 0) return r;
+ r = tree_reduce_in_look_behind(NODE_ANCHOR_BODY(an), reg, env);
+ if (r != 0) return r;
+
r = node_char_len(NODE_ANCHOR_BODY(an), reg, &ci, env);
if (r >= 0) {
if (r == CHAR_LEN_TOP_ALT_FIXED) {