added support for enum rules in hoisting code

This commit is contained in:
overflowerror 2021-11-27 19:44:38 +01:00
parent 7f352990a4
commit ef91f872ef
5 changed files with 19 additions and 12 deletions

View file

@ -209,7 +209,7 @@ public class HoistingProcessorTest extends AbstractXtextTests {
// @formatter:off
String model =
MODEL_PREAMBLE +
"S: E $$ p0 $$?=> 's';\n" +
"S: e=E $$ p0 $$?=> 's';\n" +
"enum E: A='a' | B='b';";
// @formatter:off
XtextResource resource = getResourceFromString(model);
@ -313,8 +313,8 @@ public class HoistingProcessorTest extends AbstractXtextTests {
// @formatter:off
String model =
MODEL_PREAMBLE +
"S: $$ p0 $$?=> E1 |\n" +
" | $$ p1 $$?=> E2 ;\n" +
"S: $$ p0 $$?=> e1=E1 \n" +
" | $$ p1 $$?=> e2=E2 ;\n" +
"enum E1: A='a' | B='b'; \n" +
"enum E2: C='c' | D='d';";
// @formatter:off
@ -325,7 +325,7 @@ public class HoistingProcessorTest extends AbstractXtextTests {
HoistingGuard guard = hoistingProcessor.findGuardForElement(rule.getAlternatives());
assertFalse(guard.isTrivial());
assertTrue(guard.hasTerminal());
assertEquals("(((" + getSyntaxForKeywordToken("a", 1) + " && " + getSyntaxForKeywordToken("b", 1) + ") || (p0) && ((" + getSyntaxForKeywordToken("c", 1) + " && " + getSyntaxForKeywordToken("d", 1) + ") || (p1)))", guard.render());
assertEquals("(((" + getSyntaxForKeywordToken("a", 1) + " && " + getSyntaxForKeywordToken("b", 1) + ") || (p0)) && ((" + getSyntaxForKeywordToken("c", 1) + " && " + getSyntaxForKeywordToken("d", 1) + ") || (p1)))", guard.render());
}
@Test
@ -333,8 +333,8 @@ public class HoistingProcessorTest extends AbstractXtextTests {
// @formatter:off
String model =
MODEL_PREAMBLE +
"S: $$ p0 $$?=> E 'a' | \n" +
" | $$ p1 $$?=> E 'b' ;\n" +
"S: $$ p0 $$?=> e=E 'a' \n" +
" | $$ p1 $$?=> e=E 'b' ;\n" +
"enum E: A='a' | B='b'; ";
// @formatter:off
XtextResource resource = getResourceFromString(model);

View file

@ -19,13 +19,13 @@ import java.util.stream.Collectors;
import org.apache.log4j.Logger;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.AbstractSemanticPredicate;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.JavaAction;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.XtextFactory;
@ -200,7 +200,7 @@ public class HoistingProcessor {
// issue: groupCache can't be Concurrent because of possible recursive calls to computeIfAbent
// solution: atomic section
public synchronized HoistingGuard findGuardForRule(ParserRule rule) {
public synchronized HoistingGuard findGuardForRule(AbstractRule rule) {
HoistingGuard guard = ruleCache.get(rule.getName());
if (guard == null) {
guard = findGuardForElement(rule.getAlternatives());
@ -276,9 +276,10 @@ public class HoistingProcessor {
return new PredicateGuard((AbstractSemanticPredicate) element);
} else if (Token.isToken(element)) {
return HoistingGuard.terminal();
} else if (isParserRuleCall(element)) {
} else if (isParserRuleCall(element) ||
isEnumRuleCall(element)) {
RuleCall call = (RuleCall) element;
return findGuardForRule((ParserRule) call.getRule());
return findGuardForRule(call.getRule());
} else if (element instanceof Action) {
return HoistingGuard.unguarded();
} else if (element instanceof JavaAction) {

View file

@ -156,7 +156,8 @@ public class TokenAnalysis {
do {
if (Token.isToken(path)) {
current.add(path);
} else if (isParserRuleCall(path)) {
} else if (isParserRuleCall(path) ||
isEnumRuleCall(path)) {
// path doesn't need length, because we're going to check that anyway in this function
current = getTokenForIndexes(((RuleCall) path).getRule().getAlternatives(), current, false);
} else if (path instanceof Assignment) {

View file

@ -10,6 +10,7 @@ package org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.token;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.EnumLiteralDeclaration;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.TerminalRule;
@ -25,6 +26,8 @@ public interface Token {
return true;
} else if (element instanceof RuleCall) {
return (((RuleCall) element).getRule() instanceof TerminalRule);
} else if (element instanceof EnumLiteralDeclaration) {
return true;
} else {
return false;
}
@ -38,6 +41,8 @@ public interface Token {
if (rule instanceof TerminalRule) {
return new TerminalRuleToken((TerminalRule) rule, position);
}
} else if (element instanceof EnumLiteralDeclaration) {
return new KeywordToken(((EnumLiteralDeclaration) element).getLiteral(), position);
}
throw new NotATokenException();

View file

@ -642,7 +642,7 @@ public abstract class AbstractAntlrGrammarGenerator {
{
if ((it instanceof ParserRule)) {
_builder.append("// Guard: ");
String _renderDescription = this._hoistingProcessor.findGuardForRule(((ParserRule)it)).renderDescription();
String _renderDescription = this._hoistingProcessor.findGuardForRule(it).renderDescription();
_builder.append(_renderDescription);
_builder.newLineIfNotEmpty();
}