From 2cd6e454d7d05cb719e6c285257f4c5c473827a6 Mon Sep 17 00:00:00 2001 From: overflowerror Date: Thu, 20 Jan 2022 14:26:40 +0100 Subject: [PATCH] fixed problem with empty paths in token analysis empty paths are keep the state of the prefix including the empty flag which causes empty paths in alternatives to be lost. fix: create new token state with prefix (reset empty flag) --- .../hoisting/HoistingProcessorTest.java | 25 +++++++++++++++++-- .../hoisting/pathAnalysis/TokenAnalysis.java | 3 ++- 2 files changed, 25 insertions(+), 3 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 44f2d68c4..cb2708216 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 @@ -1122,11 +1122,10 @@ public class HoistingProcessorTest extends AbstractXtextTests { } @Test - public void testRepeatableContextWithEmptyPath_bug_expectCorrectResult() throws Exception { + public void testRepeatablyQuantifiedContextWithEmptyPath_bug_expectCorrectResult() throws Exception { // @formatter:off String model = MODEL_PREAMBLE + - "hoistingDebug\n" + "S: A C+ ;\n" + "A: $$ p0 $$?=> 'a' " + " | $$ p1 $$?=> 'a' 'b' ;\n" + @@ -1142,4 +1141,26 @@ public class HoistingProcessorTest extends AbstractXtextTests { assertTrue(guard.hasTerminal()); assertEquals("(((" + getSyntaxForEofToken(2) + " && " + getSyntaxForKeywordToken("c", 2) + ") || (p0)) && (" + getSyntaxForKeywordToken("b", 2) + " || (p1)))", guard.render()); } + + @Test + public void testRecursiveContextWithEmptyPath_bug_expectCorrectResult() throws Exception { + // @formatter:off + String model = + MODEL_PREAMBLE + + "S: a=A c=C ;\n" + + "A: $$ p0 $$?=> 'a' " + + " | $$ p1 $$?=> 'a' 'b' ;\n" + + "C: {C} \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 b4cccbba1..ef1c09206 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 @@ -317,7 +317,8 @@ public class TokenAnalysis { return result; } else { // Actions, Predicates, JavaActions, ... - return prefix; + // create new state with out empty flag + return new TokenAnalysisPaths(prefix); } }; }.doSwitch(path);