mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
optimized alternative collapsing
only collapse alternative if the result is smaller than the uncollapsed version
This commit is contained in:
parent
4a9667ec4e
commit
8970ef67d4
3 changed files with 53 additions and 3 deletions
|
@ -802,7 +802,25 @@ public class HoistingProcessorTest extends AbstractXtextTests {
|
|||
assertFalse(guard.isTrivial());
|
||||
assertTrue(guard.hasTerminal());
|
||||
|
||||
assertEquals("(" + keyword("a", 2) + " || " + keyword("b", 1) + " || ((p0) && (p2))) && (" + keyword("b", 2) + " || " + keyword("b", 1) + " || ((p0) && (p3))) && (" + keyword("a", 1) + " || (p1))", guard.render());
|
||||
// collapsed version is actually not optimal
|
||||
//assertEquals("(" + keyword("a", 2) + " || " + keyword("b", 1) + " || ((p0) && (p2))) && (" + keyword("b", 2) + " || " + keyword("b", 1) + " || ((p0) && (p3))) && (" + keyword("a", 1) + " || (p1))", guard.render());
|
||||
assertEquals(
|
||||
"(" +
|
||||
keyword("b", 1) + " || " +
|
||||
"(" +
|
||||
"(p0) && (" +
|
||||
keyword("a", 2) + " || " +
|
||||
"(p2)" +
|
||||
") && (" +
|
||||
keyword("b", 2) + " || " +
|
||||
"(p3)" +
|
||||
")" +
|
||||
")" +
|
||||
") && (" +
|
||||
keyword("a", 1) + " || " +
|
||||
"(p1)" +
|
||||
")",
|
||||
guard.render());
|
||||
}
|
||||
|
||||
// currently not able to find optimal solution
|
||||
|
@ -833,7 +851,27 @@ public class HoistingProcessorTest extends AbstractXtextTests {
|
|||
//assertEquals("(" + keyword("a", 1) + " || (" + keyword("c", 3) + " && " + eof(3) + ") || ((p0) && (p2))) && (" + keyword("c", 1) + " || ((p0) && (p3))) && (" + keyword("d", 3) + " || (p1))", guard.render());
|
||||
|
||||
// still valid but non-optimal
|
||||
assertEquals("(" + keyword("a", 1) + " || (" + keyword("a", 3)+ " && " + keyword("b", 3) + " && " + keyword("c", 3) + " && " + eof(3) + ") || ((p0) && (p2))) && (" + keyword("b", 1) + " || (" + keyword("a", 3)+ " && " + keyword("b", 3) + " && " + keyword("c", 3) + " && " + eof(3) + ") || ((p0) && (p3))) && (" + keyword("d", 3) + " || (p1))", guard.render());
|
||||
assertEquals(
|
||||
"(" +
|
||||
"(" +
|
||||
keyword("a", 3) + " && " +
|
||||
keyword("b", 3) + " && " +
|
||||
keyword("c", 3) + " && " +
|
||||
eof(3) +
|
||||
") || (" +
|
||||
"(p0) && (" +
|
||||
keyword("a", 1) + " || " +
|
||||
"(p2)" +
|
||||
") && (" +
|
||||
keyword("b", 1) + " || " +
|
||||
"(p3)" +
|
||||
")" +
|
||||
")" +
|
||||
") && (" +
|
||||
keyword("d", 3) + " || " +
|
||||
"(p1)" +
|
||||
")",
|
||||
guard.render());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -31,9 +31,19 @@ public class AlternativesGuard implements HoistingGuard {
|
|||
}
|
||||
|
||||
public AlternativesGuard(List<PathGuard> paths) {
|
||||
// collapsing nested alternatives might reduce output size
|
||||
// -> try both and use smaller one
|
||||
|
||||
this.paths = paths;
|
||||
int lengthWithoutCollapse = render().length();
|
||||
this.paths = PathGuard.collapse(paths);
|
||||
int lengthWithCollapse = render().length();
|
||||
|
||||
if (lengthWithoutCollapse < lengthWithCollapse)
|
||||
this.paths = paths;
|
||||
}
|
||||
|
||||
|
||||
// package private so PathGuard can access this method
|
||||
List<PathGuard> getPaths() {
|
||||
return paths;
|
||||
|
|
|
@ -28,8 +28,10 @@ public class TokenSequenceGuard implements TokenGuard {
|
|||
|
||||
public TokenSequenceGuard(Collection<? extends TokenGuard> sequence) {
|
||||
Set<Integer> checkedPositions = new HashSet<>();
|
||||
// remove all guards from sequences who's positions are already in the sequence
|
||||
this.sequence = sequence.stream()
|
||||
.flatMap(g -> {
|
||||
// special case: reduce TokenSequenceGuards
|
||||
if (g instanceof TokenSequenceGuard) {
|
||||
return ((TokenSequenceGuard) g).sequence.stream()
|
||||
.filter(s -> !s.getPositions().stream()
|
||||
|
@ -65,7 +67,7 @@ public class TokenSequenceGuard implements TokenGuard {
|
|||
@Override
|
||||
public String render() {
|
||||
if (sequence.size() == 1) {
|
||||
return sequence.stream().findAny().get().render();
|
||||
return sequence.stream().findAny().get().render();
|
||||
} else {
|
||||
return render(ContextConnective.DISJUNCTION);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue