Skip to content

Commit

Permalink
[GR-51523] [GR-51674] TRegex bug fixes.
Browse files Browse the repository at this point in the history
PullRequest: graal/16783
  • Loading branch information
jirkamarsik committed Jan 31, 2024
2 parents 32d5155 + a0dd346 commit b7711d9
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,11 @@ public void gr48586() {
public void gr50807() {
test("(?<=%b{1,4}?)foo", "", "%bbbbfoo", 0, true, 5, 8);
}

@Test
public void gr51523() {
test("(?:^|\\.?)([A-Z])", "g", "desktopBrowser", 0, true, 7, 8, 7, 8);
test("(?:^|\\.?)([A-Z])", "g", "locationChanged", 0, true, 8, 9, 8, 9);
test("(?:^|\\.?)([A-Z]|(?<=[a-z])\\d(?=\\d+))", "g", "helloWorld", 0, true, 5, 6, 5, 6);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ public void testSpecialGroups() {
}
}

@Test
public void testNestedQuantifier() {
test("(a*|b)*", "", "aaaaaabaaaaaaaaaaaaaabb", 0, true, 0, 6, 6, 6);
test("a((b?)*)*", "", "ab", 0, true, 0, 2, 2, 2, 2, 2);
}

@Test
public void generatedTests() {
/* GENERATED CODE BEGIN - KEEP THIS MARKER FOR AUTOMATIC UPDATES */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public ASTStep step(NFAState expandState) {

@Override
protected void visit(RegexASTNode target) {
assert noPredicatesInGuards(getQuantifierGuardsOnPath());
ASTSuccessor successor = new ASTSuccessor();
ASTTransition transition = new ASTTransition(ast.getLanguage());
transition.setGroupBoundaries(getGroupBoundaries());
Expand Down Expand Up @@ -183,6 +184,19 @@ protected void visit(RegexASTNode target) {
stepCur.addSuccessor(successor);
}

private static boolean noPredicatesInGuards(QuantifierGuard[] quantifierGuards) {
// Normalization should remove any exitZeroWidth, escapeZeroWidth, checkGroupMatched and
// checkGroupNotMatched guards. The effect of updateCG guards is implemented using
// getGroupBoundaries and enterZeroWidth guards have no effect when exitZeroWidth and
// escapeZeroWidth are removed already. Other guards shouldn't be used when building a DFA.
for (QuantifierGuard guard : quantifierGuards) {
if (guard.getKind() != QuantifierGuard.Kind.updateCG && guard.getKind() != QuantifierGuard.Kind.enterZeroWidth) {
return false;
}
}
return true;
}

@Override
protected void enterLookAhead(LookAheadAssertion assertion) {
TBitSet currentMatchedConditionGroups = getCurrentMatchedConditionGroups();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.regex.tregex.parser.Token.Quantifier;
import com.oracle.truffle.regex.tregex.parser.ast.ConditionalBackReferenceGroup;
import com.oracle.truffle.regex.tregex.parser.flavors.RegexFlavor;

import java.util.Objects;

Expand Down Expand Up @@ -85,15 +86,17 @@ public enum Kind {
enterZeroWidth,
/**
* Transition is leaving a quantified expression that may match the empty string. Check if
* the current index is greater than the saved index. In the case of Ruby, also check if any
* capture groups were modified.
* the current index is greater than the saved index. In the case of flavors in which
* {@link RegexFlavor#emptyChecksMonitorCaptureGroups()}, also check if any capture groups
* were modified.
*/
exitZeroWidth,
/**
* Transition is leaving a quantified expression that may match the empty string and it is
* about to continue to what follows the loop. This is only possible in Ruby and only when
* the last iteration of the quantiifed expression fails the empty check (the check for the
* index and the state of capture groups tested by {@link #exitZeroWidth}).
* about to continue to what follows the loop. This is possible in flavors in which
* {@link RegexFlavor#failingEmptyChecksDontBacktrack()} and only when the last iteration of
* the quantified expression fails the empty check (the check for the index and the state of
* capture groups tested by {@link #exitZeroWidth}).
*/
escapeZeroWidth,
/**
Expand All @@ -111,8 +114,9 @@ public enum Kind {
exitEmptyMatch,
/**
* Transition is passing a capture group boundary. We need this information in order to
* implement the empty check test in {@link #exitZeroWidth}, which, in the case of Ruby,
* also needs to monitor the state of capture groups in between {@link #enterZeroWidth} and
* implement the empty check test in {@link #exitZeroWidth}, which, in the case of flavors
* in which {@link RegexFlavor#emptyChecksMonitorCaptureGroups()}, where we need to monitor
* the state of capture groups in between {@link #enterZeroWidth} and
* {@link #exitZeroWidth}.
*/
updateCG,
Expand Down
Loading

0 comments on commit b7711d9

Please sign in to comment.