mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
fixed problem with repeated empty paths in context
no-progress-in-loop-error is interpreted as nested identity paths - this is wrong fix: enable endless loop shortcut in context analysis
This commit is contained in:
parent
9dfc0b4bfc
commit
aad95fa670
2 changed files with 24 additions and 5 deletions
|
@ -1087,8 +1087,6 @@ public class HoistingProcessorTest extends AbstractXtextTests {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
String model =
|
String model =
|
||||||
MODEL_PREAMBLE +
|
MODEL_PREAMBLE +
|
||||||
"tokenLimit 4\n" +
|
|
||||||
"hoistingDebug\n" +
|
|
||||||
"S: a=A ;\n" +
|
"S: a=A ;\n" +
|
||||||
"A: $$ p0 $$?=> 'a' \n" +
|
"A: $$ p0 $$?=> 'a' \n" +
|
||||||
" | $$ p1 $$?=> 'a' s=S ;\n";
|
" | $$ p1 $$?=> 'a' s=S ;\n";
|
||||||
|
@ -1109,8 +1107,6 @@ public class HoistingProcessorTest extends AbstractXtextTests {
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
String model =
|
String model =
|
||||||
MODEL_PREAMBLE +
|
MODEL_PREAMBLE +
|
||||||
"tokenLimit 4\n" +
|
|
||||||
"hoistingDebug\n" +
|
|
||||||
"S: $$ p0 $$?=> 'a' \n" +
|
"S: $$ p0 $$?=> 'a' \n" +
|
||||||
" | $$ p1 $$?=> 'a' s=S ;\n";
|
" | $$ p1 $$?=> 'a' s=S ;\n";
|
||||||
// @formatter:off
|
// @formatter:off
|
||||||
|
@ -1124,4 +1120,26 @@ public class HoistingProcessorTest extends AbstractXtextTests {
|
||||||
assertTrue(guard.hasTerminal());
|
assertTrue(guard.hasTerminal());
|
||||||
assertEquals("((" + getSyntaxForEofToken(2) + " || (p0)) && (" + getSyntaxForKeywordToken("a", 2) + " || (p1)))", guard.render());
|
assertEquals("((" + getSyntaxForEofToken(2) + " || (p0)) && (" + getSyntaxForKeywordToken("a", 2) + " || (p1)))", guard.render());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRepeatableContextWithEmptyPath_bug_expectCorrectResult() throws Exception {
|
||||||
|
// @formatter:off
|
||||||
|
String model =
|
||||||
|
MODEL_PREAMBLE +
|
||||||
|
"hoistingDebug\n" +
|
||||||
|
"S: A C+ ;\n" +
|
||||||
|
"A: $$ p0 $$?=> 'a' " +
|
||||||
|
" | $$ p1 $$?=> 'a' 'b' ;\n" +
|
||||||
|
"C: 'c'? ;\n";
|
||||||
|
// @formatter:off
|
||||||
|
XtextResource resource = getResourceFromString(model);
|
||||||
|
Grammar grammar = ((Grammar) resource.getContents().get(0));
|
||||||
|
hoistingProcessor.init(grammar);
|
||||||
|
AbstractRule rule = getRule(grammar, "A");
|
||||||
|
|
||||||
|
HoistingGuard guard = hoistingProcessor.findHoistingGuard(rule.getAlternatives());
|
||||||
|
assertFalse(guard.isTrivial());
|
||||||
|
assertTrue(guard.hasTerminal());
|
||||||
|
assertEquals("(((" + getSyntaxForEofToken(2) + " && " + getSyntaxForKeywordToken("c", 2) + ") || (p0)) && (" + getSyntaxForKeywordToken("b", 2) + " || (p1)))", guard.render());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,7 +185,8 @@ public class TokenAnalysis {
|
||||||
log.info("context element: " + abstractElementToShortString(element));
|
log.info("context element: " + abstractElementToShortString(element));
|
||||||
TokenAnalysisPaths path = new TokenAnalysisPaths(prefix);
|
TokenAnalysisPaths path = new TokenAnalysisPaths(prefix);
|
||||||
path.resetProgress();
|
path.resetProgress();
|
||||||
path = getTokenPaths(element, path, false, false, shortcutEndlessLoops);
|
// shortcut endless loops instead of throwing exception
|
||||||
|
path = getTokenPaths(element, path, false, false, true);
|
||||||
if (!path.isDone() && element != null) {
|
if (!path.isDone() && element != null) {
|
||||||
if (callStack.contains(element) && !path.hasProgress()) {
|
if (callStack.contains(element) && !path.hasProgress()) {
|
||||||
throw new EmptyRecursionPathInContextAnalysisException("no progress in recursion");
|
throw new EmptyRecursionPathInContextAnalysisException("no progress in recursion");
|
||||||
|
|
Loading…
Reference in a new issue