JavaScript: Rephrase two predicates to help the optimiser.

This commit is contained in:
Max Schaefer
2019-11-11 17:54:22 +00:00
parent db3eaa23ef
commit 659cc812fe
2 changed files with 25 additions and 11 deletions

View File

@@ -32,11 +32,19 @@ predicate isSimple(RegExpTerm t) {
or
isSimple(t.(RegExpGroup).getAChild())
or
(
t instanceof RegExpAlt
or
t instanceof RegExpCharacterClass and not t.(RegExpCharacterClass).isInverted()
) and
isSimpleCharacterClass(t)
or
isSimpleAlt(t)
}
/** Holds if `t` is a non-inverted character class that contains no ranges. */
predicate isSimpleCharacterClass(RegExpCharacterClass t) {
not t.isInverted() and
forall(RegExpTerm ch | ch = t.getAChild() | isSimple(ch))
}
/** Holds if `t` is an alternation of simple terms. */
predicate isSimpleAlt(RegExpAlt t) {
forall(RegExpTerm ch | ch = t.getAChild() | isSimple(ch))
}

View File

@@ -311,13 +311,19 @@ class RegExpSequence extends RegExpTerm, @regexp_seq {
forall(RegExpTerm child | child = getAChild() | child.isNullable())
}
language[monotonicAggregates]
override string getConstantValue() {
// note: due to use of monotonic aggregates, this `strictconcat` will fail if
// `getConstantValue` is undefined for any child
result = strictconcat(RegExpTerm ch, int i | ch = getChild(i) |
ch.getConstantValue() order by i
)
result = getConstantValue(0)
}
/**
* Gets the single string matched by the `i`th child and all following children of
* this sequence, if any.
*/
private string getConstantValue(int i) {
i = getNumChild() and
result = ""
or
result = getChild(i).getConstantValue() + getConstantValue(i+1)
}
}