diff options
author | K.Kosako <kkosako0@gmail.com> | 2020-01-19 00:00:31 +0900 |
---|---|---|
committer | K.Kosako <kkosako0@gmail.com> | 2020-01-19 00:00:31 +0900 |
commit | c27eba57c03cbaa6efa74b69f6b4053f7d2e28c3 (patch) | |
tree | 4b905fc5f3a9c19159e2d5049f954b825e98c0fb | |
parent | c4522d7781c40678c856c68278028a9ce1d4b356 (diff) | |
download | oniguruma-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.c | 46 |
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) { |