From aad95fa6703a6240da630e033e1973c65b9c77f4 Mon Sep 17 00:00:00 2001 From: overflowerror Date: Thu, 20 Jan 2022 14:00:32 +0100 Subject: [PATCH] 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 --- .../hoisting/HoistingProcessorTest.java | 26 ++++++++++++++++--- .../hoisting/pathAnalysis/TokenAnalysis.java | 3 ++- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingProcessorTest.java b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingProcessorTest.java index b544165c1..44f2d68c4 100644 --- a/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingProcessorTest.java +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingProcessorTest.java @@ -1087,8 +1087,6 @@ public class HoistingProcessorTest extends AbstractXtextTests { // @formatter:off String model = MODEL_PREAMBLE + - "tokenLimit 4\n" + - "hoistingDebug\n" + "S: a=A ;\n" + "A: $$ p0 $$?=> 'a' \n" + " | $$ p1 $$?=> 'a' s=S ;\n"; @@ -1109,8 +1107,6 @@ public class HoistingProcessorTest extends AbstractXtextTests { // @formatter:off String model = MODEL_PREAMBLE + - "tokenLimit 4\n" + - "hoistingDebug\n" + "S: $$ p0 $$?=> 'a' \n" + " | $$ p1 $$?=> 'a' s=S ;\n"; // @formatter:off @@ -1124,4 +1120,26 @@ public class HoistingProcessorTest extends AbstractXtextTests { assertTrue(guard.hasTerminal()); 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()); + } } diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/pathAnalysis/TokenAnalysis.java b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/pathAnalysis/TokenAnalysis.java index 0a1f44c75..b4cccbba1 100644 --- a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/pathAnalysis/TokenAnalysis.java +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/pathAnalysis/TokenAnalysis.java @@ -185,7 +185,8 @@ public class TokenAnalysis { log.info("context element: " + abstractElementToShortString(element)); TokenAnalysisPaths path = new TokenAnalysisPaths(prefix); 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 (callStack.contains(element) && !path.hasProgress()) { throw new EmptyRecursionPathInContextAnalysisException("no progress in recursion");