Skip to content

Commit

Permalink
#2178 Adapt to using the new BNF representation
Browse files Browse the repository at this point in the history
  • Loading branch information
homedirectory committed Feb 23, 2024
1 parent 6f4a070 commit 97a41dc
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 70 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package fielden.platform.eql;

import fielden.platform.eql.fling.BNF;
import fielden.platform.eql.fling.BnfToG4;
import fielden.platform.eql.fling.BnfToHtml;
import fielden.platform.eql.fling.BnfToText;
import il.ac.technion.cs.fling.EBNF;
import il.ac.technion.cs.fling.internal.grammar.rules.Terminal;
import il.ac.technion.cs.fling.internal.grammar.rules.Variable;
import ua.com.fielden.platform.entity.query.fluent.EntityQueryProgressiveInterfaces.ICompoundCondition0;
Expand All @@ -17,8 +17,8 @@
import static fielden.platform.eql.CanonicalEqlGrammar.EqlTerminal.values;
import static fielden.platform.eql.CanonicalEqlGrammar.EqlTerminal.*;
import static fielden.platform.eql.CanonicalEqlGrammar.EqlVariable.*;
import static fielden.platform.eql.fling.BNF.Fluent.start;
import static fielden.platform.eql.fling.BnfVerifier.verifyBnf;
import static il.ac.technion.cs.fling.grammars.api.BNFAPI.bnf;
import static il.ac.technion.cs.fling.internal.grammar.rules.Quantifiers.noneOrMore;
import static il.ac.technion.cs.fling.internal.grammar.rules.Quantifiers.optional;

Expand All @@ -42,7 +42,7 @@ public final class CanonicalEqlGrammar {
* <b>NOTE</b>: Should <b>not</b> be used for fluent API generation but for <b>reference</b> only.
*/
// @formatter:off
public static final EBNF canonical_bnf = bnf().
public static final BNF canonical_bnf =
start(Query).

specialize(Query).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package fielden.platform.eql.fling;

import il.ac.technion.cs.fling.EBNF;
import fielden.platform.eql.fling.BNF.Rule;
import il.ac.technion.cs.fling.internal.grammar.rules.*;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Function;

import static java.util.stream.Collectors.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toMap;
import static org.apache.commons.lang3.StringUtils.uncapitalize;

/**
Expand All @@ -19,14 +19,14 @@
*/
public class BnfToG4 {

protected final EBNF bnf;
protected final BNF bnf;
protected final String grammarName;
protected final Map<Terminal, /*rule name*/ String> lexerRules;

public BnfToG4(EBNF bnf, String grammarName) {
public BnfToG4(BNF bnf, String grammarName) {
this.bnf = bnf;
this.grammarName = grammarName;
this.lexerRules = bnf.Σ.stream().map(tok -> tok.terminal).distinct()
this.lexerRules = bnf.tokens().stream().map(tok -> tok.terminal).distinct()
.collect(toMap(Function.identity(), t -> t.name().toUpperCase()));
}

Expand All @@ -41,16 +41,9 @@ public String bnfToG4() {
var sb = new StringBuilder();

sb.append("grammar %s;\n\n".formatted(grammarName));
sb.append("start : %s EOF;\n\n".formatted(convert(bnf.ε)));

bnf.rules()
.collect(groupingBy(rule -> rule.variable, LinkedHashMap::new, toList()))
.entrySet().stream()
.map(entry -> {
var variable = entry.getKey();
var rules = entry.getValue();
return new ERule(variable, rules.stream().flatMap(ERule::bodies).toList());
})
sb.append("start : %s EOF;\n\n".formatted(convert(bnf.start())));

bnf.rules().stream()
.map(this::convert)
.forEach(rule -> {
sb.append(rule);
Expand All @@ -73,11 +66,11 @@ public String bnfToG4() {
return sb.toString();
}

protected String convert(ERule eRule) {
Function<String, String> labeler = isSingleTerminalRule(eRule) ? s -> "token=" + s : Function.identity();
protected String convert(Rule rule) {
Function<String, String> labeler = isSingleTerminalRule(rule) ? s -> "token=" + s : Function.identity();
return "%s :\n %s\n;".formatted(
convert(eRule.variable),
eRule.bodies().map(this::convert).map(labeler).collect(joining("\n | ")));
convert(rule.lhs()),
rule.rhs().map(this::convert).map(labeler).collect(joining("\n | ")));
}

protected String convert(Body body) {
Expand Down Expand Up @@ -117,8 +110,12 @@ protected String convert(Quantifier quantifier) {
return quantifier.symbols().map(this::convert).collect(joining(" ", "(", ")" + q));
}

static boolean isSingleTerminalRule(final ERule rule) {
return rule.bodies().allMatch(body -> body.size() == 1 && (body.getFirst().isTerminal() || body.getFirst().isToken()));
static boolean isSingleTerminalRule(final Rule rule) {
return switch (rule) {
case BNF.Specialization $ -> false;
case BNF.Derivation derivation -> derivation.rhs()
.allMatch(body -> body.size() == 1 && (body.getFirst().isTerminal() || body.getFirst().isToken()));
};
}

protected static <T> T fail(String formatString, Object... args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package fielden.platform.eql.fling;

import il.ac.technion.cs.fling.EBNF;
import il.ac.technion.cs.fling.internal.grammar.rules.*;
import il.ac.technion.cs.fling.internal.grammar.types.*;
import j2html.tags.DomContent;

import java.util.LinkedHashMap;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static j2html.TagCreator.*;
import static java.util.stream.Collectors.groupingBy;

/**
* Converts {@link EBNF} instances to HTML.
* Converts {@link BNF} instances to HTML.
*/
public class BnfToHtml {

Expand All @@ -29,23 +25,15 @@ public class BnfToHtml {

public BnfToHtml() {}

public String bnfToHtml(EBNF ebnf) {
public String bnfToHtml(BNF bnf) {
// @formatter:off
return document(
html(
head(makeStyle()),
body(
table(
each(withDelimiter(
ebnf.rules()
.collect(groupingBy(rule -> rule.variable, LinkedHashMap::new, Collectors.toList()))
.entrySet().stream()
.map(entry -> {
var variable = entry.getKey();
var rules = entry.getValue();
return new ERule(variable, rules.stream().flatMap(ERule::bodies).toList());
})
.map(this::toHtml),
bnf.rules().stream().map(this::toHtml),
tr(td(), td()).withClass(DELIMITER_ROW_CLASS)))
)
)
Expand Down Expand Up @@ -98,11 +86,11 @@ protected DomContent makeStyle() {
return style(sb.toString());
}

protected DomContent toHtml(ERule eRule) {
protected DomContent toHtml(BNF.Rule rule) {
var first = tr(
td(a(eRule.variable.name()).attr("name", eRule.variable.name()).withClass(NONTERMINAL_LHS_CLASS)),
td(a(rule.lhs().name()).attr("name", rule.lhs().name()).withClass(NONTERMINAL_LHS_CLASS)),
td(""));
var rest = eRule.bodies().map(this::toHtml);
var rest = rule.rhs().map(this::toHtml);
return each(first, each(rest));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,42 +1,29 @@
package fielden.platform.eql.fling;

import il.ac.technion.cs.fling.EBNF;
import il.ac.technion.cs.fling.internal.grammar.rules.*;
import il.ac.technion.cs.fling.internal.grammar.types.ClassParameter;
import il.ac.technion.cs.fling.internal.grammar.types.Parameter;
import il.ac.technion.cs.fling.internal.grammar.types.StringTypeParameter;
import il.ac.technion.cs.fling.internal.grammar.types.VarargsClassParameter;

import java.util.LinkedHashMap;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;

/**
* Converts {@link EBNF} instances to a human-readable text format.
* Converts {@link BNF} instances to a human-readable text format.
*/
public class BnfToText {

public BnfToText() {}

public String bnfToText(EBNF ebnf) {
return ebnf.rules()
.collect(groupingBy(rule -> rule.variable, LinkedHashMap::new, Collectors.toList()))
.entrySet().stream()
.map(entry -> {
var variable = entry.getKey();
var rules = entry.getValue();
return new ERule(variable, rules.stream().flatMap(ERule::bodies).toList());
})
.map(this::toString).collect(joining("\n\n"));
public String bnfToText(BNF ebnf) {
return ebnf.rules().stream().map(this::toString).collect(joining("\n\n"));
}

protected String toString(ERule eRule) {
final int prefixLen = eRule.variable.name().length();
return eRule.bodies()
protected String toString(BNF.Rule rule) {
final int prefixLen = rule.lhs().name().length();
return rule.rhs()
.map(this::toString)
.collect(joining("\n%s | ".formatted(" ".repeat(prefixLen)), "%s = ".formatted(eRule.variable), ";"));
.collect(joining("\n%s | ".formatted(" ".repeat(prefixLen)), "%s = ".formatted(rule.lhs().name()), ";"));
}

protected String toString(final Body body) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package fielden.platform.eql.fling;

import il.ac.technion.cs.fling.EBNF;
import il.ac.technion.cs.fling.internal.grammar.rules.ERule;
import fielden.platform.eql.fling.BNF.Rule;
import il.ac.technion.cs.fling.internal.grammar.rules.Variable;
import org.apache.commons.collections4.CollectionUtils;

import java.util.Collection;
import java.util.stream.Collectors;

import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toSet;

public final class BnfVerifier {

public static void verifyBnf(EBNF bnf) {
var rhsVars = bnf.rules().flatMap(ERule::variables).collect(Collectors.toSet());
var lhsVars = bnf.rules().map(rule -> rule.variable).collect(Collectors.toSet());
public static void verifyBnf(BNF bnf) {
var rhsVars = bnf.rules().stream().flatMap(Rule::variables).collect(toSet());
var lhsVars = bnf.rules().stream().map(Rule::lhs).collect(toSet());
final Collection<Variable> diff = CollectionUtils.subtract(rhsVars, lhsVars);
if (!diff.isEmpty()) {
throw new RuntimeException("BNF uses non-terminals with no productions: { %s }".formatted(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ private static void generate(final String[] args) throws Exception {
}

public static void printBNF() {
System.out.println(new BnfToText().bnfToText(bnf));
// switched to our own BNF representation so this won't work
// System.out.println(new BnfToText().bnfToText(bnf));
}

private static String formatSource(String s, @Nullable Formatter formatter) throws FormatterException {
Expand Down

0 comments on commit 97a41dc

Please sign in to comment.