mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-15 08:18:55 +00:00
removed unnecessary parenthesis from rendered output
This commit is contained in:
parent
be80d5ffbc
commit
2726ec0e09
8 changed files with 90 additions and 31 deletions
|
@ -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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -16,4 +16,6 @@ public interface TokenGuard extends Guard {
|
||||||
default boolean isTrivial() {
|
default boolean isTrivial() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenGuard reduce();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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" +
|
||||||
|
|
Loading…
Reference in a new issue