Skip to content

Commit 1ee4c15

Browse files
jirkamarsikdjoooooe
authored andcommitted
Check all relevant guards when pushing quantifier counter guards
1 parent 8fbfee8 commit 1ee4c15

File tree

4 files changed

+82
-39
lines changed

4 files changed

+82
-39
lines changed

regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/nfa/TransitionGuard.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,10 @@ public static long createCountSet1(Quantifier quantifier) {
153153
return create(Kind.countSet1, quantifier);
154154
}
155155

156+
public static long createCountSet1(int quantifierIndex) {
157+
return create(Kind.countSet1, quantifierIndex);
158+
}
159+
156160
public static long createCountSetMin(Quantifier quantifier) {
157161
return create(Kind.countSetMin, quantifier);
158162
}
@@ -181,6 +185,10 @@ public static long createCountLtMax(Quantifier quantifier) {
181185
return create(Kind.countLtMax, quantifier);
182186
}
183187

188+
public static long createCountLtMax(int quantifierIndex) {
189+
return create(Kind.countLtMax, quantifierIndex);
190+
}
191+
184192
public static long createEnterZeroWidth(Quantifier quantifier) {
185193
return createZeroWidth(Kind.enterZeroWidth, quantifier);
186194
}

regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/RegexAST.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,10 @@ public Token.Quantifier[] getQuantifierArray() {
203203
return quantifiers.toArray(Token.Quantifier[]::new);
204204
}
205205

206+
public Token.Quantifier getQuantifier(int quantifierIndex) {
207+
return quantifiers.get(quantifierIndex);
208+
}
209+
206210
public void registerZeroWidthQuantifiable(QuantifiableTerm zeroWidthQuantifiable) {
207211
zeroWidthQuantifiable.getQuantifier().setZeroWidthIndex(zeroWidthQuantifiables.size());
208212
zeroWidthQuantifiables.add(zeroWidthQuantifiable);

regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/parser/ast/visitors/NFATraversalRegexASTVisitor.java

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
*/
4141
package com.oracle.truffle.regex.tregex.parser.ast.visitors;
4242

43+
import static com.oracle.truffle.regex.tregex.util.MathUtil.saturatingInc;
44+
4345
import java.util.Arrays;
4446
import java.util.Set;
4547

@@ -1214,13 +1216,8 @@ private void pushTransitionGuard(long guard) {
12141216
case countSet1, countSetMin -> {
12151217
bqLastCounterReset[TransitionGuard.getQuantifierIndex(guard)] = transitionGuards.length();
12161218
}
1217-
case countLtMin, countGeMin -> {
1218-
if (canOmitCounterMinCheck(guard)) {
1219-
return;
1220-
}
1221-
}
1222-
case countLtMax -> {
1223-
if (canOmitCounterMaxCheck(guard)) {
1219+
case countLtMin, countGeMin, countLtMax -> {
1220+
if (canOmitCounterCheck(guard)) {
12241221
return;
12251222
}
12261223
}
@@ -1298,47 +1295,74 @@ private void pushTransitionGuard(long guard) {
12981295
transitionGuards.add(guard);
12991296
}
13001297

1301-
private boolean canOmitCounterMinCheck(long guard) {
1302-
assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countGeMin);
1298+
private boolean canOmitCounterCheck(long guard) {
1299+
assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countGeMin) || TransitionGuard.is(guard, TransitionGuard.Kind.countLtMax);
13031300
int quantifierIndex = TransitionGuard.getQuantifierIndex(guard);
1301+
int min = ast.getQuantifier(quantifierIndex).getMin();
1302+
int max = ast.getQuantifier(quantifierIndex).getMax();
1303+
int minPlus1 = saturatingInc(min);
1304+
1305+
long countLtMin = TransitionGuard.createCountLtMin(quantifierIndex);
1306+
long countGeMin = TransitionGuard.createCountGeMin(quantifierIndex);
1307+
long countLtMax = TransitionGuard.createCountLtMax(quantifierIndex);
13041308
long countInc = TransitionGuard.createCountInc(quantifierIndex);
13051309
long countSetMin = TransitionGuard.createCountSetMin(quantifierIndex);
1306-
boolean isLtMin = TransitionGuard.is(guard, TransitionGuard.Kind.countLtMin);
1307-
long inverseGuard = isLtMin ? TransitionGuard.createCountGeMin(quantifierIndex) : TransitionGuard.createCountLtMin(quantifierIndex);
1308-
boolean omit = false;
1309-
boolean existingIsSetMin = false;
1310+
long countSet1 = TransitionGuard.createCountSet1(quantifierIndex);
1311+
1312+
int counterLow = 0;
1313+
int counterHigh = Integer.MAX_VALUE;
13101314
for (long existingGuard : transitionGuards) {
1311-
if (existingGuard == countSetMin) {
1312-
existingIsSetMin = true;
1313-
}
1314-
if (existingGuard == guard) {
1315-
omit = true;
1316-
}
1317-
if (existingGuard == countInc && !(!isLtMin && existingIsSetMin)) {
1318-
omit = false;
1319-
}
1320-
if (existingGuard == inverseGuard || isLtMin && existingIsSetMin) {
1321-
setShouldRetreat();
1322-
return true;
1315+
if (existingGuard == countLtMin) {
1316+
counterHigh = Math.min(counterHigh, min - 1);
1317+
} else if (existingGuard == countGeMin) {
1318+
counterLow = Math.max(counterLow, min);
1319+
} else if (existingGuard == countLtMax) {
1320+
counterHigh = Math.min(counterHigh, max - 1);
1321+
} else if (existingGuard == countSetMin) {
1322+
counterLow = minPlus1;
1323+
counterHigh = minPlus1;
1324+
} else if (existingGuard == countSet1) {
1325+
counterLow = 1;
1326+
counterHigh = 1;
1327+
} else if (existingGuard == countInc) {
1328+
counterLow = saturatingInc(counterLow);
1329+
counterHigh = saturatingInc(counterHigh);
13231330
}
13241331
}
1325-
return omit;
1326-
}
13271332

1328-
private boolean canOmitCounterMaxCheck(long guard) {
1329-
assert TransitionGuard.is(guard, TransitionGuard.Kind.countLtMax);
1330-
int quantifierIndex = TransitionGuard.getQuantifierIndex(guard);
1331-
long countInc = TransitionGuard.createCountInc(quantifierIndex);
1332-
boolean omit = false;
1333-
for (long existingGuard : transitionGuards) {
1334-
if (existingGuard == guard) {
1335-
omit = true;
1333+
switch (TransitionGuard.getKind(guard)) {
1334+
case countLtMin -> {
1335+
if (counterHigh < min) {
1336+
return true;
1337+
} else if (counterLow >= min) {
1338+
setShouldRetreat();
1339+
return true;
1340+
} else {
1341+
return false;
1342+
}
1343+
}
1344+
case countLtMax -> {
1345+
if (counterHigh < max) {
1346+
return true;
1347+
} else if (counterLow >= max) {
1348+
setShouldRetreat();
1349+
return true;
1350+
} else {
1351+
return false;
1352+
}
13361353
}
1337-
if (existingGuard == countInc) {
1338-
omit = false;
1354+
case countGeMin -> {
1355+
if (counterLow >= min) {
1356+
return true;
1357+
} else if (counterHigh < min) {
1358+
setShouldRetreat();
1359+
return true;
1360+
} else {
1361+
return false;
1362+
}
13391363
}
1364+
default -> throw CompilerDirectives.shouldNotReachHere();
13401365
}
1341-
return omit;
13421366
}
13431367

13441368
/// Visited set management

regex/src/com.oracle.truffle.regex/src/com/oracle/truffle/regex/tregex/util/MathUtil.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -50,4 +50,11 @@ public static int log2floor(int x) {
5050
public static int log2ceil(int x) {
5151
return 32 - Integer.numberOfLeadingZeros(x - 1);
5252
}
53+
54+
public static int saturatingInc(int x) {
55+
if (x == Integer.MAX_VALUE) {
56+
return x;
57+
}
58+
return x + 1;
59+
}
5360
}

0 commit comments

Comments
 (0)