removed unnecessary parenthesis from rendered output

This commit is contained in:
overflowerror 2021-12-17 21:52:25 +01:00
parent be80d5ffbc
commit 2726ec0e09
8 changed files with 90 additions and 31 deletions

View file

@ -9,6 +9,7 @@
package org.eclipse.xtext.xtext.generator.parser.antlr; package org.eclipse.xtext.xtext.generator.parser.antlr;
import org.eclipse.xtext.JavaCode; import org.eclipse.xtext.JavaCode;
import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.guards.Guard;
/** /**
* @author overflow - Initial contribution and API * @author overflow - Initial contribution and API
@ -18,4 +19,19 @@ public class JavaCodeUtils {
String source = code.getSource(); String source = code.getSource();
return source.substring(2, source.length() - 2); return source.substring(2, source.length() - 2);
} }
static public String formatCodeForGrammar(String code) {
return "$$ " + code + " $$";
}
static public String formatPredicateForGrammar(String predicate) {
return formatCodeForGrammar(
// remove parentheses
predicate.substring(1, predicate.length() - 1)
);
}
static public String formatGuardForGrammar(Guard guard) {
return formatPredicateForGrammar(guard.render());
}
} }

View file

@ -39,6 +39,7 @@ import org.eclipse.xtext.util.Tuples;
import static org.eclipse.xtext.GrammarUtil.*; import static org.eclipse.xtext.GrammarUtil.*;
import org.eclipse.xtext.xtext.generator.parser.antlr.JavaCodeUtils;
import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.NestedPrefixAlternativesException; import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.NestedPrefixAlternativesException;
import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.OptionalCardinalityWithoutContextException; import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.OptionalCardinalityWithoutContextException;
import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.TokenAnalysisAbortedException; import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.exceptions.TokenAnalysisAbortedException;
@ -116,7 +117,7 @@ public class HoistingProcessor {
private AbstractElement getNopElement() { private AbstractElement getNopElement() {
JavaCode virtualJavaCodeForAction = XtextFactory.eINSTANCE.createJavaCode(); JavaCode virtualJavaCodeForAction = XtextFactory.eINSTANCE.createJavaCode();
virtualJavaCodeForAction.setSource("$$ /* nop */ $$"); virtualJavaCodeForAction.setSource(JavaCodeUtils.formatCodeForGrammar("/* nop */"));
JavaAction virtualNopJavaAction = XtextFactory.eINSTANCE.createJavaAction(); JavaAction virtualNopJavaAction = XtextFactory.eINSTANCE.createJavaAction();
virtualNopJavaAction.setCode(virtualJavaCodeForAction); virtualNopJavaAction.setCode(virtualJavaCodeForAction);
@ -145,7 +146,7 @@ public class HoistingProcessor {
if (!guard.isTrivial()) { if (!guard.isTrivial()) {
JavaCode virtualJavaCodeForPredicate = XtextFactory.eINSTANCE.createJavaCode(); JavaCode virtualJavaCodeForPredicate = XtextFactory.eINSTANCE.createJavaCode();
virtualJavaCodeForPredicate.setSource("$$ " + guard.render() + " $$"); virtualJavaCodeForPredicate.setSource(JavaCodeUtils.formatGuardForGrammar(guard));
renderedVirtualPredicate = XtextFactory.eINSTANCE.createGatedSemanticPredicate(); renderedVirtualPredicate = XtextFactory.eINSTANCE.createGatedSemanticPredicate();
renderedVirtualPredicate.setCode(virtualJavaCodeForPredicate); renderedVirtualPredicate.setCode(virtualJavaCodeForPredicate);
@ -234,9 +235,11 @@ public class HoistingProcessor {
.collect(Collectors.toList()) .collect(Collectors.toList())
) )
.map(TokenSequenceGuard::new) .map(TokenSequenceGuard::new)
.map(TokenGuard::reduce)
.collect(Collectors.toList()) .collect(Collectors.toList())
) )
.map(AlternativeTokenSequenceGuard::new), .map(AlternativeTokenSequenceGuard::new)
.map(TokenGuard::reduce),
guards.stream(), guards.stream(),
(TokenGuard tokenGuard, MergedPathGuard pathGuard) -> Tuples.pair(tokenGuard, pathGuard) (TokenGuard tokenGuard, MergedPathGuard pathGuard) -> Tuples.pair(tokenGuard, pathGuard)
).map(p -> new PathGuard(p.getFirst(), p.getSecond())) ).map(p -> new PathGuard(p.getFirst(), p.getSecond()))

View file

@ -16,30 +16,31 @@ import java.util.stream.Collectors;
* @author overflow - Initial contribution and API * @author overflow - Initial contribution and API
*/ */
public class AlternativeTokenSequenceGuard implements TokenGuard { public class AlternativeTokenSequenceGuard implements TokenGuard {
private Collection<? extends TokenSequenceGuard> alternatives; private Collection<? extends TokenGuard> alternatives;
public AlternativeTokenSequenceGuard(Collection<? extends TokenSequenceGuard> alternatives) { public AlternativeTokenSequenceGuard(Collection<? extends TokenGuard> alternatives) {
this.alternatives = alternatives; this.alternatives = alternatives;
} }
public TokenGuard reduce() {
if (alternatives.size() == 1) {
return alternatives.stream().findAny().get();
} else {
return this;
}
}
@Override @Override
public String render() { public String render() {
boolean addParentheses = alternatives.size() != 1; if (alternatives.size() != 1) {
String result = ""; return "(" +
alternatives.stream()
if (addParentheses) { .map(TokenGuard::render)
result += "("; .collect(Collectors.joining(" && ")) +
")";
} else {
return alternatives.stream().findAny().get().render();
} }
result += alternatives.stream()
.map(TokenGuard::render)
.collect(Collectors.joining(" && "));
if (addParentheses) {
result += ")";
}
return result;
} }
@Override @Override

View file

@ -31,7 +31,7 @@ public class MergedPathGuard implements HoistingGuard {
pathGuards.addAll(mergedPathGuard.pathGuards); pathGuards.addAll(mergedPathGuard.pathGuards);
} }
HoistingGuard simplify() { HoistingGuard reduce() {
if (pathGuards.size() == 1) { if (pathGuards.size() == 1) {
return pathGuards.get(0); return pathGuards.get(0);
} else { } else {
@ -49,13 +49,15 @@ public class MergedPathGuard implements HoistingGuard {
if (pathGuards.size() == 1) { if (pathGuards.size() == 1) {
return pathGuards.get(0).render(); return pathGuards.get(0).render();
} else { } else {
return "(" + return "(" + renderWithoutParentheses() + ")";
pathGuards.stream()
.map(Guard::render)
.collect(Collectors.joining(" || ")) +
")";
} }
} }
String renderWithoutParentheses() {
return pathGuards.stream()
.map(Guard::render)
.collect(Collectors.joining(" || "));
}
@Override @Override
public boolean hasTerminal() { public boolean hasTerminal() {

View file

@ -42,7 +42,24 @@ public class PathGuard implements HoistingGuard {
@Override @Override
public String render() { public String render() {
// parentheses needed since tokenGuard is never empty // parentheses needed since tokenGuard is never empty
return "(" + tokenGuard.render() + " || " + hoistngGuard.render() + ")"; String result = "(";
if (tokenGuard instanceof TokenSequenceGuard) {
result += ((TokenSequenceGuard) tokenGuard).renderWithoutParenthesis();
} else {
result += tokenGuard.render();
}
result += " || ";
if (hoistngGuard instanceof MergedPathGuard) {
result += ((MergedPathGuard) hoistngGuard).renderWithoutParentheses();
} else {
result += hoistngGuard.render();
}
result += ")";
return result;
} }
public static List<PathGuard> collapse(List<PathGuard> paths) { public static List<PathGuard> collapse(List<PathGuard> paths) {
@ -57,7 +74,7 @@ public class PathGuard implements HoistingGuard {
// TODO: allow merged paths // TODO: allow merged paths
if (guard instanceof MergedPathGuard) { if (guard instanceof MergedPathGuard) {
guard = ((MergedPathGuard) guard).simplify(); guard = ((MergedPathGuard) guard).reduce();
} }
if (guard instanceof AlternativesGuard) { if (guard instanceof AlternativesGuard) {

View file

@ -19,6 +19,11 @@ public class SingleTokenGuard implements TokenGuard {
public SingleTokenGuard(Token token) { public SingleTokenGuard(Token token) {
this.token = token; this.token = token;
} }
@Override
public TokenGuard reduce() {
return this;
}
@Override @Override
public String render() { public String render() {

View file

@ -16,4 +16,6 @@ public interface TokenGuard extends Guard {
default boolean isTrivial() { default boolean isTrivial() {
return false; return false;
} }
TokenGuard reduce();
} }

View file

@ -22,6 +22,15 @@ public class TokenSequenceGuard implements TokenGuard {
this.sequence = sequence; this.sequence = sequence;
} }
@Override
public TokenGuard reduce() {
if (sequence.size() == 1) {
return sequence.stream().findAny().get();
} else {
return this;
}
}
@Override @Override
public String render() { public String render() {
boolean addParentheses = sequence.size() != 1; boolean addParentheses = sequence.size() != 1;
@ -31,9 +40,7 @@ public class TokenSequenceGuard implements TokenGuard {
result += "("; result += "(";
} }
result += sequence.stream() result += renderWithoutParenthesis();
.map(TokenGuard::render)
.collect(Collectors.joining(" || "));
if (addParentheses) { if (addParentheses) {
result += ")"; result += ")";
@ -42,6 +49,12 @@ public class TokenSequenceGuard implements TokenGuard {
return result; return result;
} }
public String renderWithoutParenthesis() {
return sequence.stream()
.map(TokenGuard::render)
.collect(Collectors.joining(" || "));
}
@Override @Override
public String toString() { public String toString() {
return "TokenSequenceGuard (\n" + return "TokenSequenceGuard (\n" +