diff --git a/.github/workflows/iguana-build.yml b/.github/workflows/iguana-build.yml index 423294cc5..781f56865 100644 --- a/.github/workflows/iguana-build.yml +++ b/.github/workflows/iguana-build.yml @@ -1,4 +1,4 @@ -name: Java CI with Maven +name: Iguana build on: push: diff --git a/src/org/iguana/Iguana.java b/src/org/iguana/Iguana.java index b6b91a0be..21f885dfc 100644 --- a/src/org/iguana/Iguana.java +++ b/src/org/iguana/Iguana.java @@ -43,7 +43,8 @@ static class Command { @Option(names = "--package", description = "package name for the generated code") private String packageName; - @Option(names = {"--grammar-output"}, description = "The location where the grammar.json file will be generated.", required = true) + @Option(names = {"--grammar-output"}, description = "The location where the grammar.json file will be generated.", + required = true) private Path grammarOutputDirectory; public static void main(String[] args) { @@ -63,24 +64,30 @@ public Integer call() throws Exception { JsonSerializer.serialize(grammar, jsonPath); System.out.println("grammar.json file has been generated in " + jsonPath); Path typesOutputDirectory = outputDirectory.resolve(packageName.replace(".", "/")); - ParserGenerator parserGenerator = new ParserGenerator(grammarName, packageName, typesOutputDirectory.toAbsolutePath().toString()); + ParserGenerator parserGenerator = new ParserGenerator(grammarName, packageName, + typesOutputDirectory.toAbsolutePath().toString()); parserGenerator.generateGrammar(); } if (command.generateTypes) { Path typesOutputDirectory = outputDirectory.resolve(packageName.replace(".", "/")); - ParserGenerator parserGenerator = new ParserGenerator(grammarName, packageName, typesOutputDirectory.toAbsolutePath().toString()); + ParserGenerator parserGenerator = new ParserGenerator(grammarName, packageName, + typesOutputDirectory.toAbsolutePath().toString()); parserGenerator.generateParser(); - ParseTreeVisitorGenerator generator = new ParseTreeVisitorGenerator(grammar.toRuntimeGrammar(), grammarName, packageName, typesOutputDirectory.toAbsolutePath().toString()); + ParseTreeVisitorGenerator generator = new ParseTreeVisitorGenerator(grammar.toRuntimeGrammar(), grammarName, + packageName, typesOutputDirectory.toAbsolutePath().toString()); generator.generate(); } if (command.generateIDE) { - GenerateLangFiles generateLangFiles = new GenerateLangFiles(grammarName, outputDirectory.toAbsolutePath().toString()); + GenerateLangFiles generateLangFiles = new GenerateLangFiles(grammarName, + outputDirectory.toAbsolutePath().toString()); generateLangFiles.generate(); - GeneratePsiElements generatePSIElements = new GeneratePsiElements(grammar.toRuntimeGrammar(), grammarName, packageName, outputDirectory.toAbsolutePath().toString()); + GeneratePsiElements generatePSIElements = new GeneratePsiElements(grammar.toRuntimeGrammar(), grammarName, + packageName, outputDirectory.toAbsolutePath().toString()); generatePSIElements.generate(); - GenerateParserFiles generateParserFiles = new GenerateParserFiles(grammar.toRuntimeGrammar(), grammarName, packageName, outputDirectory.toAbsolutePath().toString()); + GenerateParserFiles generateParserFiles = new GenerateParserFiles(grammar.toRuntimeGrammar(), grammarName, + packageName, outputDirectory.toAbsolutePath().toString()); generateParserFiles.generate(); } diff --git a/src/org/iguana/datadependent/ast/AST.java b/src/org/iguana/datadependent/ast/AST.java index 0c1388298..915ee3bd7 100644 --- a/src/org/iguana/datadependent/ast/AST.java +++ b/src/org/iguana/datadependent/ast/AST.java @@ -163,7 +163,7 @@ public Object interpret(IEvaluatorContext ctx, Input input) { } } - public static Indent indent(Expression...args) { + public static Indent indent(Expression... args) { if (args.length != 1) throw new RuntimeException("args size should be one"); return indent(args[0]); } @@ -189,7 +189,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { NonPackedNode node = (NonPackedNode) var; - ctx.declareGlobalVariable(input.subString(node.getLeftExtent(), node.getRightExtent()), value.interpret(ctx, input)); + ctx.declareGlobalVariable(input.subString(node.getLeftExtent(), node.getRightExtent()), + value.interpret(ctx, input)); return null; } @@ -379,7 +380,7 @@ public Object interpret(IEvaluatorContext ctx, Input input) { } public static Pr1 pr1(Expression arg1, Expression arg2, Expression arg3) { - return new Pr1(arg1, arg2, arg3); + return new Pr1(arg1, arg2, arg3); } public static class Pr2 extends Expression.Call { @@ -575,7 +576,7 @@ public Object interpret(IEvaluatorContext ctx, Input input) { } } - public static Contains contains(Expression...args) { + public static Contains contains(Expression... args) { if (args.length != 2) throw new RuntimeException("args size should be two"); return contains(args[0], args[1]); } @@ -684,7 +685,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { throw new UnexpectedTypeOfArgumentException(this); @SuppressWarnings("unchecked") - Stack> s = (Stack>) value; + Stack> s = + (Stack>) value; java.lang.String key = (java.lang.String) arguments[0].interpret(ctx, input); diff --git a/src/org/iguana/datadependent/ast/Expression.java b/src/org/iguana/datadependent/ast/Expression.java index 758070022..2501b70a3 100644 --- a/src/org/iguana/datadependent/ast/Expression.java +++ b/src/org/iguana/datadependent/ast/Expression.java @@ -310,7 +310,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { @Override public java.lang.String toString() { - return "(" + listToString(Arrays.stream(elements).map(Object::toString).collect(Collectors.toList()), ",") + ")"; + return "(" + listToString(Arrays.stream(elements).map(Object::toString) + .collect(Collectors.toList()), ",") + ")"; } @Override @@ -519,7 +520,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { @Override public java.lang.String toString() { - return i != -1 ? java.lang.String.format("%s:%s = %s", id, i, exp) : java.lang.String.format("%s = %s", id, exp); + return i != -1 ? java.lang.String.format("%s:%s = %s", id, i, exp) + : java.lang.String.format("%s = %s", id, exp); } @Override @@ -659,7 +661,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { @Override public java.lang.String toString() { - // return ind + " == 0 || (" + first + " && " + lExt + " - " + index + " == 0) || indent(" + lExt + ") > " + ind; + // return ind + " == 0 || (" + first + " && " + lExt + " - " + index + " == 0) || + // indent(" + lExt + ") > " + ind; return java.lang.String.format("f(%s,%s,%s,%s)", index, ind, first, lExt); } @@ -796,7 +799,9 @@ public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof BinaryExpression)) return false; BinaryExpression other = (BinaryExpression) obj; - return this.lhs.equals(other.lhs) && this.rhs.equals(other.rhs) && Objects.equals(this.symbolName, other.symbolName); + return this.lhs.equals(other.lhs) && + this.rhs.equals(other.rhs) && + Objects.equals(this.symbolName, other.symbolName); } @Override @@ -1276,7 +1281,8 @@ public Object interpret(IEvaluatorContext ctx, Input input) { return input.subString(node.getLeftExtent(), node.getRightExtent()); } // In case of recognizer, we don't have a node. else if (value instanceof RecognizerResult) { - return input.subString(((RecognizerResult) value).getLeftExtent(), ((RecognizerResult) value).getRightExtent()); + return input.subString(((RecognizerResult) value).getLeftExtent(), + ((RecognizerResult) value).getRightExtent()); } else { throw new UnexpectedTypeOfArgumentException(this); } @@ -1284,7 +1290,8 @@ else if (value instanceof RecognizerResult) { @Override public java.lang.String toString() { - return i == -1 ? java.lang.String.format("%s.yield", label) : java.lang.String.format("%s:%d.yield", label, i); + return i == -1 ? java.lang.String.format("%s.yield", label) + : java.lang.String.format("%s:%d.yield", label, i); } @Override diff --git a/src/org/iguana/datadependent/ast/VariableDeclaration.java b/src/org/iguana/datadependent/ast/VariableDeclaration.java index 4d0299320..50ec53c27 100644 --- a/src/org/iguana/datadependent/ast/VariableDeclaration.java +++ b/src/org/iguana/datadependent/ast/VariableDeclaration.java @@ -97,7 +97,8 @@ public int hashCode() { @Override public String toString() { - return expression != null? (i != -1? String.format( "var %s:%s = %s", name, i, expression) : String.format( "var %s = %s", name, expression)) + return expression != null? (i != -1? String.format( "var %s:%s = %s", name, i, expression) : + String.format( "var %s = %s", name, expression)) : (i != -1? String.format("var %s:%s", name, i) : String.format("var %s", name)); } diff --git a/src/org/iguana/datadependent/env/persistent/PersistentEnvironment.java b/src/org/iguana/datadependent/env/persistent/PersistentEnvironment.java index bbe4211cf..3821f00d3 100644 --- a/src/org/iguana/datadependent/env/persistent/PersistentEnvironment.java +++ b/src/org/iguana/datadependent/env/persistent/PersistentEnvironment.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -34,151 +34,151 @@ import org.iguana.grammar.exception.UndefinedRuntimeValueException; public class PersistentEnvironment implements Environment { - - private final PersistentEnvironment parent; - - final private Map.Immutable bindings; - - static final Environment EMPTY = new PersistentEnvironment(null, (Map.Immutable) Map.Immutable.of()); - - private PersistentEnvironment(PersistentEnvironment parent, Map.Immutable bindings) { - this.parent = parent; - this.bindings = bindings; - } - - @Override - public boolean isEmpty() { - return bindings.isEmpty() && (parent == null || parent.isEmpty()); - } + + private final PersistentEnvironment parent; + + final private Map.Immutable bindings; + + static final Environment EMPTY = new PersistentEnvironment(null, Map.Immutable.of()); + + private PersistentEnvironment(PersistentEnvironment parent, Map.Immutable bindings) { + this.parent = parent; + this.bindings = bindings; + } + + @Override + public boolean isEmpty() { + return bindings.isEmpty() && (parent == null || parent.isEmpty()); + } + + @Override + public Environment pop() { + return parent; + } + + @Override + public Environment push() { + return new PersistentEnvironment(this, Map.Immutable.of()); + } + + @Override + public Environment _declare(String name, Object value) { + return new PersistentEnvironment(parent, bindings.__put(name, value)); + } + + @Override + public Environment declare(String[] names, Object[] values) { + Map.Immutable bindings = this.bindings; + int i = 0; + while (i < names.length) { + bindings = bindings.__put(names[i], values[i]); + i++; + } + return new PersistentEnvironment(parent, bindings); + } + + @Override + public Environment store(String name, Object value) { + + Object result = bindings.get(name); + + if (result == null) { + + if (parent == null) { + throw new UndeclaredVariableException(name); + } + + Environment parent = this.parent.store(name, value); + + if (parent == this.parent) { + return this; + } + + return new PersistentEnvironment((PersistentEnvironment) parent, bindings); + } + + Map.Immutable bindings = this.bindings.__put(name, value); + if (bindings == this.bindings) { + return this; + } + + return new PersistentEnvironment(parent, bindings); + } + + @Override + public Object lookup(String name) { + + Object value = bindings.get(name); + + if (value == null && parent != null) { + value = parent.lookup(name); + } + + if (value != null) { + + if (value == VariableDeclaration.defaultValue) { + throw UndefinedRuntimeValueException.instance; + } + + return value; + } + + throw new UndeclaredVariableException(name); + } + + @Override + public int hashCode() { + return (parent == null ? 0 : parent.hashCode()) + bindings.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (this == other) return true; + + if (!(other instanceof PersistentEnvironment)) return false; + + PersistentEnvironment that = (PersistentEnvironment) other; + + if (this.bindings == that.bindings || this.bindings.equals(that.bindings)) { + + if (this.parent == that.parent) { + return true; + } + + if (this.parent != null) { + return this.parent.equals(that.parent); + } + + return false; + } + + return false; + } + + @Override + public String toString() { + return (parent != null ? parent.toString() + " -> " : "() -> ") + + (bindings != null ? bindings.toString() : "()"); + } + + @Override + public Environment _declare(Object value) { + throw new RuntimeException("Unsupported with this type of environment!"); + } + + @Override + public Environment declare(Object[] values) { + throw new RuntimeException("Unsupported with this type of environment!"); + } + + @Override + public Environment store(int i, Object value) { + throw new RuntimeException("Unsupported with this type of environment!"); + } @Override - public Environment pop() { - return parent; - } - - @Override - public Environment push() { - return new PersistentEnvironment(this, Map.Immutable.of()); - } - - @Override - public Environment _declare(String name, Object value) { - return new PersistentEnvironment(parent, bindings.__put(name, value)); - } - - @Override - public Environment declare(String[] names, Object[] values) { - Map.Immutable bindings = this.bindings; - int i = 0; - while (i < names.length) { - bindings = bindings.__put(names[i], values[i]); - i++; - } - return new PersistentEnvironment(parent, bindings); - } - - @Override - public Environment store(String name, Object value) { - - Object result = bindings.get(name); - - if (result == null) { - - if (parent == null) { - throw new UndeclaredVariableException(name); - } - - Environment parent = this.parent.store(name, value); - - if (parent == this.parent) { - return this; - } - - return new PersistentEnvironment((PersistentEnvironment) parent, bindings); - } - - Map.Immutable bindings = this.bindings.__put(name, value); - if (bindings == this.bindings) { - return this; - } - - return new PersistentEnvironment(parent, bindings); - } - - @Override - public Object lookup(String name) { - - Object value = bindings.get(name); - - if (value == null && parent != null) { - value = parent.lookup(name); - } - - if (value != null) { - - if (value == VariableDeclaration.defaultValue) { - throw UndefinedRuntimeValueException.instance; - } - - return value; - } - - throw new UndeclaredVariableException(name); - } - - @Override - public int hashCode() { - return (parent == null ? 0 : parent.hashCode()) + bindings.hashCode(); - } - - @Override - public boolean equals(Object other) { - if (this == other) return true; - - if (!(other instanceof PersistentEnvironment)) return false; - - PersistentEnvironment that = (PersistentEnvironment) other; - - if (this.bindings == that.bindings || this.bindings.equals(that.bindings)) { - - if (this.parent == that.parent) { - return true; - } - - if (this.parent != null) { - return this.parent.equals(that.parent); - } - - return false; - } - - return false; - } - - @Override - public String toString() { - return (parent != null? parent.toString() + " -> " : "() -> ") - + (bindings != null? bindings.toString(): "()"); - } - - @Override - public Environment _declare(Object value) { - throw new RuntimeException("Unsupported with this type of environment!"); - } - - @Override - public Environment declare(Object[] values) { - throw new RuntimeException("Unsupported with this type of environment!"); - } - - @Override - public Environment store(int i, Object value) { - throw new RuntimeException("Unsupported with this type of environment!"); - } - - @Override - public Object lookup(int i) { - throw new RuntimeException("Unsupported with this type of environment!"); - } + public Object lookup(int i) { + throw new RuntimeException("Unsupported with this type of environment!"); + } } diff --git a/src/org/iguana/datadependent/env/simple/SimpleImmutableEnvironment.java b/src/org/iguana/datadependent/env/simple/SimpleImmutableEnvironment.java index 85eba1f4d..fd862f84b 100644 --- a/src/org/iguana/datadependent/env/simple/SimpleImmutableEnvironment.java +++ b/src/org/iguana/datadependent/env/simple/SimpleImmutableEnvironment.java @@ -169,7 +169,8 @@ public int hashCode() { @Override public String toString() { return (parent != null? parent.toString() + " -> " : "() -> ") - + (bindings != null? listToString(bindings.entrySet().stream().map(entry -> entry.getKey() + " : " + entry.getValue()).collect(Collectors.toList()), ";") + + (bindings != null? listToString(bindings.entrySet().stream() + .map(entry -> entry.getKey() + " : " + entry.getValue()).collect(Collectors.toList()), ";") : "()"); } diff --git a/src/org/iguana/datadependent/traversal/FreeVariableVisitor.java b/src/org/iguana/datadependent/traversal/FreeVariableVisitor.java index 43f581a58..be6fe68fc 100644 --- a/src/org/iguana/datadependent/traversal/FreeVariableVisitor.java +++ b/src/org/iguana/datadependent/traversal/FreeVariableVisitor.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -49,684 +49,691 @@ public class FreeVariableVisitor implements IAbstractASTVisitor, ISymbolVisitor, IConditionVisitor { - - /* - * Free variables of a symbol and updates to free variables - */ - private final Set freeVariables; - private final Set updates; - - public FreeVariableVisitor(Set freeVariables) { - this(freeVariables, null); - } - - public FreeVariableVisitor(Set freeVariables, Set updates) { - this.freeVariables = freeVariables; - this.updates = updates; - this.nonterminal_uses = null; - this.nonterminal_updates = null; - this.nonterminal_returns = null; - this.nonterminal_bindings = null; - } - - public void compute(RuntimeRule rule) { - io.usethesource.capsule.Set.Immutable env = io.usethesource.capsule.Set.Immutable.of(); - - List parameters = rule.getHead().getParameters(); - if (parameters != null) { - for (java.lang.String parameter : parameters) - env = env.__insert(parameter); - } - - io.usethesource.capsule.Set.Immutable _env = env; - - for (Symbol symbol : rule.getBody()) { - - symbol.setEnv(_env); - this.visitSymbol(symbol); - _env = symbol.getEnv(); - - symbol.setEmpty(); - } - - } - - /* - * State variable bindings of nonterminals in the rule - */ - private final Map> nonterminal_uses; - private final Map> nonterminal_updates; // Given assignments to state variables within a nonterminal - private final Map> nonterminal_returns; // Given uses of updated state variables of a nonterminal after a use of a nonterminal in all the rules - - private Map> nonterminal_bindings; // Given uses of updated state variables of a nonterminal after a use of the nonterminal in the current rule - - public FreeVariableVisitor(Map> nonterminal_uses, Map> nonterminal_updates, Map> nonterminal_returns) { - this.freeVariables = null; - this.updates = null; - this.nonterminal_uses = nonterminal_uses; - this.nonterminal_updates = nonterminal_updates; - this.nonterminal_returns = nonterminal_returns; - this.nonterminal_bindings = new HashMap<>(); - } - - public Map> computeBindings(RuntimeRule rule) { - initBindings(); - compute(rule); - return nonterminal_bindings; - } - - private void initBindings() { - this.nonterminal_bindings = new HashMap<>(); - } - - @Override - public Void visit(Boolean expression) { - return null; - } - - @Override - public Void visit(Integer expression) { - return null; - } - - @Override - public Void visit(Real expression) { - return null; - } - - @Override - public Void visit(String expression) { - return null; - } - - @Override - public Void visit(Not not) { - org.iguana.datadependent.ast.Expression expression = not.getExp(); - - expression.setEnv(not.getEnv()); - expression.accept(this); - return null; - } - - @Override - public Void visit(Tuple expression) { - - for (org.iguana.datadependent.ast.Expression element : expression.getElements()) { - element.setEnv(expression.getEnv()); - element.accept(this); - } - - return null; - } - - @Override - public Void visit(Name expression) { - java.lang.String name = expression.getName(); - - if (!expression.getEnv().contains(name)) - use(name); - - return null; - } - - private void use(java.lang.String name) { - if (freeVariables != null) - freeVariables.add(name); - - if (nonterminal_bindings != null && !nonterminal_bindings.isEmpty()) { - for (Nonterminal nonterminal : nonterminal_bindings.keySet()) { - if (nonterminal_updates.get(nonterminal).contains(name)) { - nonterminal_returns.get(nonterminal).add(name); - nonterminal_bindings.get(nonterminal).add(name); - } - } - } - } - - @Override - public Void visit(Call expression) { - - for (org.iguana.datadependent.ast.Expression argument : expression.getArguments()) { - argument.setEnv(expression.getEnv()); - argument.accept(this); - } - - return null; - } - - @Override - public Void visit(Assignment expression) { - - java.lang.String id = expression.getId(); - org.iguana.datadependent.ast.Expression exp = expression.getExpression(); - - if (!expression.getEnv().contains(id)) { - use(id); - update(id); - } - - exp.setEnv(expression.getEnv()); - exp.accept(this); - - return null; - } - - private void update(java.lang.String name) { - if (updates != null) - updates.add(name); - } - - @Override - public Void visit(LShiftANDEqZero expression) { - - org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); - - lhs.setEnv(expression.getEnv()); - lhs.accept(this); - - org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); - - rhs.setEnv(expression.getEnv()); - rhs.accept(this); - - return null; - } - - @Override - public Void visit(OrIndent expression) { - - org.iguana.datadependent.ast.Expression index = expression.getIndex(); - - index.setEnv(expression.getEnv()); - index.accept(this); - - org.iguana.datadependent.ast.Expression ind = expression.getIndent(); - - ind.setEnv(expression.getEnv()); - ind.accept(this); - - org.iguana.datadependent.ast.Expression first = expression.getFirst(); - - first.setEnv(expression.getEnv()); - first.accept(this); - - org.iguana.datadependent.ast.Expression lExt = expression.getLExt(); - - lExt.setEnv(expression.getEnv()); - lExt.accept(this); - - return null; - } - - @Override - public Void visit(AndIndent expression) { - - org.iguana.datadependent.ast.Expression index = expression.getIndex(); - - index.setEnv(expression.getEnv()); - index.accept(this); - - org.iguana.datadependent.ast.Expression first = expression.getFirst(); - - first.setEnv(expression.getEnv()); - first.accept(this); - - org.iguana.datadependent.ast.Expression lExt = expression.getLExt(); - - lExt.setEnv(expression.getEnv()); - lExt.accept(this); - - return null; - } - - @Override - public Void visit(Or expression) { - - org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); - - lhs.setEnv(expression.getEnv()); - lhs.accept(this); - - org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); - - rhs.setEnv(expression.getEnv()); - rhs.accept(this); - - return null; - } - - @Override - public Void visit(Add expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Subtract expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Multiply expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Divide expression) { - return visitBinaryExpression(expression); - } - - private Void visitBinaryExpression(BinaryExpression expression) { - org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); - - lhs.setEnv(expression.getEnv()); - lhs.accept(this); - - org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); - - rhs.setEnv(expression.getEnv()); - rhs.accept(this); - - return null; - } - - @Override - public Void visit(And expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Less expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(LessThanEqual expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Greater expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(GreaterThanEqual expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(Equal expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(NotEqual expression) { - return visitBinaryExpression(expression); - } - - @Override - public Void visit(LeftExtent expression) { - - java.lang.String name = java.lang.String.format(org.iguana.datadependent.ast.Expression.LeftExtent.format, expression.getLabel()); - - if (!expression.getEnv().contains(name)) - use(name); - - return null; - } - - @Override - public Void visit(RightExtent expression) { - - java.lang.String label = expression.getLabel(); - - if (!expression.getEnv().contains(label)) - use(label); - - return null; - } - - @Override - public Void visit(Yield expression) { - - java.lang.String label = expression.getLabel(); - - if (!expression.getEnv().contains(label)) - use(label); - - return null; - } - - @Override - public Void visit(Val expression) { - - java.lang.String label = expression.getLabel(); - - if (!expression.getEnv().contains(label)) - use(label); - - return null; - } - - @Override - public Void visit(EndOfFile expression) { - - org.iguana.datadependent.ast.Expression index = expression.getIndex(); - - index.setEnv(expression.getEnv()); - index.accept(this); - - return null; - } - - @Override - public Void visit(org.iguana.datadependent.ast.Expression.IfThenElse expression) { - - org.iguana.datadependent.ast.Expression condition = expression.getCondition(); - condition.setEnv(expression.getEnv()); - condition.accept(this); - - org.iguana.datadependent.ast.Expression thenPart = expression.getThenPart(); - thenPart.setEnv(expression.getEnv()); - thenPart.accept(this); - - org.iguana.datadependent.ast.Expression elsePart = expression.getElsePart(); - elsePart.setEnv(expression.getEnv()); - elsePart.accept(this); - - return null; - } - - @Override - public Void visit(VariableDeclaration declaration) { - - org.iguana.datadependent.ast.Expression expression = declaration.getExpression(); - - if (expression != null) { - expression.setEnv(declaration.getEnv()); - expression.accept(this); - } - - declaration.setEnv(declaration.getEnv().__insert(declaration.getName())); - - return null; - } - - @Override - public Void visit(org.iguana.datadependent.ast.Statement.VariableDeclaration statement) { - - VariableDeclaration declaration = statement.getDeclaration(); - - declaration.setEnv(statement.getEnv()); - declaration.accept(this); - - statement.setEnv(declaration.getEnv()); - - return null; - } - - @Override - public Void visit(Expression statement) { - - org.iguana.datadependent.ast.Expression expression = statement.getExpression(); - - expression.setEnv(statement.getEnv()); - expression.accept(this); - - return null; - } - - @Override - public Void visit(Align symbol) { - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - symbol.setEnv(sym.getEnv()); - - return null; - } - - @Override - public Void visit(Block symbol) { - - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - for (Symbol sym : symbol.getSymbols()) { - sym.setEnv(env); - visitSymbol(sym); - env = sym.getEnv(); - } - - return null; - } - - @Override - public Void visit(Code symbol) { - - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - Symbol sym = symbol.getSymbol(); - - sym.setEnv(env); - visitSymbol(sym); - env = sym.getEnv(); - - for (Statement statement : symbol.getStatements()) { - statement.setEnv(env); - statement.accept(this); - env = statement.getEnv(); - } - - symbol.setEnv(env); - - return null; - } - - @Override - public Void visit(Error error) { - return null; - } - - @Override - public Void visit(Conditional symbol) { - - Symbol sym = symbol.getSymbol(); - org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); - - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - sym.setEnv(env); - visitSymbol(sym); - - env = sym.getEnv(); - - expression.setEnv(env); - expression.accept(this); - - return null; - } - - @Override - public Void visit(IfThen symbol) { - - org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); - Symbol thenPart = symbol.getThenPart(); - - expression.setEnv(symbol.getEnv()); - expression.accept(this); - - thenPart.setEnv(symbol.getEnv()); - visitSymbol(thenPart); - - return null; - } - - @Override - public Void visit(IfThenElse symbol) { - - org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); - Symbol thenPart = symbol.getThenPart(); - Symbol elsePart = symbol.getElsePart(); - - expression.setEnv(symbol.getEnv()); - expression.accept(this); - - thenPart.setEnv(symbol.getEnv()); - visitSymbol(thenPart); - - elsePart.setEnv(symbol.getEnv()); - visitSymbol(thenPart); - - return null; - } - - @Override - public Void visit(Ignore symbol) { - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - symbol.setEnv(sym.getEnv()); - - return null; - } - - @Override - public Void visit(Nonterminal symbol) { - - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - if (symbol.getVariable() != null) - env = env.__insert(symbol.getVariable()); - - if (symbol.getArguments() != null) { - for (org.iguana.datadependent.ast.Expression argument : symbol.getArguments()) { - argument.setEnv(env); - argument.accept(this); - env = argument.getEnv(); - } - } - - if (nonterminal_uses != null && nonterminal_uses.containsKey(symbol)) { - for (java.lang.String parameter : nonterminal_uses.get(symbol)) - use(parameter); - } - - if (nonterminal_bindings != null - && !nonterminal_bindings.containsKey(symbol) - && nonterminal_updates.containsKey(symbol) ) - nonterminal_bindings.put(symbol, new HashSet<>()); - - symbol.setEnv(env); - - return null; - } - - @Override - public Void visit(Offside symbol) { - - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - symbol.setEnv(sym.getEnv()); - - return null; - } - - @Override - public Void visit(Terminal symbol) { - return null; - } - - @Override - public Void visit(While symbol) { - - org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); - Symbol body = symbol.getBody(); - - expression.setEnv(symbol.getEnv()); - expression.accept(this); - - body.setEnv(symbol.getEnv()); - visitSymbol(body); - - return null; - } - - @Override - public Void visit(Return symbol) { - org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); - - expression.setEnv(symbol.getEnv()); - expression.accept(this); - - symbol.setEnv(expression.getEnv()); - - return null; - } - - @Override - public Void visit(Alt symbol) { - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - for (Symbol sym : symbol.getSymbols()) { - sym.setEnv(env); - visitSymbol(sym); - } - - return null; - } - - @Override - public Void visit(Opt symbol) { - - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - return null; - } - - @Override - public Void visit(Plus symbol) { - - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - return null; - } - - @Override - public Void visit(Group symbol) { - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - for (Symbol sym : symbol.getSymbols()) { - sym.setEnv(env); - visitSymbol(sym); - env = sym.getEnv(); - } - - return null; - } - - @Override - public Void visit(Star symbol) { - - Symbol sym = symbol.getSymbol(); - - sym.setEnv(symbol.getEnv()); - visitSymbol(sym); - - return null; - } + + /* + * Free variables of a symbol and updates to free variables + */ + private final Set freeVariables; + private final Set updates; + + public FreeVariableVisitor(Set freeVariables) { + this(freeVariables, null); + } + + public FreeVariableVisitor(Set freeVariables, Set updates) { + this.freeVariables = freeVariables; + this.updates = updates; + this.nonterminal_uses = null; + this.nonterminal_updates = null; + this.nonterminal_returns = null; + this.nonterminal_bindings = null; + } + + public void compute(RuntimeRule rule) { + io.usethesource.capsule.Set.Immutable env = io.usethesource.capsule.Set.Immutable.of(); + + List parameters = rule.getHead().getParameters(); + if (parameters != null) { + for (java.lang.String parameter : parameters) + env = env.__insert(parameter); + } + + io.usethesource.capsule.Set.Immutable _env = env; + + for (Symbol symbol : rule.getBody()) { + + symbol.setEnv(_env); + this.visitSymbol(symbol); + _env = symbol.getEnv(); + + symbol.setEmpty(); + } + + } + + /* + * State variable bindings of nonterminals in the rule + */ + private final Map> nonterminal_uses; + // Given assignments to state variables within a nonterminal + private final Map> nonterminal_updates; + // Given uses of updated state variables of a nonterminal after a use of a nonterminal in all the rules + private final Map> nonterminal_returns; + // Given uses of updated state variables of a nonterminal after a use of the nonterminal in the current rule + private Map> nonterminal_bindings; + + public FreeVariableVisitor( + Map> nonterminal_uses, + Map> nonterminal_updates, + Map> nonterminal_returns + ) { + this.freeVariables = null; + this.updates = null; + this.nonterminal_uses = nonterminal_uses; + this.nonterminal_updates = nonterminal_updates; + this.nonterminal_returns = nonterminal_returns; + this.nonterminal_bindings = new HashMap<>(); + } + + public Map> computeBindings(RuntimeRule rule) { + initBindings(); + compute(rule); + return nonterminal_bindings; + } + + private void initBindings() { + this.nonterminal_bindings = new HashMap<>(); + } + + @Override + public Void visit(Boolean expression) { + return null; + } + + @Override + public Void visit(Integer expression) { + return null; + } + + @Override + public Void visit(Real expression) { + return null; + } + + @Override + public Void visit(String expression) { + return null; + } + + @Override + public Void visit(Not not) { + org.iguana.datadependent.ast.Expression expression = not.getExp(); + + expression.setEnv(not.getEnv()); + expression.accept(this); + return null; + } + + @Override + public Void visit(Tuple expression) { + + for (org.iguana.datadependent.ast.Expression element : expression.getElements()) { + element.setEnv(expression.getEnv()); + element.accept(this); + } + + return null; + } + + @Override + public Void visit(Name expression) { + java.lang.String name = expression.getName(); + + if (!expression.getEnv().contains(name)) + use(name); + + return null; + } + + private void use(java.lang.String name) { + if (freeVariables != null) + freeVariables.add(name); + + if (nonterminal_bindings != null && !nonterminal_bindings.isEmpty()) { + for (Nonterminal nonterminal : nonterminal_bindings.keySet()) { + if (nonterminal_updates.get(nonterminal).contains(name)) { + nonterminal_returns.get(nonterminal).add(name); + nonterminal_bindings.get(nonterminal).add(name); + } + } + } + } + + @Override + public Void visit(Call expression) { + + for (org.iguana.datadependent.ast.Expression argument : expression.getArguments()) { + argument.setEnv(expression.getEnv()); + argument.accept(this); + } + + return null; + } + + @Override + public Void visit(Assignment expression) { + + java.lang.String id = expression.getId(); + org.iguana.datadependent.ast.Expression exp = expression.getExpression(); + + if (!expression.getEnv().contains(id)) { + use(id); + update(id); + } + + exp.setEnv(expression.getEnv()); + exp.accept(this); + + return null; + } + + private void update(java.lang.String name) { + if (updates != null) + updates.add(name); + } + + @Override + public Void visit(LShiftANDEqZero expression) { + + org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); + + lhs.setEnv(expression.getEnv()); + lhs.accept(this); + + org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); + + rhs.setEnv(expression.getEnv()); + rhs.accept(this); + + return null; + } + + @Override + public Void visit(OrIndent expression) { + + org.iguana.datadependent.ast.Expression index = expression.getIndex(); + + index.setEnv(expression.getEnv()); + index.accept(this); + + org.iguana.datadependent.ast.Expression ind = expression.getIndent(); + + ind.setEnv(expression.getEnv()); + ind.accept(this); + + org.iguana.datadependent.ast.Expression first = expression.getFirst(); + + first.setEnv(expression.getEnv()); + first.accept(this); + + org.iguana.datadependent.ast.Expression lExt = expression.getLExt(); + + lExt.setEnv(expression.getEnv()); + lExt.accept(this); + + return null; + } + + @Override + public Void visit(AndIndent expression) { + + org.iguana.datadependent.ast.Expression index = expression.getIndex(); + + index.setEnv(expression.getEnv()); + index.accept(this); + + org.iguana.datadependent.ast.Expression first = expression.getFirst(); + + first.setEnv(expression.getEnv()); + first.accept(this); + + org.iguana.datadependent.ast.Expression lExt = expression.getLExt(); + + lExt.setEnv(expression.getEnv()); + lExt.accept(this); + + return null; + } + + @Override + public Void visit(Or expression) { + + org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); + + lhs.setEnv(expression.getEnv()); + lhs.accept(this); + + org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); + + rhs.setEnv(expression.getEnv()); + rhs.accept(this); + + return null; + } + + @Override + public Void visit(Add expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Subtract expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Multiply expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Divide expression) { + return visitBinaryExpression(expression); + } + + private Void visitBinaryExpression(BinaryExpression expression) { + org.iguana.datadependent.ast.Expression lhs = expression.getLhs(); + + lhs.setEnv(expression.getEnv()); + lhs.accept(this); + + org.iguana.datadependent.ast.Expression rhs = expression.getRhs(); + + rhs.setEnv(expression.getEnv()); + rhs.accept(this); + + return null; + } + + @Override + public Void visit(And expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Less expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(LessThanEqual expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Greater expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(GreaterThanEqual expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(Equal expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(NotEqual expression) { + return visitBinaryExpression(expression); + } + + @Override + public Void visit(LeftExtent expression) { + + java.lang.String name = java.lang.String.format(org.iguana.datadependent.ast.Expression.LeftExtent.format, + expression.getLabel()); + + if (!expression.getEnv().contains(name)) + use(name); + + return null; + } + + @Override + public Void visit(RightExtent expression) { + + java.lang.String label = expression.getLabel(); + + if (!expression.getEnv().contains(label)) + use(label); + + return null; + } + + @Override + public Void visit(Yield expression) { + + java.lang.String label = expression.getLabel(); + + if (!expression.getEnv().contains(label)) + use(label); + + return null; + } + + @Override + public Void visit(Val expression) { + + java.lang.String label = expression.getLabel(); + + if (!expression.getEnv().contains(label)) + use(label); + + return null; + } + + @Override + public Void visit(EndOfFile expression) { + + org.iguana.datadependent.ast.Expression index = expression.getIndex(); + + index.setEnv(expression.getEnv()); + index.accept(this); + + return null; + } + + @Override + public Void visit(org.iguana.datadependent.ast.Expression.IfThenElse expression) { + + org.iguana.datadependent.ast.Expression condition = expression.getCondition(); + condition.setEnv(expression.getEnv()); + condition.accept(this); + + org.iguana.datadependent.ast.Expression thenPart = expression.getThenPart(); + thenPart.setEnv(expression.getEnv()); + thenPart.accept(this); + + org.iguana.datadependent.ast.Expression elsePart = expression.getElsePart(); + elsePart.setEnv(expression.getEnv()); + elsePart.accept(this); + + return null; + } + + @Override + public Void visit(VariableDeclaration declaration) { + + org.iguana.datadependent.ast.Expression expression = declaration.getExpression(); + + if (expression != null) { + expression.setEnv(declaration.getEnv()); + expression.accept(this); + } + + declaration.setEnv(declaration.getEnv().__insert(declaration.getName())); + + return null; + } + + @Override + public Void visit(org.iguana.datadependent.ast.Statement.VariableDeclaration statement) { + + VariableDeclaration declaration = statement.getDeclaration(); + + declaration.setEnv(statement.getEnv()); + declaration.accept(this); + + statement.setEnv(declaration.getEnv()); + + return null; + } + + @Override + public Void visit(Expression statement) { + + org.iguana.datadependent.ast.Expression expression = statement.getExpression(); + + expression.setEnv(statement.getEnv()); + expression.accept(this); + + return null; + } + + @Override + public Void visit(Align symbol) { + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + symbol.setEnv(sym.getEnv()); + + return null; + } + + @Override + public Void visit(Block symbol) { + + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + for (Symbol sym : symbol.getSymbols()) { + sym.setEnv(env); + visitSymbol(sym); + env = sym.getEnv(); + } + + return null; + } + + @Override + public Void visit(Code symbol) { + + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + Symbol sym = symbol.getSymbol(); + + sym.setEnv(env); + visitSymbol(sym); + env = sym.getEnv(); + + for (Statement statement : symbol.getStatements()) { + statement.setEnv(env); + statement.accept(this); + env = statement.getEnv(); + } + + symbol.setEnv(env); + + return null; + } + + @Override + public Void visit(Error error) { + return null; + } + + @Override + public Void visit(Conditional symbol) { + + Symbol sym = symbol.getSymbol(); + org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); + + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + sym.setEnv(env); + visitSymbol(sym); + + env = sym.getEnv(); + + expression.setEnv(env); + expression.accept(this); + + return null; + } + + @Override + public Void visit(IfThen symbol) { + + org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); + Symbol thenPart = symbol.getThenPart(); + + expression.setEnv(symbol.getEnv()); + expression.accept(this); + + thenPart.setEnv(symbol.getEnv()); + visitSymbol(thenPart); + + return null; + } + + @Override + public Void visit(IfThenElse symbol) { + + org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); + Symbol thenPart = symbol.getThenPart(); + Symbol elsePart = symbol.getElsePart(); + + expression.setEnv(symbol.getEnv()); + expression.accept(this); + + thenPart.setEnv(symbol.getEnv()); + visitSymbol(thenPart); + + elsePart.setEnv(symbol.getEnv()); + visitSymbol(thenPart); + + return null; + } + + @Override + public Void visit(Ignore symbol) { + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + symbol.setEnv(sym.getEnv()); + + return null; + } + + @Override + public Void visit(Nonterminal symbol) { + + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + if (symbol.getVariable() != null) + env = env.__insert(symbol.getVariable()); + + if (symbol.getArguments() != null) { + for (org.iguana.datadependent.ast.Expression argument : symbol.getArguments()) { + argument.setEnv(env); + argument.accept(this); + env = argument.getEnv(); + } + } + + if (nonterminal_uses != null && nonterminal_uses.containsKey(symbol)) { + for (java.lang.String parameter : nonterminal_uses.get(symbol)) + use(parameter); + } + + if (nonterminal_bindings != null + && !nonterminal_bindings.containsKey(symbol) + && nonterminal_updates.containsKey(symbol)) + nonterminal_bindings.put(symbol, new HashSet<>()); + + symbol.setEnv(env); + + return null; + } + + @Override + public Void visit(Offside symbol) { + + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + symbol.setEnv(sym.getEnv()); + + return null; + } + + @Override + public Void visit(Terminal symbol) { + return null; + } + + @Override + public Void visit(While symbol) { + + org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); + Symbol body = symbol.getBody(); + + expression.setEnv(symbol.getEnv()); + expression.accept(this); + + body.setEnv(symbol.getEnv()); + visitSymbol(body); + + return null; + } + + @Override + public Void visit(Return symbol) { + org.iguana.datadependent.ast.Expression expression = symbol.getExpression(); + + expression.setEnv(symbol.getEnv()); + expression.accept(this); + + symbol.setEnv(expression.getEnv()); + + return null; + } + + @Override + public Void visit(Alt symbol) { + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + for (Symbol sym : symbol.getSymbols()) { + sym.setEnv(env); + visitSymbol(sym); + } + + return null; + } + + @Override + public Void visit(Opt symbol) { + + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + return null; + } + + @Override + public Void visit(Plus symbol) { + + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + return null; + } + + @Override + public Void visit(Group symbol) { + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + for (Symbol sym : symbol.getSymbols()) { + sym.setEnv(env); + visitSymbol(sym); + env = sym.getEnv(); + } + + return null; + } + + @Override + public Void visit(Star symbol) { + + Symbol sym = symbol.getSymbol(); + + sym.setEnv(symbol.getEnv()); + visitSymbol(sym); + + return null; + } @Override public Void visit(Start start) { @@ -739,55 +746,55 @@ public Void visit(Start start) { } // Accounts for optional label and optional preconditions and postconditions - public Void visitSymbol(Symbol symbol) { - - io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); - - if (symbol.getLabel() != null) - env = env.__insert(java.lang.String.format(LeftExtent.format, symbol.getLabel())); - - for (Condition condition : symbol.getPreConditions()) { - condition.setEnv(env); - condition.accept(this); - } - - symbol.setEnv(env); - symbol.accept(this); - - env = symbol.getEnv(); - - if (symbol.getLabel() != null) - env = env.__insert(symbol.getLabel()); - - for (Condition condition : symbol.getPostConditions()) { - condition.setEnv(env); - condition.accept(this); - } - - symbol.setEnv(env); - - return null; - } - - @Override - public Void visit(DataDependentCondition condition) { - - org.iguana.datadependent.ast.Expression expression = condition.getExpression(); - - expression.setEnv(condition.getEnv()); - expression.accept(this); - - return null; - } - - @Override - public Void visit(PositionalCondition condition) { - return null; - } - - @Override - public Void visit(RegularExpressionCondition condition) { - return null; - } - + public Void visitSymbol(Symbol symbol) { + + io.usethesource.capsule.Set.Immutable env = symbol.getEnv(); + + if (symbol.getLabel() != null) + env = env.__insert(java.lang.String.format(LeftExtent.format, symbol.getLabel())); + + for (Condition condition : symbol.getPreConditions()) { + condition.setEnv(env); + condition.accept(this); + } + + symbol.setEnv(env); + symbol.accept(this); + + env = symbol.getEnv(); + + if (symbol.getLabel() != null) + env = env.__insert(symbol.getLabel()); + + for (Condition condition : symbol.getPostConditions()) { + condition.setEnv(env); + condition.accept(this); + } + + symbol.setEnv(env); + + return null; + } + + @Override + public Void visit(DataDependentCondition condition) { + + org.iguana.datadependent.ast.Expression expression = condition.getExpression(); + + expression.setEnv(condition.getEnv()); + expression.accept(this); + + return null; + } + + @Override + public Void visit(PositionalCondition condition) { + return null; + } + + @Override + public Void visit(RegularExpressionCondition condition) { + return null; + } + } diff --git a/src/org/iguana/generator/Generator.java b/src/org/iguana/generator/Generator.java index e9319e1c7..d140f1acb 100644 --- a/src/org/iguana/generator/Generator.java +++ b/src/org/iguana/generator/Generator.java @@ -54,7 +54,8 @@ protected void generateTypes(StringBuilder sb, Function f) { for (RuntimeRule alternative : alternatives) { if (alternative.getLabel() == null) throw new RuntimeException("All alternatives must have a label: " + alternative); - String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + nonterminalName.substring(1); + String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + + nonterminalName.substring(1); sb.append(f.apply(nodeName)); } } diff --git a/src/org/iguana/generator/ide/GenerateLangFiles.java b/src/org/iguana/generator/ide/GenerateLangFiles.java index 2af9772a4..5bb3c8fe7 100644 --- a/src/org/iguana/generator/ide/GenerateLangFiles.java +++ b/src/org/iguana/generator/ide/GenerateLangFiles.java @@ -77,7 +77,8 @@ private void generateIcon() { "import javax.swing.*;\n" + "\n" + "public class " + className + "Icon {\n" + - " public static final Icon icon = IconLoader.getIcon(\"/META-INF/pluginIcon.svg\", " + className + "Icon.class);\n" + + " public static final Icon icon = IconLoader.getIcon(\"/META-INF/pluginIcon.svg\", " + className + + "Icon.class);\n" + "}\n"; writeToJavaFile(content, langGenDirectory, className + "Icon"); } diff --git a/src/org/iguana/generator/ide/GenerateParserFiles.java b/src/org/iguana/generator/ide/GenerateParserFiles.java index dbead6081..80ce6fe1a 100644 --- a/src/org/iguana/generator/ide/GenerateParserFiles.java +++ b/src/org/iguana/generator/ide/GenerateParserFiles.java @@ -59,7 +59,8 @@ private void generateIggyElementTypes() { } private String generateElementType(String type) { - return " public static IElementType " + type + " = new IggyElementType(\"" + type + "\", IggyLang.instance);\n"; + return " public static IElementType " + type + " = new IggyElementType(\"" + type + + "\", IggyLang.instance);\n"; } private String generateStringToElementTypetMapEntry(String type) { diff --git a/src/org/iguana/generator/ide/GeneratePsiElements.java b/src/org/iguana/generator/ide/GeneratePsiElements.java index 74d6576ef..cbe336aee 100644 --- a/src/org/iguana/generator/ide/GeneratePsiElements.java +++ b/src/org/iguana/generator/ide/GeneratePsiElements.java @@ -58,15 +58,19 @@ private void generatePsiElements() { List alternatives = entry.getValue(); if (alternatives.size() == 0) { - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, Collections.emptyList())); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, + Collections.emptyList())); } else if (alternatives.size() == 1) { - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, alternatives.get(0).getBody())); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, + alternatives.get(0).getBody())); } else { - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), true, Collections.emptyList())); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), true, + Collections.emptyList())); for (RuntimeRule alternative : alternatives) { if (alternative.getLabel() == null) throw new RuntimeException("All alternatives must have a label: " + alternative); - String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + nonterminalName.substring(1); + String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + + nonterminalName.substring(1); sb.append(generateSymbolClass(nodeName, nonterminalName, false, alternative.getBody())); } } @@ -93,7 +97,9 @@ private void generatePsiElementFactory() { sb.append("\n"); sb.append("public class " + className + "PsiElementFactory {\n"); sb.append("\n"); - sb.append(" private static final Map> elementTypeToPsiElementMap = new IdentityHashMap<>();\n"); + sb.append( + " private static final Map> elementTypeToPsiElementMap " + + "= new IdentityHashMap<>();\n"); sb.append("\n"); sb.append(" static {\n"); metaSymbolNodes.forEach(s -> sb.append(generateTypeToPsiElementMapEntry(s))); @@ -115,12 +121,13 @@ private String generateTypeToPsiElementMapEntry(String type) { private String generateSymbolClass(String symbolClass, String superType, boolean isAbstract, List symbols) { return - " public static " + (isAbstract ? "abstract " : "") + "class " + symbolClass + " extends ASTWrapperPsiElement {\n" + - " public " + symbolClass + "(@NotNull ASTNode node) {\n" + - " super(node);\n" + - " }\n\n" + - generateSymbols(symbols) + - " }\n\n"; + " public static " + (isAbstract ? "abstract " : "") + "class " + symbolClass + + " extends ASTWrapperPsiElement {\n" + + " public " + symbolClass + "(@NotNull ASTNode node) {\n" + + " super(node);\n" + + " }\n\n" + + generateSymbols(symbols) + + " }\n\n"; } private String generateSymbols(List symbols) { @@ -155,6 +162,7 @@ private static class Type { public Type(String name) { this(name, null); } + public Type(String name, String parameter) { this.name = name; this.parameter = parameter; diff --git a/src/org/iguana/generator/parser/ParseTreeVisitorGenerator.java b/src/org/iguana/generator/parser/ParseTreeVisitorGenerator.java index 159013d7b..ce120e4b4 100644 --- a/src/org/iguana/generator/parser/ParseTreeVisitorGenerator.java +++ b/src/org/iguana/generator/parser/ParseTreeVisitorGenerator.java @@ -19,7 +19,12 @@ public class ParseTreeVisitorGenerator extends Generator { - public ParseTreeVisitorGenerator(RuntimeGrammar grammar, String grammarName, String packageName, String genDirectory) { + public ParseTreeVisitorGenerator( + RuntimeGrammar grammar, + String grammarName, + String packageName, + String genDirectory + ) { super(grammar, grammarName, packageName, genDirectory); } @@ -40,6 +45,7 @@ private void generateParseTreeBuilder() { sb.append("import org.iguana.utils.input.Input;\n\n"); sb.append("import java.util.List;\n\n"); + // CHECKSTYLE:OFF: LineLength String className = toFirstUpperCase(grammarName) + "ParseTreeBuilder"; sb.append("public class " + className + " extends DefaultParseTreeBuilder {\n\n"); sb.append(" public " + className + "(Input input) {\n"); @@ -47,7 +53,8 @@ private void generateParseTreeBuilder() { sb.append(" }\n\n"); sb.append(" @Override\n"); - sb.append(" public NonterminalNode nonterminalNode(RuntimeRule rule, List children, int leftExtent, int rightExtent) {\n"); + sb.append( + " public NonterminalNode nonterminalNode(RuntimeRule rule, List children, int leftExtent, int rightExtent) {\n"); sb.append(" java.lang.String name = rule.getHead().getName();\n"); sb.append(" java.lang.String label = rule.getLabel();\n\n"); sb.append(" switch (name) {\n"); @@ -57,6 +64,7 @@ private void generateParseTreeBuilder() { sb.append(" }\n"); sb.append(" }\n"); sb.append("}\n"); + // CHECKSTYLE:ON: LineLength writeToJavaFile(sb.toString(), genDirectory, className); System.out.println(className + " has been generated in " + genDirectory + "/" + className + ".java"); @@ -69,17 +77,21 @@ private void generateBuilderCases(RuntimeGrammar grammar, StringBuilder sb) { sb.append(" case \"" + nonterminalName + "\":\n"); if (alternatives.size() == 0) { - sb.append(" return new " + toFirstUpperCase(grammarName) + "ParseTree" + "." + toFirstUpperCase(nonterminalName) + "(rule, children, leftExtent, rightExtent);\n"); + sb.append(" return new " + toFirstUpperCase(grammarName) + "ParseTree" + "." + + toFirstUpperCase(nonterminalName) + "(rule, children, leftExtent, rightExtent);\n"); } else if (alternatives.size() == 1) { - sb.append(" return new " + toFirstUpperCase(grammarName) + "ParseTree" + "." + toFirstUpperCase(nonterminalName) + "(rule, children, leftExtent, rightExtent);\n"); + sb.append(" return new " + toFirstUpperCase(grammarName) + "ParseTree" + "." + + toFirstUpperCase(nonterminalName) + "(rule, children, leftExtent, rightExtent);\n"); } else { sb.append(" switch (label) {\n"); for (RuntimeRule alternative : alternatives) { if (alternative.getLabel() == null) throw new RuntimeException("All alternatives must have a label: " + alternative); sb.append(" case \"" + alternative.getLabel() + "\":\n"); - String className = toFirstUpperCase(grammarName) + "ParseTree" + "." + toFirstUpperCase(alternative.getLabel()) + toFirstUpperCase(nonterminalName); - sb.append(" return new " + toFirstUpperCase(className) + "(rule, children, leftExtent, rightExtent);\n"); + String className = toFirstUpperCase(grammarName) + "ParseTree" + "." + + toFirstUpperCase(alternative.getLabel()) + toFirstUpperCase(nonterminalName); + sb.append(" return new " + toFirstUpperCase(className) + + "(rule, children, leftExtent, rightExtent);\n"); } sb.append(" default:\n"); sb.append(" throw new RuntimeException(\"Unexpected label:\" + label);\n"); @@ -104,17 +116,23 @@ private void generateParseTreeTypes() { if (alternatives.size() == 0) { sb.append(" // " + nonterminalName + " = \n"); - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, Collections.emptyList())); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, + Collections.emptyList())); } else if (alternatives.size() == 1) { - sb.append(" // " + nonterminalName + " = " + listToString(alternatives.get(0).getBody().stream().map(this::symbolToString).collect(Collectors.toList())) + "\n"); - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, alternatives.get(0).getBody())); + sb.append(" // " + nonterminalName + " = " + listToString(alternatives.get(0).getBody().stream() + .map(this::symbolToString).collect(Collectors.toList())) + "\n"); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), false, + alternatives.get(0).getBody())); } else { - sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), true, Collections.emptyList())); + sb.append(generateSymbolClass(nonterminalName, NonterminalNode.class.getSimpleName(), true, + Collections.emptyList())); for (RuntimeRule alternative : alternatives) { if (alternative.getLabel() == null) throw new RuntimeException("All alternatives must have a label: " + alternative); - String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + nonterminalName.substring(1); - sb.append(" // " + nonterminalName + " = " + listToString(alternative.getBody().stream().map(this::symbolToString).collect(Collectors.toList())) + "\n"); + String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + + nonterminalName.substring(1); + sb.append(" // " + nonterminalName + " = " + listToString(alternative.getBody().stream() + .map(this::symbolToString).collect(Collectors.toList())) + "\n"); sb.append(generateSymbolClass(nodeName, nonterminalName, false, alternative.getBody())); } } @@ -156,7 +174,8 @@ private void generateVisitMethods(RuntimeGrammar grammar, StringBuilder sb) { for (RuntimeRule alternative : alternatives) { if (alternative.getLabel() == null) throw new RuntimeException("All alternatives must have a label: " + alternative); - String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + nonterminalName.substring(1); + String nodeName = alternative.getLabel() + nonterminalName.substring(0, 1).toUpperCase() + + nonterminalName.substring(1); sb.append(generateVisitorMethod(nodeName)); } } @@ -165,36 +184,47 @@ private void generateVisitMethods(RuntimeGrammar grammar, StringBuilder sb) { private String generateVisitorMethod(String name) { String className = toFirstUpperCase(grammarName) + "ParseTree"; + // CHECKSTYLE:DISABLE:LineLength if (name.startsWith("$_")) { - return " default T visit" + toFirstUpperCase(name) + "(" + className + "." + toFirstUpperCase(name) + " node) {\n" + + return " default T visit" + toFirstUpperCase(name) + "(" + className + "." + toFirstUpperCase(name) + + " node) {\n" + " return node.child().accept(this);\n" + " }\n\n"; } else { - return " T visit" + toFirstUpperCase(name) + "(" + className + "." + toFirstUpperCase(name) + " node);\n\n"; + return " T visit" + toFirstUpperCase(name) + "(" + className + "." + toFirstUpperCase(name) + + " node);\n\n"; } + // CHECKSTYLE:ENABLE:LineLength } private String generateSymbolClass(String symbolClass, String superType, boolean isAbstract, List symbols) { + // CHECKSTYLE:DISABLE:LineLength return - " public static " + (isAbstract ? "abstract " : "") + "class " + toFirstUpperCase(symbolClass) + " extends " + toFirstUpperCase(superType) + " {\n" + - " public " + toFirstUpperCase(symbolClass) + "(RuntimeRule rule, List children, int start, int end) {\n" + + " public static " + (isAbstract ? "abstract " : "") + "class " + toFirstUpperCase(symbolClass) + + " extends " + toFirstUpperCase(superType) + " {\n" + + " public " + toFirstUpperCase(symbolClass) + + "(RuntimeRule rule, List children, int start, int end) {\n" + " super(rule, children, start, end);\n" + " }\n\n" + generateSymbols(symbols) + (isAbstract ? "" : generateAcceptMethod(symbolClass)) + " }\n\n"; + // CHECKSTYLE:ENABLE:LineLength } private String generateAcceptMethod(String symbolClass) { + // CHECKSTYLE:DISABLE:LineLength String visitorName = toFirstUpperCase(grammarName) + "ParseTreeVisitor"; return " @Override\n" + " public T accept(ParseTreeVisitor visitor) {\n" + " if (visitor instanceof " + visitorName + ") {\n" + - " return ((" + visitorName + ") visitor).visit" + toFirstUpperCase(symbolClass) + "(this);\n" + + " return ((" + visitorName + ") visitor).visit" + toFirstUpperCase(symbolClass) + + "(this);\n" + " }\n" + " return visitor.visitNonterminalNode(this);\n" + " }\n"; + // CHECKSTYLE:ENABLE:LineLength } private String generateSymbols(List symbols) { diff --git a/src/org/iguana/generator/parser/ParserGenerator.java b/src/org/iguana/generator/parser/ParserGenerator.java index 985ff637d..1fb23283b 100644 --- a/src/org/iguana/generator/parser/ParserGenerator.java +++ b/src/org/iguana/generator/parser/ParserGenerator.java @@ -11,6 +11,7 @@ public ParserGenerator(String grammarName, String packageName, String genDirecto super(null, grammarName, packageName, genDirectory); } + // CHECKSTYLE:OFF: LineLength public void generateGrammar() { String className = toFirstUpperCase(grammarName); String content = @@ -49,6 +50,7 @@ public void generateGrammar() { writeToJavaFile(content, genDirectory, className + "Grammar"); System.out.println(className + "Grammar" + " has been generated in " + genDirectory + "/" + className + "Grammar.java"); } + // CHECKSTYLE:ON: LineLength public void generateParser() { String className = toFirstUpperCase(grammarName); @@ -83,6 +85,7 @@ public void generateParser() { " }\n" + "}\n"; writeToJavaFile(content, genDirectory, className + "Parser"); - System.out.println(className + "Parser" + " has been generated in " + genDirectory + "/" + className + "Parser.java"); + System.out.println( + className + "Parser" + " has been generated in " + genDirectory + "/" + className + "Parser.java"); } } diff --git a/src/org/iguana/grammar/Grammar.java b/src/org/iguana/grammar/Grammar.java index 100766bed..e9085286f 100644 --- a/src/org/iguana/grammar/Grammar.java +++ b/src/org/iguana/grammar/Grammar.java @@ -84,7 +84,7 @@ public String getName() { public RuntimeGrammar toRuntimeGrammar() { if (runtimeGrammar == null) { - Map regularExpressions = InlineReferences.inline(this.regularExpressionDefinitions); + Map regularExpressions = InlineReferences.inline(regularExpressionDefinitions); Set nonterminals = rules.stream().map(r -> r.getHead().getName()).collect(Collectors.toSet()); ResolveIdentifiers resolveIdentifiers = new ResolveIdentifiers(nonterminals, regularExpressions); GrammarVisitor grammarVisitor = new GrammarVisitor(resolveIdentifiers); @@ -114,7 +114,8 @@ public RuntimeGrammar toRuntimeGrammar() { } else if (newLayout instanceof Nonterminal) { newLayout = ((Nonterminal) newLayout).copy().setNodeType(NonterminalNodeType.Layout).build(); } else { - throw new RuntimeException("Layout can only be an instance of a terminal or nonterminal, but was " + newLayout.getClass().getSimpleName()); + throw new RuntimeException("Layout can only be an instance of a terminal or nonterminal, but was " + + newLayout.getClass().getSimpleName()); } } @@ -315,7 +316,12 @@ public Grammar build() { } } - private List getRules(Rule highLevelRule, Map> leftEnds, Map> rightEnds, Set ebnfs) { + private List getRules( + Rule highLevelRule, + Map> leftEnds, + Map> rightEnds, + Set ebnfs + ) { List priorityLevels = highLevelRule.getPriorityLevels(); List rules = new ArrayList<>(); @@ -335,7 +341,8 @@ private List getRules(Rule highLevelRule, Map> ListIterator seqIt = sequences.listIterator(sequences.size()); while (seqIt.hasPrevious()) { Sequence sequence = seqIt.previous(); - RuntimeRule rule = getRule(head, sequence.getSymbols(), sequence.associativity, sequence.label, highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); + RuntimeRule rule = getRule(head, sequence.getSymbols(), sequence.associativity, sequence.label, + highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); int precedence = assocGroup.getPrecedence(rule); rule = rule.copy() .setPrecedence(precedence) @@ -352,7 +359,8 @@ private List getRules(Rule highLevelRule, Map> if (alternative.first().isEmpty()) { // Empty alternative Sequence sequence = alternative.first(); String label = sequence.label; - RuntimeRule rule = getRule(head, symbols, Associativity.UNDEFINED, label, highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); + RuntimeRule rule = getRule(head, symbols, Associativity.UNDEFINED, label, + highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); int precedence = level.getPrecedence(rule); rule = rule.copy() .setPrecedence(precedence) @@ -365,7 +373,8 @@ private List getRules(Rule highLevelRule, Map> symbols.add(sequence.first()); if (sequence.rest() != null) addAll(symbols, sequence.rest()); - RuntimeRule rule = getRule(head, symbols, sequence.associativity, sequence.label, highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); + RuntimeRule rule = getRule(head, symbols, sequence.associativity, sequence.label, + highLevelRule.getLayoutStrategy(), leftEnds, rightEnds, ebnfs); int precedence = level.getPrecedence(rule); rule = rule.copy() .setPrecedence(precedence) @@ -384,10 +393,20 @@ private List getRules(Rule highLevelRule, Map> return rules; } - private RuntimeRule getRule(Nonterminal head, List body, Associativity associativity, String label, - LayoutStrategy layoutStrategy, Map> leftEnds, Map> rightEnds, Set ebnfs) { - boolean isLeft = body.size() != 0 && body.get(0).accept(new IsRecursive(head, Recursion.LEFT_REC, leftEnds, ebnfs)); - boolean isRight = body.size() != 0 && body.get(body.size() - 1).accept(new IsRecursive(head, Recursion.RIGHT_REC, leftEnds, ebnfs)); + private RuntimeRule getRule( + Nonterminal head, + List body, + Associativity associativity, + String label, + LayoutStrategy layoutStrategy, + Map> leftEnds, + Map> rightEnds, + Set ebnfs + ) { + boolean isLeft = body.size() != 0 && body.get(0).accept( + new IsRecursive(head, Recursion.LEFT_REC, leftEnds, ebnfs)); + boolean isRight = body.size() != 0 && body.get(body.size() - 1).accept( + new IsRecursive(head, Recursion.RIGHT_REC, leftEnds, ebnfs)); IsRecursive visitor = new IsRecursive(head, Recursion.iLEFT_REC, leftEnds, ebnfs); @@ -447,7 +466,13 @@ else if (isiRight) .build(); } - private void computeEnds(Nonterminal head, List symbols, Map> leftEnds, Map> rightEnds, Set ebnfs) { + private void computeEnds( + Nonterminal head, + List symbols, + Map> leftEnds, + Map> rightEnds, + Set ebnfs + ) { if (symbols.size() >= 1) { Symbol first = symbols.get(0); Symbol last = symbols.get(symbols.size() - 1); @@ -487,7 +512,8 @@ private static Set getTopLevelRegularExpressions(Grammar grammar) { for (Alternative alternative : priorityLevel.getAlternatives()) { for (Sequence seq : alternative.seqs()) { for (Symbol symbol : seq.getSymbols()) { - GatherTopLevelRegularExpressionsVisitor visitor = new GatherTopLevelRegularExpressionsVisitor(grammar); + GatherTopLevelRegularExpressionsVisitor visitor = + new GatherTopLevelRegularExpressionsVisitor(grammar); symbol.accept(visitor); references.addAll(visitor.references); } @@ -501,7 +527,8 @@ private static Set getTopLevelRegularExpressions(Grammar grammar) { // Top-level regular expressions are the ones that are directly reachable from context free rules. // They define the tokens of the language. // TODO: unify this with SymbolToSymbolVisitor - private static class GatherTopLevelRegularExpressionsVisitor implements ISymbolVisitor, RegularExpressionVisitor, IConditionVisitor { + private static class GatherTopLevelRegularExpressionsVisitor + implements ISymbolVisitor, RegularExpressionVisitor, IConditionVisitor { private final Set references = new LinkedHashSet<>(); private final Grammar grammar; @@ -931,8 +958,8 @@ public Boolean visit(org.iguana.grammar.symbol.Group symbol) { @Override public Boolean visit(org.iguana.grammar.symbol.Star symbol) { - - if (recursion == Recursion.LEFT_REC || recursion == Recursion.RIGHT_REC) { // TODO: not good, there should be also left and right ends + // TODO: not good, there should be also left and right ends + if (recursion == Recursion.LEFT_REC || recursion == Recursion.RIGHT_REC) { IsRecursive visitor = new IsRecursive(head, recursion, ebnfs); symbol.getSymbol().accept(visitor); diff --git a/src/org/iguana/grammar/GrammarGraph.java b/src/org/iguana/grammar/GrammarGraph.java index 2baa74e93..961c2a8dd 100644 --- a/src/org/iguana/grammar/GrammarGraph.java +++ b/src/org/iguana/grammar/GrammarGraph.java @@ -16,27 +16,35 @@ public class GrammarGraph { - public static final TerminalGrammarSlot epsilonSlot = new TerminalGrammarSlot(Terminal.epsilon(), new DFAMatcherFactory()); + public static final TerminalGrammarSlot epsilonSlot = + new TerminalGrammarSlot(Terminal.epsilon(), new DFAMatcherFactory()); private final List slots; private final Map globals; private final Map nonterminalsMap; - public GrammarGraph(List slots, Map nonterminalsMap, Map globals) { + public GrammarGraph( + List slots, + Map nonterminalsMap, + Map globals + ) { this.slots = slots; this.nonterminalsMap = nonterminalsMap; this.globals = globals; } public List getNonterminalGrammarSlots() { - return slots.stream().filter(slot -> slot instanceof NonterminalGrammarSlot).map(slot -> (NonterminalGrammarSlot) slot).collect(toList()); + return slots.stream().filter(slot -> slot instanceof NonterminalGrammarSlot) + .map(slot -> (NonterminalGrammarSlot) slot).collect(toList()); } public List getTerminalGrammarSlots() { - return slots.stream().filter(slot -> slot instanceof TerminalGrammarSlot).map(slot -> (TerminalGrammarSlot) slot).collect(toList()); + return slots.stream().filter(slot -> slot instanceof TerminalGrammarSlot) + .map(slot -> (TerminalGrammarSlot) slot).collect(toList()); } public List getBodyGrammarSlots() { - return slots.stream().filter(slot -> slot instanceof BodyGrammarSlot).map(slot -> (BodyGrammarSlot) slot).collect(toList()); + return slots.stream().filter(slot -> slot instanceof BodyGrammarSlot) + .map(slot -> (BodyGrammarSlot) slot).collect(toList()); } public NonterminalGrammarSlot getStartSlot(Nonterminal nonterminal) { diff --git a/src/org/iguana/grammar/GrammarGraphBuilder.java b/src/org/iguana/grammar/GrammarGraphBuilder.java index 00e427d07..2788908b3 100644 --- a/src/org/iguana/grammar/GrammarGraphBuilder.java +++ b/src/org/iguana/grammar/GrammarGraphBuilder.java @@ -149,7 +149,10 @@ private void setFirstFollowTests(Nonterminal nonterminal) { nonterminalSlot.setFollowTest(getFollowTest(nonterminal)); } - private RangeMap getLookAheadTest(Nonterminal nonterminal, NonterminalGrammarSlot nonterminalSlot) { + private RangeMap getLookAheadTest( + Nonterminal nonterminal, + NonterminalGrammarSlot nonterminalSlot + ) { if (config.getLookAheadCount() == 0) return i -> nonterminalSlot.getFirstSlots(); @@ -222,16 +225,19 @@ public Void visit(Nonterminal symbol) { BodyGrammarSlot slot; if (i == rule.size() - 1 && j == -1) - slot = getEndSlot(rule, i + 1, rule.getPosition(i + 1), head, symbol.getLabel(), symbol.getVariable(), symbol.getState()); + slot = getEndSlot(rule, i + 1, rule.getPosition(i + 1), head, symbol.getLabel(), symbol.getVariable(), + symbol.getState()); else - slot = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), symbol.getLabel(), symbol.getVariable(), symbol.getState()); + slot = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), symbol.getLabel(), symbol.getVariable(), + symbol.getState()); Expression[] arguments = symbol.getArguments(); validateNumberOfArguments(nonterminalSlot.getNonterminal(), arguments); List preConditions = (i == 0 && j == -1) ? new ArrayList<>() : symbol.getPreConditions(); - setTransition(new NonterminalTransition(nonterminalSlot, currentSlot, slot, arguments, getConditions(preConditions))); + setTransition( + new NonterminalTransition(nonterminalSlot, currentSlot, slot, arguments, getConditions(preConditions))); currentSlot = slot; @@ -291,7 +297,8 @@ public Void visit(Return symbol) { throw new RuntimeException("Return symbol can only be used at the end of a grammar rule!"); else { if (rule.size() == 1) - done = new EpsilonGrammarSlot(rule.getPosition(i + 1), head, epsilonSlot, ConditionsFactory.DEFAULT); + done = new EpsilonGrammarSlot(rule.getPosition(i + 1), head, epsilonSlot, + ConditionsFactory.DEFAULT); else done = getEndSlot(rule, i + 1, rule.getPosition(i + 1), head, null, null, null); } @@ -315,7 +322,8 @@ public Void visit(Terminal symbol) { slot = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), symbol.getLabel(), null, null); List preConditions = (i == 0 && j == -1) ? Collections.emptyList() : symbol.getPreConditions(); - TerminalTransition transition = getTerminalTransition(terminalSlot, currentSlot, slot, preConditions, symbol.getPostConditions()); + TerminalTransition transition = getTerminalTransition(terminalSlot, currentSlot, slot, preConditions, + symbol.getPostConditions()); setTransition(transition); currentSlot = slot; @@ -327,7 +335,10 @@ public Void visit(Terminal symbol) { */ private void visitSymbol(Symbol symbol) { - if (symbol instanceof Nonterminal || symbol instanceof Terminal || symbol instanceof Error || symbol instanceof Return) { // TODO: I think this can be unified + if (symbol instanceof Nonterminal || + symbol instanceof Terminal || + symbol instanceof Error || + symbol instanceof Return) { // TODO: I think this can be unified symbol.accept(this); return; } @@ -336,7 +347,8 @@ private void visitSymbol(Symbol symbol) { if (symbol.getLabel() != null) { BodyGrammarSlot declared = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), null, null, null); - EpsilonTransition transition = new EpsilonTransition(Type.DECLARE_LABEL, symbol.getLabel(), preconditions, currentSlot, declared); + EpsilonTransition transition = new EpsilonTransition(Type.DECLARE_LABEL, symbol.getLabel(), + preconditions, currentSlot, declared); setTransition(transition); currentSlot = declared; } else { @@ -360,7 +372,8 @@ private void visitSymbol(Symbol symbol) { else stored = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), null, null, null); - EpsilonTransition transition = new EpsilonTransition(Type.STORE_LABEL, symbol.getLabel(), getConditions(symbol.getPostConditions()), currentSlot, stored); + EpsilonTransition transition = new EpsilonTransition(Type.STORE_LABEL, symbol.getLabel(), + getConditions(symbol.getPostConditions()), currentSlot, stored); setTransition(transition); currentSlot = stored; } else { @@ -371,7 +384,8 @@ private void visitSymbol(Symbol symbol) { else checked = getBodyGrammarSlot(rule, i + 1, rule.getPosition(i + 1), null, null, null); - EpsilonTransition transition = new EpsilonTransition(getConditions(symbol.getPostConditions()), currentSlot, checked); + EpsilonTransition transition = new EpsilonTransition(getConditions(symbol.getPostConditions()), + currentSlot, checked); setTransition(transition); currentSlot = checked; } @@ -413,35 +427,56 @@ private BodyGrammarSlot getFirstGrammarSlot(RuntimeRule rule, NonterminalGrammar // not any precondition of the first symbol (due to labels) can currently be moved to the first slot. List preConditions = new ArrayList<>(rule.symbolAt(0).getPreConditions()); - slot = new BodyGrammarSlot(rule.getPosition(0, 0), rule.symbolAt(0).getLabel(), null, null, getConditions(preConditions), FollowTest.DEFAULT); + slot = new BodyGrammarSlot(rule.getPosition(0, 0), rule.symbolAt(0).getLabel(), null, null, + getConditions(preConditions), FollowTest.DEFAULT); } bodyGrammarSlots.add(slot); return slot; } - private BodyGrammarSlot getBodyGrammarSlot(RuntimeRule rule, int i, Position position, String label, String variable, Set state) { + private BodyGrammarSlot getBodyGrammarSlot( + RuntimeRule rule, + int i, + Position position, + String label, + String variable, + Set state + ) { assert (i - 1) < rule.size(); BodyGrammarSlot slot; if (current != null) slot = new BodyGrammarSlot(position, label, (label != null && !label.isEmpty()) ? current.get(label) : -1, - variable, (variable != null && !variable.isEmpty()) ? current.get(variable) : -1, state, getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); + variable, (variable != null && !variable.isEmpty()) ? current.get(variable) : -1, state, + getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); else - slot = new BodyGrammarSlot(position, label, variable, state, getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); + slot = new BodyGrammarSlot(position, label, variable, state, + getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); bodyGrammarSlots.add(slot); return slot; } - private BodyGrammarSlot getEndSlot(RuntimeRule rule, int i, Position position, NonterminalGrammarSlot nonterminal, String label, String variable, Set state) { + private BodyGrammarSlot getEndSlot( + RuntimeRule rule, + int i, + Position position, + NonterminalGrammarSlot nonterminal, + String label, + String variable, + Set state + ) { assert i == rule.size(); BodyGrammarSlot slot; if (current != null) - slot = new EndGrammarSlot(position, nonterminal, label, (label != null && !label.isEmpty()) ? current.get(label) : -1, - variable, (variable != null && !variable.isEmpty()) ? current.get(variable) : -1, state, getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); + slot = new EndGrammarSlot(position, nonterminal, label, + (label != null && !label.isEmpty()) ? current.get(label) : -1, + variable, (variable != null && !variable.isEmpty()) ? current.get(variable) : -1, state, + getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); else - slot = new EndGrammarSlot(position, nonterminal, label, variable, state, getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); + slot = new EndGrammarSlot(position, nonterminal, label, variable, state, + getConditions(rule.symbolAt(i - 1).getPostConditions()), getFollowTest(rule, i)); bodyGrammarSlots.add(slot); return slot; @@ -449,7 +484,9 @@ private BodyGrammarSlot getEndSlot(RuntimeRule rule, int i, Position position, N static private void validateNumberOfArguments(Nonterminal nonterminal, Expression[] arguments) { List parameters = nonterminal.getParameters(); - if ((parameters == null && arguments == null) || (Objects.requireNonNull(parameters).size() == Objects.requireNonNull(arguments).length)) return; + if ((parameters == null && arguments == null) || + (Objects.requireNonNull(parameters).size() == Objects.requireNonNull(arguments).length)) + return; throw new IncorrectNumberOfArgumentsException(nonterminal, arguments); } diff --git a/src/org/iguana/grammar/condition/Conditions.java b/src/org/iguana/grammar/condition/Conditions.java index d0a292162..3478ef8e5 100644 --- a/src/org/iguana/grammar/condition/Conditions.java +++ b/src/org/iguana/grammar/condition/Conditions.java @@ -38,17 +38,45 @@ public interface Conditions { - default boolean execute(Input input, BodyGrammarSlot slot, GSSNode u, int leftExtent, int rightExtent, IguanaRuntime runtime) { + default boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode u, + int leftExtent, + int rightExtent, + IguanaRuntime runtime + ) { return execute(input, slot, u, leftExtent, rightExtent, GLLEvaluator.getDefaultEvaluatorContext(), runtime); } - boolean execute(Input input, BodyGrammarSlot slot, GSSNode u, int leftExtent, int rightExtent, IEvaluatorContext ctx, IguanaRuntime runtime); + boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode u, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx, + IguanaRuntime runtime + ); - default boolean execute(Input input, BodyGrammarSlot slot, GSSNode u, int inputIndex, IguanaRuntime runtime) { + default boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode u, + int inputIndex, + IguanaRuntime runtime + ) { return execute(input, slot, u, inputIndex, GLLEvaluator.getDefaultEvaluatorContext(), runtime); } - - default boolean execute(Input input, BodyGrammarSlot slot, GSSNode u, int inputIndex, IEvaluatorContext ctx, IguanaRuntime runtime) { + + default boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode u, + int inputIndex, + IEvaluatorContext ctx, + IguanaRuntime runtime + ) { return execute(input, slot, u, inputIndex, inputIndex, ctx, runtime); } diff --git a/src/org/iguana/grammar/condition/ConditionsFactory.java b/src/org/iguana/grammar/condition/ConditionsFactory.java index 7edfe534b..61a420455 100644 --- a/src/org/iguana/grammar/condition/ConditionsFactory.java +++ b/src/org/iguana/grammar/condition/ConditionsFactory.java @@ -48,7 +48,15 @@ public class ConditionsFactory { public static Conditions DEFAULT = new Conditions() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode u, int leftExtent, int rightExtent, IEvaluatorContext ctx, IguanaRuntime runtime) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode u, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx, + IguanaRuntime runtime + ) { return false; } @@ -77,7 +85,15 @@ public static Conditions getConditions(List conditions, MatcherFactor return new Conditions() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int lefExtent, int rightExtent, IEvaluatorContext ctx, IguanaRuntime runtime) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int lefExtent, + int rightExtent, + IEvaluatorContext ctx, + IguanaRuntime runtime + ) { for (int j = 0; j < actions.size(); j++) { SlotAction slotAction = actions.get(j); if (slotAction.execute(input, slot, gssNode, lefExtent, rightExtent, ctx)) { @@ -99,7 +115,15 @@ public String toString() { return new Conditions() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx, IguanaRuntime runtime) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx, + IguanaRuntime runtime + ) { for (int j = 0; j < actions.size(); j++) { SlotAction slotAction = actions.get(j); if (slotAction.execute(input, slot, gssNode, leftExtent, rightExtent, ctx)) { diff --git a/src/org/iguana/grammar/condition/SlotAction.java b/src/org/iguana/grammar/condition/SlotAction.java index 450d8c0bc..a06f5b4ab 100644 --- a/src/org/iguana/grammar/condition/SlotAction.java +++ b/src/org/iguana/grammar/condition/SlotAction.java @@ -37,13 +37,26 @@ @FunctionalInterface public interface SlotAction { - boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx); + boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ); default boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int inputIndex) { return execute(input, slot, gssNode, inputIndex, inputIndex, GLLEvaluator.getDefaultEvaluatorContext()); } - - default boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int inputIndex, IEvaluatorContext ctx) { + + default boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int inputIndex, + IEvaluatorContext ctx + ) { return execute(input, slot, gssNode, inputIndex, inputIndex, ctx); } } diff --git a/src/org/iguana/grammar/exception/IncorrectNumberOfArgumentsException.java b/src/org/iguana/grammar/exception/IncorrectNumberOfArgumentsException.java index 81a3e8905..fefa80b41 100644 --- a/src/org/iguana/grammar/exception/IncorrectNumberOfArgumentsException.java +++ b/src/org/iguana/grammar/exception/IncorrectNumberOfArgumentsException.java @@ -33,7 +33,8 @@ public class IncorrectNumberOfArgumentsException extends RuntimeException { public IncorrectNumberOfArgumentsException(Nonterminal nonterminal, Expression[] arguments) { - super("Incorrect number of arguments passed to nonterminal " + nonterminal + ": " + arguments.length + " instead of " + nonterminal.getParameters().size()); + super("Incorrect number of arguments passed to nonterminal " + nonterminal + ": " + arguments.length + + " instead of " + nonterminal.getParameters().size()); } } diff --git a/src/org/iguana/grammar/exception/UnexpectedSymbolException.java b/src/org/iguana/grammar/exception/UnexpectedSymbolException.java index 6755bccad..aea6ad559 100644 --- a/src/org/iguana/grammar/exception/UnexpectedSymbolException.java +++ b/src/org/iguana/grammar/exception/UnexpectedSymbolException.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -31,12 +31,14 @@ public class UnexpectedSymbolException extends RuntimeException { - public UnexpectedSymbolException(Symbol symbol) { - super("Unexpected symbol " + symbol); - } - - public UnexpectedSymbolException(Symbol symbol, String phase) { - super(String.format("Unexpected symbol %s has been encountered in %s. This symbol must be desugared prior to this phase.", symbol, phase)); - } + public UnexpectedSymbolException(Symbol symbol) { + super("Unexpected symbol " + symbol); + } + + public UnexpectedSymbolException(Symbol symbol, String phase) { + super(String.format( + "Unexpected symbol %s has been encountered in %s. This symbol must be desugared prior to this phase.", + symbol, phase)); + } } diff --git a/src/org/iguana/grammar/operations/ReachabilityGraph.java b/src/org/iguana/grammar/operations/ReachabilityGraph.java index fbeecd079..fa23b7cf1 100644 --- a/src/org/iguana/grammar/operations/ReachabilityGraph.java +++ b/src/org/iguana/grammar/operations/ReachabilityGraph.java @@ -247,8 +247,12 @@ public Boolean visit(Start start) { } } - - private static boolean add(Nonterminal a, Nonterminal nonterminal, Map> reachabilityGraph) { + + private static boolean add( + Nonterminal a, + Nonterminal nonterminal, + Map> reachabilityGraph + ) { boolean changed = false; changed |= reachabilityGraph.get(a).add(nonterminal); changed |= reachabilityGraph.get(a).addAll(reachabilityGraph.get(nonterminal)); diff --git a/src/org/iguana/grammar/runtime/AssociativityGroup.java b/src/org/iguana/grammar/runtime/AssociativityGroup.java index 91f3706dd..88bc46711 100644 --- a/src/org/iguana/grammar/runtime/AssociativityGroup.java +++ b/src/org/iguana/grammar/runtime/AssociativityGroup.java @@ -55,8 +55,14 @@ public AssociativityGroup(Associativity associativity, PrecedenceLevel precedenc this.map = new HashMap<>(); this.lhs = precedenceLevel.getLhs(); } - - public AssociativityGroup(Associativity associativity, PrecedenceLevel precedenceLevel, int lhs, int rhs, int precedence) { + + public AssociativityGroup( + Associativity associativity, + PrecedenceLevel precedenceLevel, + int lhs, + int rhs, + int precedence + ) { this(associativity, precedenceLevel); this.precedence = precedence; this.lhs = lhs; diff --git a/src/org/iguana/grammar/runtime/PrecedenceLevel.java b/src/org/iguana/grammar/runtime/PrecedenceLevel.java index 81c19e10b..82d871247 100644 --- a/src/org/iguana/grammar/runtime/PrecedenceLevel.java +++ b/src/org/iguana/grammar/runtime/PrecedenceLevel.java @@ -58,8 +58,17 @@ public class PrecedenceLevel { this.index = lhs; } - public PrecedenceLevel(int lhs, int rhs, int undefined, boolean hasPrefixUnary, boolean hasPostfixUnary, - boolean hasPrefixUnaryBelow, Integer[] prefixUnaryBelow, boolean hasPostfixUnaryBelow, Integer[] postfixUnaryBelow) { + public PrecedenceLevel( + int lhs, + int rhs, + int undefined, + boolean hasPrefixUnary, + boolean hasPostfixUnary, + boolean hasPrefixUnaryBelow, + Integer[] prefixUnaryBelow, + boolean hasPostfixUnaryBelow, + Integer[] postfixUnaryBelow + ) { this.lhs = lhs; this.index = lhs; this.rhs = rhs; @@ -71,9 +80,16 @@ public PrecedenceLevel(int lhs, int rhs, int undefined, boolean hasPrefixUnary, this.hasPostfixUnaryBelow = hasPostfixUnaryBelow; this.postfixUnaryBelow = postfixUnaryBelow; } - - public static PrecedenceLevel from(int lhs, int rhs, int undefined, boolean hasPrefixUnary, boolean hasPostfixUnary, - boolean hasPrefixUnaryBelow, boolean hasPostfixUnaryBelow) { + + public static PrecedenceLevel from( + int lhs, + int rhs, + int undefined, + boolean hasPrefixUnary, + boolean hasPostfixUnary, + boolean hasPrefixUnaryBelow, + boolean hasPostfixUnaryBelow + ) { PrecedenceLevel level = new PrecedenceLevel(lhs); level.rhs = rhs; level.undefined = undefined; @@ -83,9 +99,18 @@ public static PrecedenceLevel from(int lhs, int rhs, int undefined, boolean hasP level.hasPostfixUnaryBelow = hasPostfixUnaryBelow; return level; } - - public static PrecedenceLevel from(int lhs, int rhs, int undefined, boolean hasPrefixUnary, boolean hasPostfixUnary, - boolean hasPrefixUnaryBelow, Integer[] prefixUnaryBelow, boolean hasPostfixUnaryBelow, Integer[] postfixUnaryBelow) { + + public static PrecedenceLevel from( + int lhs, + int rhs, + int undefined, + boolean hasPrefixUnary, + boolean hasPostfixUnary, + boolean hasPrefixUnaryBelow, + Integer[] prefixUnaryBelow, + boolean hasPostfixUnaryBelow, + Integer[] postfixUnaryBelow + ) { PrecedenceLevel level = new PrecedenceLevel(lhs); level.rhs = rhs; level.undefined = undefined; diff --git a/src/org/iguana/grammar/runtime/RuntimeGrammar.java b/src/org/iguana/grammar/runtime/RuntimeGrammar.java index 8d96f1412..a5f9b074e 100644 --- a/src/org/iguana/grammar/runtime/RuntimeGrammar.java +++ b/src/org/iguana/grammar/runtime/RuntimeGrammar.java @@ -34,13 +34,11 @@ import org.iguana.grammar.symbol.Start; import org.iguana.grammar.symbol.Symbol; import org.iguana.regex.RegularExpression; -import org.iguana.traversal.idea.IdeaIDEGenerator; import java.io.*; import java.net.URI; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.StreamSupport; import static org.iguana.utils.string.StringUtil.listToString; @@ -132,7 +130,10 @@ public Map getLiterals() { return literals; } - private static Set validate(List rules, Map> definitions) { + private static Set validate( + List rules, + Map> definitions + ) { Set exceptions = new HashSet<>(); for (RuntimeRule rule : rules) { if (rule.getBody() != null) { @@ -160,7 +161,9 @@ public String toString() { for (Nonterminal nonterminal : definitions.keySet()) { sb.append(nonterminal).append(" = "); - for (List alternatives : definitions.get(nonterminal).stream().map(r -> r.getBody()).collect(Collectors.toList())) { + List> alternativesList = definitions.get(nonterminal).stream().map(r -> r.getBody()).collect( + Collectors.toList()); + for (List alternatives : alternativesList) { if (alternatives == null) continue; sb.append(listToString(alternatives)).append("\n"); } @@ -243,7 +246,8 @@ public RuntimeGrammar build() { throw new GrammarValidationException(exceptions); } - if (regularExpressionDefinitions == null) throw new RuntimeException("regularExpressionDefinitions is null"); + if (regularExpressionDefinitions == null) + throw new RuntimeException("regularExpressionDefinitions is null"); return new RuntimeGrammar(this); } @@ -386,33 +390,4 @@ public int size() { .sum(); return heads + bodySymbols; } - - private static String rulesToString(Iterable rules) { - return StreamSupport.stream(rules.spliterator(), false) - .map(r -> "\n// " + r.toString() + "\n.addRule(" + r + ")") - .collect(Collectors.joining()); - } - - private static String leftsToString(Map> lefts) { - return lefts.entrySet().stream() - .map(entry -> ".addEBNFl(" + "\"" + entry.getKey() + "\"," - + "new HashSet(Arrays.asList(" - + listToString(entry.getValue().stream().map(elem -> "\"" + elem + "\"").collect(Collectors.toList()), ",") - + ")))") - .collect(Collectors.joining()); - } - - private static String rightsToString(Map> rights) { - return rights.entrySet().stream() - .map(entry -> ".addEBNFr(" + "\"" + entry.getKey() + "\"," - + "new HashSet(Arrays.asList(" - + listToString(entry.getValue().stream().map(elem -> "\"" + elem + "\"").collect(Collectors.toList()), ",") - + ")))") - .collect(Collectors.joining()); - } - - public void generate_idea_ide(String language, String extendsion, String path) { - new IdeaIDEGenerator().generate(this, language, "iggy", path); - } - } diff --git a/src/org/iguana/grammar/runtime/RuntimeRule.java b/src/org/iguana/grammar/runtime/RuntimeRule.java index 107a03dab..cd30dbdcd 100644 --- a/src/org/iguana/grammar/runtime/RuntimeRule.java +++ b/src/org/iguana/grammar/runtime/RuntimeRule.java @@ -146,11 +146,15 @@ public boolean isIRightRecursive() { } public boolean isLeftOrRightRecursive() { - return recursion == Recursion.LEFT_RIGHT_REC || recursion == Recursion.LEFT_REC || recursion == Recursion.RIGHT_REC; + return recursion == Recursion.LEFT_RIGHT_REC || + recursion == Recursion.LEFT_REC || + recursion == Recursion.RIGHT_REC; } public boolean isILeftOrRightRecursive() { - return irecursion == Recursion.iLEFT_RIGHT_REC || irecursion == Recursion.iLEFT_REC || irecursion == Recursion.iRIGHT_REC; + return irecursion == Recursion.iLEFT_RIGHT_REC || + irecursion == Recursion.iLEFT_REC || + irecursion == Recursion.iRIGHT_REC; } public Recursion getRecursion() { diff --git a/src/org/iguana/grammar/slot/BodyGrammarSlot.java b/src/org/iguana/grammar/slot/BodyGrammarSlot.java index 1a820f323..ace75a1b5 100644 --- a/src/org/iguana/grammar/slot/BodyGrammarSlot.java +++ b/src/org/iguana/grammar/slot/BodyGrammarSlot.java @@ -60,17 +60,33 @@ public class BodyGrammarSlot implements GrammarSlot { private final Set state; - private FollowTest followTest; + private final FollowTest followTest; private Transition outTransition; private Transition inTransition; - public BodyGrammarSlot(Position position, String label, String variable, Set state, Conditions conditions, FollowTest followTest) { + public BodyGrammarSlot( + Position position, + String label, + String variable, + Set state, + Conditions conditions, + FollowTest followTest + ) { this(position, label, -1, variable, -1, state, conditions, followTest); } - - public BodyGrammarSlot(Position position, String label, int i1, String variable, int i2, Set state, Conditions conditions, FollowTest followTest) { + + public BodyGrammarSlot( + Position position, + String label, + int i1, + String variable, + int i2, + Set state, + Conditions conditions, + FollowTest followTest + ) { this.position = position; this.conditions = conditions; this.label = label; @@ -91,7 +107,13 @@ public boolean testFollow(int v) { } @SuppressWarnings("unchecked") - public T getIntermediateNode(T leftResult, int destinationIndex, T rightResult, Environment env, IguanaRuntime runtime) { + public T getIntermediateNode( + T leftResult, + int destinationIndex, + T rightResult, + Environment env, + IguanaRuntime runtime + ) { if (isFirst()) return rightResult; @@ -128,8 +150,14 @@ public String getLabel() { public String getVariable() { return variable; } - - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { outTransition.execute(input, u, result, env, runtime); } @@ -242,7 +270,14 @@ public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; BodyGrammarSlot that = (BodyGrammarSlot) o; - return i1 == that.i1 && i2 == that.i2 && Objects.equals(position, that.position) && Objects.equals(conditions, that.conditions) && Objects.equals(label, that.label) && Objects.equals(variable, that.variable) && Objects.equals(state, that.state) && Objects.equals(followTest, that.followTest); + return i1 == that.i1 && + i2 == that.i2 && + Objects.equals(position, that.position) && + Objects.equals(conditions, that.conditions) && + Objects.equals(label, that.label) && + Objects.equals(variable, that.variable) && + Objects.equals(state, that.state) && + Objects.equals(followTest, that.followTest); } @Override diff --git a/src/org/iguana/grammar/slot/CodeTransition.java b/src/org/iguana/grammar/slot/CodeTransition.java index 6cadb0d5e..235ea409a 100644 --- a/src/org/iguana/grammar/slot/CodeTransition.java +++ b/src/org/iguana/grammar/slot/CodeTransition.java @@ -46,7 +46,13 @@ public CodeTransition(Statement[] statements, BodyGrammarSlot origin, BodyGramma } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { runtime.evaluate(statements, env, input); dest.execute(input, u, result, runtime.getEnvironment(), runtime); } diff --git a/src/org/iguana/grammar/slot/ConditionalTransition.java b/src/org/iguana/grammar/slot/ConditionalTransition.java index ff1bcb510..c69a85e14 100644 --- a/src/org/iguana/grammar/slot/ConditionalTransition.java +++ b/src/org/iguana/grammar/slot/ConditionalTransition.java @@ -45,7 +45,12 @@ public ConditionalTransition(Expression condition, BodyGrammarSlot origin, BodyG this(condition, origin, dest, null); } - private ConditionalTransition(Expression condition, BodyGrammarSlot origin, BodyGrammarSlot dest, BodyGrammarSlot ifFalse) { + private ConditionalTransition( + Expression condition, + BodyGrammarSlot origin, + BodyGrammarSlot dest, + BodyGrammarSlot ifFalse + ) { super(origin, dest); this.condition = condition; this.ifFalse = ifFalse; @@ -61,7 +66,13 @@ public String getLabel() { } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { Object value = runtime.evaluate(condition, env, input); diff --git a/src/org/iguana/grammar/slot/EndGrammarSlot.java b/src/org/iguana/grammar/slot/EndGrammarSlot.java index e9cb9cefd..f8206bb3f 100644 --- a/src/org/iguana/grammar/slot/EndGrammarSlot.java +++ b/src/org/iguana/grammar/slot/EndGrammarSlot.java @@ -67,11 +67,23 @@ public Object getObject() { } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { execute(input, u, result, result.getValue(), runtime); } - - public void execute(Input input, GSSNode u, T result, Object value, IguanaRuntime runtime) { + + public void execute( + Input input, + GSSNode u, + T result, + Object value, + IguanaRuntime runtime + ) { int rightExtent = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); int nextChar = input.charAt(rightExtent); @@ -79,7 +91,8 @@ public void execute(Input input, GSSNode u, T result, Obje if (followTest.test(nextChar)) { u.pop(input, this, result, value, runtime); } else { - runtime.recordParseError(rightExtent, input, this, u, "Expected " + followTest + " but was " + (char) nextChar); + runtime.recordParseError(rightExtent, input, this, u, + "Expected " + followTest + " but was " + (char) nextChar); } } diff --git a/src/org/iguana/grammar/slot/EpsilonGrammarSlot.java b/src/org/iguana/grammar/slot/EpsilonGrammarSlot.java index 84a244bf3..9bf8eb044 100644 --- a/src/org/iguana/grammar/slot/EpsilonGrammarSlot.java +++ b/src/org/iguana/grammar/slot/EpsilonGrammarSlot.java @@ -40,18 +40,35 @@ public class EpsilonGrammarSlot extends EndGrammarSlot { private final TerminalGrammarSlot epsilonSlot; - public EpsilonGrammarSlot(Position position, NonterminalGrammarSlot nonterminal, TerminalGrammarSlot epsilonSlot, Conditions conditions) { + public EpsilonGrammarSlot( + Position position, + NonterminalGrammarSlot nonterminal, + TerminalGrammarSlot epsilonSlot, + Conditions conditions + ) { super(position, nonterminal, null, null, null, conditions, FollowTest.DEFAULT); this.epsilonSlot = epsilonSlot; } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { execute(input, u, result, (Object) null, runtime); } @Override - public void execute(Input input, GSSNode u, T result, Object value, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Object value, + IguanaRuntime runtime + ) { int i = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); int nextChar = input.charAt(i); diff --git a/src/org/iguana/grammar/slot/EpsilonTransition.java b/src/org/iguana/grammar/slot/EpsilonTransition.java index 06db400a8..bb9248466 100644 --- a/src/org/iguana/grammar/slot/EpsilonTransition.java +++ b/src/org/iguana/grammar/slot/EpsilonTransition.java @@ -56,7 +56,13 @@ private EpsilonTransition(Type type, Conditions conditions, BodyGrammarSlot orig this.conditions = conditions; } - public EpsilonTransition(Type type, String label, Conditions conditions, BodyGrammarSlot origin, BodyGrammarSlot dest) { + public EpsilonTransition( + Type type, + String label, + Conditions conditions, + BodyGrammarSlot origin, + BodyGrammarSlot dest + ) { super(origin, dest); assert label != null && (type == Type.DECLARE_LABEL || type == Type.STORE_LABEL); @@ -86,7 +92,13 @@ public String getLabel() { } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { int i = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); runtime.setEnvironment(env); @@ -115,7 +127,8 @@ public void execute(Input input, GSSNode u, T result, Envi case DECLARE_LABEL: runtime.getEvaluatorContext().declareVariable(label, Tuple.of(i, -1)); - runtime.getEvaluatorContext().declareVariable(String.format(Expression.LeftExtent.format, label), Tuple.of(i, -1)); + runtime.getEvaluatorContext().declareVariable( + String.format(Expression.LeftExtent.format, label), Tuple.of(i, -1)); if (conditions.execute(input, origin, u, i, runtime.getEvaluatorContext(), runtime)) return; diff --git a/src/org/iguana/grammar/slot/ErrorTransition.java b/src/org/iguana/grammar/slot/ErrorTransition.java index e6c90aca7..52eb79dd4 100644 --- a/src/org/iguana/grammar/slot/ErrorTransition.java +++ b/src/org/iguana/grammar/slot/ErrorTransition.java @@ -17,7 +17,13 @@ public String getLabel() { throw new UnsupportedOperationException(); } - public void handleError(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void handleError( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { int rightExtent = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); int i = rightExtent; while (i < input.length() && !dest.testFollow(input.charAt(i))) { @@ -33,7 +39,13 @@ public void handleError(Input input, GSSNode u, T result, } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { dest.execute(input, u, result, env, runtime); } } diff --git a/src/org/iguana/grammar/slot/NonterminalGrammarSlot.java b/src/org/iguana/grammar/slot/NonterminalGrammarSlot.java index 854fd498c..c135b751b 100644 --- a/src/org/iguana/grammar/slot/NonterminalGrammarSlot.java +++ b/src/org/iguana/grammar/slot/NonterminalGrammarSlot.java @@ -137,7 +137,15 @@ public void reset() { intGSSNodes = null; } - public void create(Input input, BodyGrammarSlot returnSlot, GSSNode u, T result, Expression[] arguments, Environment env, IguanaRuntime runtime) { + public void create( + Input input, + BodyGrammarSlot returnSlot, + GSSNode u, + T result, + Expression[] arguments, + Environment env, + IguanaRuntime runtime + ) { int i = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); Key key = null; @@ -180,10 +188,12 @@ public void create(Input input, BodyGrammarSlot returnSlot, G Environment newEnv = runtime.getEnvironment(); if (data != null) { - if (runtime.getConfiguration().getEnvImpl() == EnvironmentImpl.ARRAY || runtime.getConfiguration().getEnvImpl() == EnvironmentImpl.INT_ARRAY) + if (runtime.getConfiguration().getEnvImpl() == EnvironmentImpl.ARRAY || + runtime.getConfiguration().getEnvImpl() == EnvironmentImpl.INT_ARRAY) newEnv = runtime.getEmptyEnvironment().declare(data); else - newEnv = runtime.getEmptyEnvironment().declare(nonterminal.getParameters().toArray(new String[] {}), data); + newEnv = runtime.getEmptyEnvironment().declare( + nonterminal.getParameters().toArray(new String[] {}), data); } for (int j = 0; j < firstSlots.size(); j++) { @@ -191,11 +201,14 @@ public void create(Input input, BodyGrammarSlot returnSlot, G runtime.setEnvironment(newEnv); if (slot.getLabel() != null) - runtime.getEvaluatorContext().declareVariable(String.format(Expression.LeftExtent.format, slot.getLabel()), i); + runtime.getEvaluatorContext().declareVariable( + String.format(Expression.LeftExtent.format, slot.getLabel()), i); int inputIndex = result.isDummy() ? gssNode.getInputIndex() : result.getRightExtent(); - if (!slot.getConditions().execute(input, returnSlot, gssNode, inputIndex, runtime.getEvaluatorContext(), runtime)) + if (!slot.getConditions().execute(input, returnSlot, gssNode, inputIndex, runtime.getEvaluatorContext(), + runtime)) { runtime.scheduleDescriptor(slot, gssNode, runtime.getResultOps().dummy(), runtime.getEnvironment()); + } } diff --git a/src/org/iguana/grammar/slot/NonterminalTransition.java b/src/org/iguana/grammar/slot/NonterminalTransition.java index 9505b8113..5f87b38fa 100644 --- a/src/org/iguana/grammar/slot/NonterminalTransition.java +++ b/src/org/iguana/grammar/slot/NonterminalTransition.java @@ -46,8 +46,13 @@ public class NonterminalTransition extends AbstractTransition { private final Expression[] arguments; - public NonterminalTransition(NonterminalGrammarSlot nonterminal, BodyGrammarSlot origin, BodyGrammarSlot dest, - Expression[] arguments, Conditions preConditions) { + public NonterminalTransition( + NonterminalGrammarSlot nonterminal, + BodyGrammarSlot origin, + BodyGrammarSlot dest, + Expression[] arguments, + Conditions preConditions + ) { super(origin, dest); this.nonterminal = nonterminal; this.arguments = arguments; @@ -62,11 +67,18 @@ public NonterminalGrammarSlot getSlot() { public String getLabel() { return (dest.getVariable() != null? dest.getVariable() + "=" : "") + (dest.getLabel() != null? dest.getLabel() + ":" : "") - + (arguments != null? String.format("%s(%s)", getSlot().toString(), listToString(arguments, ",")) : getSlot().toString()); + + (arguments != null ? String.format("%s(%s)", getSlot().toString(), listToString(arguments, ",")) + : getSlot().toString()); } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { int i = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); diff --git a/src/org/iguana/grammar/slot/ReturnTransition.java b/src/org/iguana/grammar/slot/ReturnTransition.java index efa383579..7793295d0 100644 --- a/src/org/iguana/grammar/slot/ReturnTransition.java +++ b/src/org/iguana/grammar/slot/ReturnTransition.java @@ -49,7 +49,13 @@ public String getLabel() { } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { Object value = runtime.evaluate(expression, env, input); ((EndGrammarSlot) dest).execute(input, u, result, value, runtime); } diff --git a/src/org/iguana/grammar/slot/TerminalGrammarSlot.java b/src/org/iguana/grammar/slot/TerminalGrammarSlot.java index 48388708f..37f3ae9e4 100644 --- a/src/org/iguana/grammar/slot/TerminalGrammarSlot.java +++ b/src/org/iguana/grammar/slot/TerminalGrammarSlot.java @@ -51,7 +51,13 @@ public TerminalGrammarSlot(Terminal terminal, MatcherFactory factory) { this.matcher = factory.getMatcher(terminal.getRegularExpression()); } - public T getResult(Input input, int i, BodyGrammarSlot slot, GSSNode gssNode, IguanaRuntime runtime) { + public T getResult( + Input input, + int i, + BodyGrammarSlot slot, + GSSNode gssNode, + IguanaRuntime runtime + ) { if (terminalNodes == null) { terminalNodes = new OpenAddressingIntHashMap<>(); } diff --git a/src/org/iguana/grammar/slot/TerminalTransition.java b/src/org/iguana/grammar/slot/TerminalTransition.java index a48003014..7bb4f426f 100644 --- a/src/org/iguana/grammar/slot/TerminalTransition.java +++ b/src/org/iguana/grammar/slot/TerminalTransition.java @@ -43,7 +43,13 @@ public class TerminalTransition extends AbstractTransition { private final Conditions postConditions; - public TerminalTransition(TerminalGrammarSlot terminalSlot, BodyGrammarSlot origin, BodyGrammarSlot dest, Conditions preConditions, Conditions postConditions) { + public TerminalTransition( + TerminalGrammarSlot terminalSlot, + BodyGrammarSlot origin, + BodyGrammarSlot dest, + Conditions preConditions, + Conditions postConditions + ) { super(origin, dest); this.terminalSlot = terminalSlot; this.preConditions = preConditions; @@ -60,13 +66,20 @@ public String getLabel() { } @Override - public void execute(Input input, GSSNode u, T result, Environment env, IguanaRuntime runtime) { + public void execute( + Input input, + GSSNode u, + T result, + Environment env, + IguanaRuntime runtime + ) { int i = result.isDummy() ? u.getInputIndex() : result.getRightExtent(); runtime.setEnvironment(env); if (dest.getLabel() != null) - runtime.getEvaluatorContext().declareVariable(String.format(Expression.LeftExtent.format, dest.getLabel()), i); + runtime.getEvaluatorContext().declareVariable( + String.format(Expression.LeftExtent.format, dest.getLabel()), i); if (preConditions.execute(input, origin, u, i, runtime.getEvaluatorContext(), runtime)) { terminalSlot.recordFailure(i); @@ -83,7 +96,8 @@ public void execute(Input input, GSSNode u, T result, Envi if (dest.getLabel() != null) runtime.getEvaluatorContext().declareVariable(dest.getLabel(), cr); - if (postConditions.execute(input, origin, u, cr.getLeftExtent(), cr.getRightExtent(), runtime.getEvaluatorContext(), runtime)) { + if (postConditions.execute(input, origin, u, cr.getLeftExtent(), cr.getRightExtent(), + runtime.getEvaluatorContext(), runtime)) { terminalSlot.recordFailure(cr.getRightExtent()); return; } diff --git a/src/org/iguana/grammar/transformation/DesugarAlignAndOffside.java b/src/org/iguana/grammar/transformation/DesugarAlignAndOffside.java index 9cec765fb..089c395d9 100644 --- a/src/org/iguana/grammar/transformation/DesugarAlignAndOffside.java +++ b/src/org/iguana/grammar/transformation/DesugarAlignAndOffside.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -44,481 +44,494 @@ import static org.iguana.grammar.condition.DataDependentCondition.predicate; public class DesugarAlignAndOffside implements GrammarTransformation { - - private Map> reachabilityGraph; - - private Set offsided; - - private boolean doAlign = true; - - public void doAlign() { - this.doAlign = true; - } - - public void doOffside() { - this.doAlign = false; - } - - @Override - public RuntimeGrammar transform(RuntimeGrammar grammar) { - - if (doAlign) { - DesugarAlignAndOffsideVisitor desugarAligns = new DesugarAlignAndOffsideVisitor(new HashSet<>()); - desugarAligns.doAlign(doAlign); - - Set rules = new LinkedHashSet<>(); - - for (RuntimeRule rule : grammar.getRules()) - rules.add(desugarAligns.transform(rule, grammar.getLayout())); - - return RuntimeGrammar.builder().addRules(rules) - .setLayout(grammar.getLayout()) - .setStartSymbols(grammar.getStartSymbols()) - .setEbnfLefts(grammar.getEBNFLefts()) - .setEbnfRights(grammar.getEBNFRights()) - .setGlobals(grammar.getGlobals()) - .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) - .build(); - } - - // After EBNF translation - reachabilityGraph = new ReachabilityGraph(grammar).getReachabilityGraph(); - - FindOffsidesVisitor findOffsides = new FindOffsidesVisitor(); - findOffsides.find(grammar); - offsided = findOffsides.getOffsides(); - - reachabilityGraph.entrySet().forEach(e -> { if (offsided.contains(e.getKey().getName())) { - e.getValue().forEach(n -> offsided.add(n.getName())); - }}); - - DesugarAlignAndOffsideVisitor desugarOffsides = new DesugarAlignAndOffsideVisitor(offsided); - desugarOffsides.doAlign(doAlign); - - Set rules = new LinkedHashSet<>(); - - for (RuntimeRule rule : grammar.getRules()) - rules.add(desugarOffsides.transform(rule, grammar.getLayout())); - - return RuntimeGrammar.builder().addRules(rules) - .setLayout(grammar.getLayout()) - .setStartSymbols(grammar.getStartSymbols()) - .setGlobals(grammar.getGlobals()) - .setEbnfLefts(grammar.getEBNFLefts()) - .setEbnfRights(grammar.getEBNFRights()) - .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) - .build(); - } - - private static class DesugarAlignAndOffsideVisitor implements ISymbolVisitor { - - private static final String ind = "ind"; - private static final String first = "fst"; - private static final String index = "i"; - - private static final Expression ind_exp = var(ind); - private static final Expression first_exp = var(first); - private static final Expression index_exp = var(index); - - private static final String l_align = "a"; - private static final String l_offside = "o"; - - private boolean doAlign; - - private final Set offsided; - - private RuntimeRule rule; - private Symbol layout; - - private boolean isOffsided; - - private int i; - - public DesugarAlignAndOffsideVisitor(Set offsided) { - this.offsided = offsided; - } - - public void doAlign(boolean doAlign) { - this.doAlign = doAlign; - } - - public RuntimeRule transform(RuntimeRule rule, Symbol layout) { - this.rule = rule; - this.layout = layout; - this.isOffsided = false; - i = 0; - - if (doAlign) { - List symbols = new ArrayList<>(); - RuntimeRule.Builder builder = rule.copy(); - - if (this.rule.getBody() != null) { - - builder = builder.setSymbols(symbols); - - for (Symbol symbol : this.rule.getBody()) { + + private Map> reachabilityGraph; + + private Set offsided; + + private boolean doAlign = true; + + public void doAlign() { + this.doAlign = true; + } + + public void doOffside() { + this.doAlign = false; + } + + @Override + public RuntimeGrammar transform(RuntimeGrammar grammar) { + + if (doAlign) { + DesugarAlignAndOffsideVisitor desugarAligns = new DesugarAlignAndOffsideVisitor(new HashSet<>()); + desugarAligns.doAlign(doAlign); + + Set rules = new LinkedHashSet<>(); + + for (RuntimeRule rule : grammar.getRules()) + rules.add(desugarAligns.transform(rule, grammar.getLayout())); + + return RuntimeGrammar.builder().addRules(rules) + .setLayout(grammar.getLayout()) + .setStartSymbols(grammar.getStartSymbols()) + .setEbnfLefts(grammar.getEBNFLefts()) + .setEbnfRights(grammar.getEBNFRights()) + .setGlobals(grammar.getGlobals()) + .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) + .build(); + } + + // After EBNF translation + reachabilityGraph = new ReachabilityGraph(grammar).getReachabilityGraph(); + + FindOffsidesVisitor findOffsides = new FindOffsidesVisitor(); + findOffsides.find(grammar); + offsided = findOffsides.getOffsides(); + + reachabilityGraph.entrySet().forEach(e -> { + if (offsided.contains(e.getKey().getName())) { + e.getValue().forEach(n -> offsided.add(n.getName())); + } + }); + + DesugarAlignAndOffsideVisitor desugarOffsides = new DesugarAlignAndOffsideVisitor(offsided); + desugarOffsides.doAlign(doAlign); + + Set rules = new LinkedHashSet<>(); + + for (RuntimeRule rule : grammar.getRules()) + rules.add(desugarOffsides.transform(rule, grammar.getLayout())); + + return RuntimeGrammar.builder().addRules(rules) + .setLayout(grammar.getLayout()) + .setStartSymbols(grammar.getStartSymbols()) + .setGlobals(grammar.getGlobals()) + .setEbnfLefts(grammar.getEBNFLefts()) + .setEbnfRights(grammar.getEBNFRights()) + .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) + .build(); + } + + private static class DesugarAlignAndOffsideVisitor implements ISymbolVisitor { + + private static final String ind = "ind"; + private static final String first = "fst"; + private static final String index = "i"; + + private static final Expression ind_exp = var(ind); + private static final Expression first_exp = var(first); + private static final Expression index_exp = var(index); + + private static final String l_align = "a"; + private static final String l_offside = "o"; + + private boolean doAlign; + + private final Set offsided; + + private RuntimeRule rule; + private Symbol layout; + + private boolean isOffsided; + + private int i; + + public DesugarAlignAndOffsideVisitor(Set offsided) { + this.offsided = offsided; + } + + public void doAlign(boolean doAlign) { + this.doAlign = doAlign; + } + + public RuntimeRule transform(RuntimeRule rule, Symbol layout) { + this.rule = rule; + this.layout = layout; + this.isOffsided = false; + i = 0; + + if (doAlign) { + List symbols = new ArrayList<>(); + RuntimeRule.Builder builder = rule.copy(); + + if (this.rule.getBody() != null) { + + builder = builder.setSymbols(symbols); + + for (Symbol symbol : this.rule.getBody()) { // if (symbol instanceof Align) { -// Symbol sym = ((Align) symbol).getSymbol(); -// if (sym instanceof Plus || sym instanceof Star || sym instanceof Sequence) { -// Symbol s = symbol.accept(this); -// String l3 = l_align + i++; -// Nonterminal longest = getLayout().copyBuilder().setLabel(l3) -// .addPostCondition(predicate(or(endOfFile(rExt(l3)), lessEq(indent(rExt(l3)), indent(lExt(s.getLabel())))))) -// .build(); -// symbols.add(s); -// symbols.add(longest); -// continue; -// } -// } - symbols.add(symbol.accept(this)); - } - } - - return builder.build(); - } - - isOffsided = offsided.contains(this.rule.getHead().getName()); - - RuntimeRule.Builder builder; - - if (isOffsided) - builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters(index, ind, first).build()); - else - builder = rule.copy(); - - List symbols = new ArrayList<>(); - - if (this.rule.getBody() != null) { - - builder = builder.setSymbols(symbols); - - for (Symbol symbol : this.rule.getBody()) { - symbols.add(symbol.accept(this)); - } - } - - return builder.build(); - } - - @Override - public Symbol visit(Align symbol) { - - if (doAlign) { - Symbol sym = symbol.getSymbol().accept(this); - - if (sym instanceof Plus) { - String l1 = getLabel(symbol, sym); - - Plus plus = (Plus) sym; - - Symbol s = plus.getSymbol(); - String l2 = s.getLabel() != null? s.getLabel() : l_align + i++; // TODO: conflicting labels - - s = getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2); - - return new Plus.Builder(s).addSeparators(plus.getSeparators()).setLabel(l1).addConditions(plus).addConditions(symbol).build(); - - } else if (sym instanceof Star) { - String l1 = getLabel(symbol, sym); - - Star star = (Star) sym; - - Symbol s = star.getSymbol(); - String l2 = s.getLabel() != null? s.getLabel() : l_align + i++; // TODO: conflicting labels - - s = getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2); - - return new Star.Builder(s).addSeparators(star.getSeparators()).setLabel(l1).addConditions(star).addConditions(symbol).build(); - } else if (sym instanceof Group) { - String l1 = getLabel(symbol, sym); - - @SuppressWarnings("unchecked") +// Symbol sym = ((Align) symbol).getSymbol(); +// if (sym instanceof Plus || sym instanceof Star || sym instanceof Sequence) { +// Symbol s = symbol.accept(this); +// String l3 = l_align + i++; +// Nonterminal longest = getLayout().copyBuilder().setLabel(l3) +// .addPostCondition(predicate(or(endOfFile(rExt(l3)), +// lessEq(indent(rExt(l3)), indent(lExt(s.getLabel())))))) +// .build(); +// symbols.add(s); +// symbols.add(longest); +// continue; +// } +// } + symbols.add(symbol.accept(this)); + } + } + + return builder.build(); + } + + isOffsided = offsided.contains(this.rule.getHead().getName()); + + RuntimeRule.Builder builder; + + if (isOffsided) + builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters(index, ind, first).build()); + else + builder = rule.copy(); + + List symbols = new ArrayList<>(); + + if (this.rule.getBody() != null) { + + builder = builder.setSymbols(symbols); + + for (Symbol symbol : this.rule.getBody()) { + symbols.add(symbol.accept(this)); + } + } + + return builder.build(); + } + + @Override + public Symbol visit(Align symbol) { + + if (doAlign) { + Symbol sym = symbol.getSymbol().accept(this); + + if (sym instanceof Plus) { + String l1 = getLabel(symbol, sym); + + Plus plus = (Plus) sym; + + Symbol s = plus.getSymbol(); + String l2 = s.getLabel() != null ? s.getLabel() : l_align + i++; // TODO: conflicting labels + + s = getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2); + + return new Plus.Builder(s).addSeparators(plus.getSeparators()).setLabel(l1).addConditions(plus) + .addConditions(symbol).build(); + + } else if (sym instanceof Star) { + String l1 = getLabel(symbol, sym); + + Star star = (Star) sym; + + Symbol s = star.getSymbol(); + String l2 = s.getLabel() != null ? s.getLabel() : l_align + i++; // TODO: conflicting labels + + s = getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2); + + return new Star.Builder(s).addSeparators(star.getSeparators()).setLabel(l1).addConditions(star) + .addConditions(symbol).build(); + } else if (sym instanceof Group) { + String l1 = getLabel(symbol, sym); + + @SuppressWarnings("unchecked") Group seq = (Group) sym; - - List symbols = seq.getSymbols(); - List syms = new ArrayList<>(); - - for (Symbol s : symbols) { - String l2 = s.getLabel() != null? s.getLabel() : l_align + i++; // TODO: conflicting labels - syms.add(getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2)); - } - - return new Group.Builder(syms).setLabel(l1) - .addConditions(seq).addConditions(symbol).build(); - } else - return sym; - } - - Symbol sym = symbol.getSymbol().accept(this); - - return sym == symbol.getSymbol()? symbol - : new Align.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(Block symbol) { - List symbols = symbol.getSymbols(); - Symbol[] syms = new Symbol[symbols.size()]; - - int j = 0; - boolean modified = false; - for (Symbol sym : symbols) { - - syms[j] = sym.accept(this); - if (sym != syms[j]) - modified |= true; - j++; - } - - return modified? new Block.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() - : symbol; - } - - @Override - public Symbol visit(Code symbol) { - Symbol sym = symbol.getSymbol().accept(this); - if (sym == symbol.getSymbol()) - return symbol; - - return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(Error error) { - return error; - } - - @Override - public Symbol visit(Conditional symbol) { - Symbol sym = symbol.getSymbol().accept(this); - if (sym == symbol.getSymbol()) - return symbol; - - return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(IfThen symbol) { - Symbol sym = symbol.getThenPart().accept(this); - if (sym == symbol.getThenPart()) - return symbol; - - return new IfThen.Builder(symbol.getExpression(), sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(IfThenElse symbol) { - Symbol thenPart = symbol.getThenPart().accept(this); - Symbol elsePart = symbol.getElsePart().accept(this); - if (thenPart == symbol.getThenPart() - && elsePart == symbol.getElsePart()) - return symbol; - - return new IfThenElse.Builder(symbol.getExpression(), thenPart, elsePart).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(Nonterminal symbol) { - if (isOffsided && offsided.contains(symbol.getName())) { // The rule has a parameter for indentation, and therefore, also all reachable nonterminals - String l = symbol.getLabel() != null? symbol.getLabel() : l_offside + i++; - return symbol.copy().apply(// (fst & (lExt - index == 0)) == 1? index : 0 or fst == 1? index : 0 - // after non-nullable (0 as only indentation will be needed) - andIndent(index_exp, first_exp, lExt(l), true), - ind_exp, - // fst & (lExt - index == 0) or 0 after non-nullable - andIndent(index_exp, first_exp, lExt(l))) - .setLabel(l).build(); - } else if (offsided.contains(symbol.getName())) // A ::= offside B; B ::= D; C ::= B or C ::= D - return symbol.copy().apply(integer(0), integer(0), integer(0)).build(); - else - return symbol; - } - - @Override - public Symbol visit(Ignore symbol) { - if (doAlign) { - Symbol sym = symbol.getSymbol().accept(this); - - return sym == symbol.getSymbol()? symbol - : new Ignore.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - Symbol sym = symbol.getSymbol(); - - if (sym instanceof Nonterminal) { - Nonterminal s = (Nonterminal) sym; - - if (offsided.contains(s.getName())) { // TODO: too general - return s.copy() - .apply(integer(0), integer(0), integer(0)) - .addConditions(symbol) - .addConditions(sym) - .build(); - } - } - - // Otherwise, ignore 'ignore' - sym = sym.accept(this); - return sym.copy().addConditions(symbol).build(); - } - - @Override - public Symbol visit(Offside symbol) { - - if (doAlign) { - Symbol sym = symbol.getSymbol().accept(this); - - return sym == symbol.getSymbol()? symbol - : new Offside.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - Symbol sym = symbol.getSymbol(); - - if (sym instanceof Nonterminal) { - Nonterminal s = (Nonterminal) sym; - - String l = symbol.getLabel(); - if (l != null && s.getLabel() != null) { - if (!l.equals(s.getLabel())) - throw new RuntimeException("Conflicting labels: " + symbol); - } else if (s.getLabel() != null) - l = s.getLabel(); - else if (l == null && s.getLabel() == null) - l = l_offside + i++; - - if (isOffsided) { // Offside inside a rule that has a parameter for indentation - return s.copy() - .apply(lExt(l), indent(lExt(l)), integer(1)) - .setLabel(l) - .addConditions(symbol) - .addConditions(sym) - // [ ind == 0 || (first && l.lExt - index == 0) || indent(l.lExt) > ind] - .addPreCondition(predicate(orIndent(index_exp, ind_exp, first_exp, lExt(l)))) - .build(); - } else { - return s.copy() - .apply(lExt(l), indent(lExt(l)), integer(1)) - .setLabel(l) - .addConditions(symbol) - .addConditions(sym) - .build(); - } - } - - // Otherwise, ignore offside - sym = sym.accept(this); - return sym.copy().addConditions(symbol).build(); - } - - @Override - public Symbol visit(Terminal symbol) { - if (isOffsided) { - String l = symbol.getLabel() != null? symbol.getLabel() : l_offside + i++; - return symbol.copy() - .setLabel(l) - .addConditions(symbol) - .addPreCondition(predicate(orIndent(index_exp, ind_exp, first_exp, lExt(l)))) - .build(); - } - return symbol; - } - - @Override - public Symbol visit(While symbol) { - Symbol body = symbol.getBody().accept(this); - if (body == symbol.getBody()) - return symbol; - - return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(Return symbol) { - return symbol; - } - - @Override - public Symbol visit(Alt symbol) { - - List symbols = symbol.getSymbols(); - List syms = new ArrayList<>(); - - boolean modified = false; - for (Symbol sym : symbols) { - Symbol s = sym.accept(this); - syms.add(s); - if (sym != s) - modified |= true; - } - - return modified? new Alt.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() - : symbol; - } - - @Override - public Symbol visit(Opt symbol) { - Symbol sym = symbol.getSymbol().accept(this); - if (sym == symbol.getSymbol()) - return symbol; - return new Opt.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); - } - - @Override - public Symbol visit(Plus symbol) { - - Symbol sym = symbol.getSymbol().accept(this); - List separators = symbol.getSeparators(); - - boolean modified = sym != symbol.getSymbol(); - - List seps = new ArrayList<>(); - for (Symbol sep : separators) { - Symbol s = sep.accept(this); - seps.add(s); - if (s != sep) - modified |= true; - } - - return modified? new Plus.Builder(sym).addSeparators(seps).setLabel(symbol.getLabel()).addConditions(symbol).build() - : symbol; - } - - @Override - public Symbol visit(Group symbol) { - - List symbols = symbol.getSymbols(); - List syms = new ArrayList<>(); - - boolean modified = false; - for (Symbol sym : symbols) { - Symbol s = sym.accept(this); - syms.add(s); - if (sym != s) - modified |= true; - } - - return modified? new Group.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() - : symbol; - } - - @Override - public Symbol visit(Star symbol) { - Symbol sym = symbol.getSymbol().accept(this); - List separators = symbol.getSeparators(); - - boolean modified = sym != symbol.getSymbol(); - - List seps = new ArrayList<>(); - for (Symbol sep : separators) { - Symbol s = sep.accept(this); - seps.add(s); - if (s != sep) - modified |= true; - } - - return modified? new Star.Builder(sym).addSeparators(seps).setLabel(symbol.getLabel()).addConditions(symbol).build() - : symbol; - } + + List symbols = seq.getSymbols(); + List syms = new ArrayList<>(); + + for (Symbol s : symbols) { + String l2 = s.getLabel() != null ? s.getLabel() : l_align + i++; // TODO: conflicting labels + syms.add(getSymbol(s, predicate(equal(indent(lExt(l2)), indent(lExt(l1)))), l2)); + } + + return new Group.Builder(syms).setLabel(l1) + .addConditions(seq).addConditions(symbol).build(); + } else + return sym; + } + + Symbol sym = symbol.getSymbol().accept(this); + + return sym == symbol.getSymbol() ? symbol + : new Align.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); + } + + @Override + public Symbol visit(Block symbol) { + List symbols = symbol.getSymbols(); + Symbol[] syms = new Symbol[symbols.size()]; + + int j = 0; + boolean modified = false; + for (Symbol sym : symbols) { + + syms[j] = sym.accept(this); + if (sym != syms[j]) + modified |= true; + j++; + } + + return modified ? new Block.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() + : symbol; + } + + @Override + public Symbol visit(Code symbol) { + Symbol sym = symbol.getSymbol().accept(this); + if (sym == symbol.getSymbol()) + return symbol; + + return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); + } + + @Override + public Symbol visit(Error error) { + return error; + } + + @Override + public Symbol visit(Conditional symbol) { + Symbol sym = symbol.getSymbol().accept(this); + if (sym == symbol.getSymbol()) + return symbol; + + return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()) + .addConditions(symbol).build(); + } + + @Override + public Symbol visit(IfThen symbol) { + Symbol sym = symbol.getThenPart().accept(this); + if (sym == symbol.getThenPart()) + return symbol; + + return new IfThen.Builder(symbol.getExpression(), sym).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); + } + + @Override + public Symbol visit(IfThenElse symbol) { + Symbol thenPart = symbol.getThenPart().accept(this); + Symbol elsePart = symbol.getElsePart().accept(this); + if (thenPart == symbol.getThenPart() + && elsePart == symbol.getElsePart()) + return symbol; + + return new IfThenElse.Builder(symbol.getExpression(), thenPart, elsePart).setLabel(symbol.getLabel()) + .addConditions(symbol).build(); + } + + @Override + public Symbol visit(Nonterminal symbol) { + // The rule has a parameter for indentation, and therefore, also all reachable nonterminals + if (isOffsided && offsided.contains(symbol.getName())) { + String l = symbol.getLabel() != null ? symbol.getLabel() : l_offside + i++; + return symbol.copy().apply(// (fst & (lExt - index == 0)) == 1? index : 0 or fst == 1? index : 0 + // after non-nullable (0 as only indentation will be needed) + andIndent(index_exp, first_exp, lExt(l), true), + ind_exp, + // fst & (lExt - index == 0) or 0 after non-nullable + andIndent(index_exp, first_exp, lExt(l))) + .setLabel(l).build(); + } else if (offsided.contains(symbol.getName())) // A ::= offside B; B ::= D; C ::= B or C ::= D + return symbol.copy().apply(integer(0), integer(0), integer(0)).build(); + else + return symbol; + } + + @Override + public Symbol visit(Ignore symbol) { + if (doAlign) { + Symbol sym = symbol.getSymbol().accept(this); + + return sym == symbol.getSymbol() ? symbol + : new Ignore.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); + } + + Symbol sym = symbol.getSymbol(); + + if (sym instanceof Nonterminal) { + Nonterminal s = (Nonterminal) sym; + + if (offsided.contains(s.getName())) { // TODO: too general + return s.copy() + .apply(integer(0), integer(0), integer(0)) + .addConditions(symbol) + .addConditions(sym) + .build(); + } + } + + // Otherwise, ignore 'ignore' + sym = sym.accept(this); + return sym.copy().addConditions(symbol).build(); + } + + @Override + public Symbol visit(Offside symbol) { + + if (doAlign) { + Symbol sym = symbol.getSymbol().accept(this); + + return sym == symbol.getSymbol() ? symbol + : new Offside.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); + } + + Symbol sym = symbol.getSymbol(); + + if (sym instanceof Nonterminal) { + Nonterminal s = (Nonterminal) sym; + + String l = symbol.getLabel(); + if (l != null && s.getLabel() != null) { + if (!l.equals(s.getLabel())) + throw new RuntimeException("Conflicting labels: " + symbol); + } else if (s.getLabel() != null) + l = s.getLabel(); + else if (l == null && s.getLabel() == null) + l = l_offside + i++; + + if (isOffsided) { // Offside inside a rule that has a parameter for indentation + return s.copy() + .apply(lExt(l), indent(lExt(l)), integer(1)) + .setLabel(l) + .addConditions(symbol) + .addConditions(sym) + // [ ind == 0 || (first && l.lExt - index == 0) || indent(l.lExt) > ind] + .addPreCondition(predicate(orIndent(index_exp, ind_exp, first_exp, lExt(l)))) + .build(); + } else { + return s.copy() + .apply(lExt(l), indent(lExt(l)), integer(1)) + .setLabel(l) + .addConditions(symbol) + .addConditions(sym) + .build(); + } + } + + // Otherwise, ignore offside + sym = sym.accept(this); + return sym.copy().addConditions(symbol).build(); + } + + @Override + public Symbol visit(Terminal symbol) { + if (isOffsided) { + String l = symbol.getLabel() != null ? symbol.getLabel() : l_offside + i++; + return symbol.copy() + .setLabel(l) + .addConditions(symbol) + .addPreCondition(predicate(orIndent(index_exp, ind_exp, first_exp, lExt(l)))) + .build(); + } + return symbol; + } + + @Override + public Symbol visit(While symbol) { + Symbol body = symbol.getBody().accept(this); + if (body == symbol.getBody()) + return symbol; + + return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); + } + + @Override + public Symbol visit(Return symbol) { + return symbol; + } + + @Override + public Symbol visit(Alt symbol) { + + List symbols = symbol.getSymbols(); + List syms = new ArrayList<>(); + + boolean modified = false; + for (Symbol sym : symbols) { + Symbol s = sym.accept(this); + syms.add(s); + if (sym != s) + modified |= true; + } + + return modified ? new Alt.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() + : symbol; + } + + @Override + public Symbol visit(Opt symbol) { + Symbol sym = symbol.getSymbol().accept(this); + if (sym == symbol.getSymbol()) + return symbol; + return new Opt.Builder(sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); + } + + @Override + public Symbol visit(Plus symbol) { + + Symbol sym = symbol.getSymbol().accept(this); + List separators = symbol.getSeparators(); + + boolean modified = sym != symbol.getSymbol(); + + List seps = new ArrayList<>(); + for (Symbol sep : separators) { + Symbol s = sep.accept(this); + seps.add(s); + if (s != sep) + modified |= true; + } + + return modified ? new Plus.Builder(sym).addSeparators(seps).setLabel(symbol.getLabel()) + .addConditions(symbol).build() + : symbol; + } + + @Override + public Symbol visit(Group symbol) { + + List symbols = symbol.getSymbols(); + List syms = new ArrayList<>(); + + boolean modified = false; + for (Symbol sym : symbols) { + Symbol s = sym.accept(this); + syms.add(s); + if (sym != s) + modified |= true; + } + + return modified ? new Group.Builder(syms).setLabel(symbol.getLabel()).addConditions(symbol).build() + : symbol; + } + + @Override + public Symbol visit(Star symbol) { + Symbol sym = symbol.getSymbol().accept(this); + List separators = symbol.getSeparators(); + + boolean modified = sym != symbol.getSymbol(); + + List seps = new ArrayList<>(); + for (Symbol sep : separators) { + Symbol s = sep.accept(this); + seps.add(s); + if (s != sep) + modified |= true; + } + + return modified ? new Star.Builder(sym).addSeparators(seps).setLabel(symbol.getLabel()) + .addConditions(symbol).build() + : symbol; + } @Override public Symbol visit(Start start) { @@ -526,178 +539,178 @@ public Symbol visit(Start start) { } private String getLabel(Align align, Symbol symbol) { - String label = null; - - if (align.getLabel() != null && symbol.getLabel() != null) { - if (!align.getLabel().equals(symbol.getLabel())) - throw new RuntimeException("Two conflicting labels: " + align); - else - label = align.getLabel(); - } else if (align.getLabel() != null) - label = align.getLabel(); - else if (symbol.getLabel() != null) - label = symbol.getLabel(); - - return label != null? label : l_align + i++; - } - - private Symbol getSymbol(Symbol symbol, Condition precondition, String label) { - - if (symbol instanceof Offside) { - Offside sym = (Offside) symbol; - return new Offside.Builder(sym.getSymbol().copy().addPreCondition(precondition).setLabel(label).build()) - .addConditions(symbol).setLabel(symbol.getLabel()).build(); - } - - return symbol.copy().addPreCondition(precondition).setLabel(label).build(); - } - - @SuppressWarnings("unused") - private Symbol getLayout() { - switch(rule.getLayoutStrategy()) { - case NO_LAYOUT: - throw new RuntimeException("Align should not be part of lexicals."); - case INHERITED: - return layout; - case FIXED: - return rule.getLayout(); - } - return layout; - } - - } - - private static class FindOffsidesVisitor implements ISymbolVisitor { - - private final Set offsided; - - public FindOffsidesVisitor() { - this.offsided = new HashSet<>(); - } - - public Set getOffsides() { - return offsided; - } - - public void find(RuntimeGrammar grammar) { - - for (RuntimeRule rule : grammar.getRules()) { - if (rule.getBody() == null) - continue; - - for (Symbol s : rule.getBody()) - s.accept(this); - } - } - - @Override - public Void visit(Offside symbol) { - Symbol sym = symbol.getSymbol(); - - // Offside will only be applied to nonterminals - if (sym instanceof Nonterminal) - offsided.add(((Nonterminal) sym).getName()); - - return sym.accept(this); - } - - @Override - public Void visit(Align symbol) { - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(Block symbol) { - for (Symbol sym : symbol.getSymbols()) - sym.accept(this); - return null; - } - - @Override - public Void visit(Code symbol) { - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(Error error) { - return null; - } - - @Override - public Void visit(Conditional symbol) { - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(IfThen symbol) { - return symbol.getThenPart().accept(this); - } - - @Override - public Void visit(IfThenElse symbol) { - symbol.getThenPart().accept(this); - symbol.getElsePart().accept(this); - return null; - } - - @Override - public Void visit(Ignore symbol) { - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(Nonterminal symbol) { - return null; - } - - @Override - public Void visit(Terminal symbol) { - return null; - } - - @Override - public Void visit(While symbol) { - return symbol.getBody().accept(this); - } - - @Override - public Void visit(Return symbol) { - // TODO: support for return - return null; - } - - @Override - public Void visit(Alt symbol) { - for (Symbol sym : symbol.getSymbols()) - sym.accept(this); - return null; - } - - @Override - public Void visit(Opt symbol) { - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(Plus symbol) { - for (Symbol sym : symbol.getSeparators()) - sym.accept(this); - return symbol.getSymbol().accept(this); - } - - @Override - public Void visit(Group symbol) { - for (Symbol sym : symbol.getSymbols()) - sym.accept(this); - return null; - } - - @Override - public Void visit(Star symbol) { - for (Symbol sym : symbol.getSeparators()) - sym.accept(this); - return symbol.getSymbol().accept(this); - } + String label = null; + + if (align.getLabel() != null && symbol.getLabel() != null) { + if (!align.getLabel().equals(symbol.getLabel())) + throw new RuntimeException("Two conflicting labels: " + align); + else + label = align.getLabel(); + } else if (align.getLabel() != null) + label = align.getLabel(); + else if (symbol.getLabel() != null) + label = symbol.getLabel(); + + return label != null ? label : l_align + i++; + } + + private Symbol getSymbol(Symbol symbol, Condition precondition, String label) { + + if (symbol instanceof Offside) { + Offside sym = (Offside) symbol; + return new Offside.Builder(sym.getSymbol().copy().addPreCondition(precondition).setLabel(label).build()) + .addConditions(symbol).setLabel(symbol.getLabel()).build(); + } + + return symbol.copy().addPreCondition(precondition).setLabel(label).build(); + } + + @SuppressWarnings("unused") + private Symbol getLayout() { + switch (rule.getLayoutStrategy()) { + case NO_LAYOUT: + throw new RuntimeException("Align should not be part of lexicals."); + case INHERITED: + return layout; + case FIXED: + return rule.getLayout(); + } + return layout; + } + + } + + private static class FindOffsidesVisitor implements ISymbolVisitor { + + private final Set offsided; + + public FindOffsidesVisitor() { + this.offsided = new HashSet<>(); + } + + public Set getOffsides() { + return offsided; + } + + public void find(RuntimeGrammar grammar) { + + for (RuntimeRule rule : grammar.getRules()) { + if (rule.getBody() == null) + continue; + + for (Symbol s : rule.getBody()) + s.accept(this); + } + } + + @Override + public Void visit(Offside symbol) { + Symbol sym = symbol.getSymbol(); + + // Offside will only be applied to nonterminals + if (sym instanceof Nonterminal) + offsided.add(((Nonterminal) sym).getName()); + + return sym.accept(this); + } + + @Override + public Void visit(Align symbol) { + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(Block symbol) { + for (Symbol sym : symbol.getSymbols()) + sym.accept(this); + return null; + } + + @Override + public Void visit(Code symbol) { + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(Error error) { + return null; + } + + @Override + public Void visit(Conditional symbol) { + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(IfThen symbol) { + return symbol.getThenPart().accept(this); + } + + @Override + public Void visit(IfThenElse symbol) { + symbol.getThenPart().accept(this); + symbol.getElsePart().accept(this); + return null; + } + + @Override + public Void visit(Ignore symbol) { + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(Nonterminal symbol) { + return null; + } + + @Override + public Void visit(Terminal symbol) { + return null; + } + + @Override + public Void visit(While symbol) { + return symbol.getBody().accept(this); + } + + @Override + public Void visit(Return symbol) { + // TODO: support for return + return null; + } + + @Override + public Void visit(Alt symbol) { + for (Symbol sym : symbol.getSymbols()) + sym.accept(this); + return null; + } + + @Override + public Void visit(Opt symbol) { + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(Plus symbol) { + for (Symbol sym : symbol.getSeparators()) + sym.accept(this); + return symbol.getSymbol().accept(this); + } + + @Override + public Void visit(Group symbol) { + for (Symbol sym : symbol.getSymbols()) + sym.accept(this); + return null; + } + + @Override + public Void visit(Star symbol) { + for (Symbol sym : symbol.getSeparators()) + sym.accept(this); + return symbol.getSymbol().accept(this); + } @Override public Void visit(Start start) { diff --git a/src/org/iguana/grammar/transformation/DesugarPrecedenceAndAssociativity.java b/src/org/iguana/grammar/transformation/DesugarPrecedenceAndAssociativity.java index 4aaeec69d..826a03529 100644 --- a/src/org/iguana/grammar/transformation/DesugarPrecedenceAndAssociativity.java +++ b/src/org/iguana/grammar/transformation/DesugarPrecedenceAndAssociativity.java @@ -135,13 +135,14 @@ boolean hasPostfix(int lhs) { } boolean hasPrefixBelow(int lhs) { - if (prefixBelow == -1) { - prefixBelow = prefix_rules.isEmpty()? 0 : prefix_rules.keySet().stream().min(Comparator.naturalOrder()).get(); - if (!iprefix_rules.isEmpty()) { - int other = iprefix_rules.keySet().stream().min(Comparator.naturalOrder()).get(); - prefixBelow = Integer.min(prefixBelow, other); - } - } + if (prefixBelow == -1) { + prefixBelow = prefix_rules.isEmpty() ? 0 : prefix_rules.keySet().stream().min(Comparator.naturalOrder()) + .get(); + if (!iprefix_rules.isEmpty()) { + int other = iprefix_rules.keySet().stream().min(Comparator.naturalOrder()).get(); + prefixBelow = Integer.min(prefixBelow, other); + } + } if (prefixBelow == 0) return false; @@ -157,7 +158,8 @@ boolean hasPrefixBelow(int lhs) { @SuppressWarnings("unused") boolean hasPostfixBelow(int lhs) { if (postfixBelow == -1) { - postfixBelow = postfix_rules.isEmpty()? 0 : postfix_rules.keySet().stream().min(Comparator.naturalOrder()).get(); + postfixBelow = postfix_rules.isEmpty() ? 0 : postfix_rules.keySet().stream().min( + Comparator.naturalOrder()).get(); if (!ipostfix_rules.isEmpty()) { int other = ipostfix_rules.keySet().stream().min(Comparator.naturalOrder()).get(); postfixBelow = Integer.max(postfixBelow, other); @@ -237,8 +239,12 @@ private static boolean canBePrefix(String nt, String leftEnd, Map configs, boolean compute) { + + private static boolean canBePostfix( + String nt, + String rightEnd, + Map configs, + boolean compute) { Configuration config = configs.get(nt); @@ -343,8 +349,10 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { } // 2. Precedence - if (rule.getPrecedenceLevel().getRhs() != 1 || (rule.getPrecedence() == 1 && rule.getAssociativity() != Associativity.UNDEFINED)) + if (rule.getPrecedenceLevel().getRhs() != 1 || + (rule.getPrecedence() == 1 && rule.getAssociativity() != Associativity.UNDEFINED)) { leftOrRightRecursiveNonterminals.add(head.getName()); + } // else: all the rules have a precedence -1 (non-recursive), or 1 and // undefined associativity; therefore, precedence does not apply @@ -359,9 +367,9 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { boolean isBinary = rule.isLeftRecursive() && rule.isRightRecursive(); boolean isPrefix = !(rule.isLeftRecursive() || rule.isILeftRecursive()) && rule.isRightRecursive(); boolean isPostfix = rule.isLeftRecursive() && !(rule.isRightRecursive() || rule.isIRightRecursive()); - + boolean canBeBinary = ((rule.isLeftRecursive() || rule.isILeftRecursive()) && rule.isIRightRecursive()) - || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); + || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); boolean canBePrefix = false; boolean canBePostfix = false; @@ -474,8 +482,9 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { default: } } - - boolean climbing = prec_level.getLhs() == assoc_group.getLhs() && prec_level.getRhs() == assoc_group.getRhs(); + + boolean climbing = + prec_level.getLhs() == assoc_group.getLhs() && prec_level.getRhs() == assoc_group.getRhs(); if (climbing) { if (isBinary && rule.getPrecedence() != assoc_group.getPrecedence()) @@ -538,8 +547,9 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { Integer arity = config.groups.get(prec_level.getLhs()); if (assoc_group != null) { - - boolean climbing = prec_level.getLhs() == assoc_group.getLhs() && prec_level.getRhs() == assoc_group.getRhs(); + + boolean climbing = + prec_level.getLhs() == assoc_group.getLhs() && prec_level.getRhs() == assoc_group.getRhs(); if (climbing) { @@ -552,12 +562,14 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { boolean canHaveBinary = config.ibinary_rules.get(prec_level.getLhs()) != null; boolean canHavePrefix = config.iprefix_rules.get(prec_level.getLhs()) != null; boolean canHavePostfix = config.ipostfix_rules.get(prec_level.getLhs()) != null; - - if (((hasBinary || canHaveBinary) && (hasPrefix || hasPostfix || canHavePrefix || canHavePostfix)) - || ((hasPrefix || canHavePrefix) && (hasPostfix || canHavePostfix))) { + + if (((hasBinary || canHaveBinary) && + (hasPrefix || hasPostfix || canHavePrefix || canHavePostfix)) + || ((hasPrefix || canHavePrefix) && (hasPostfix || canHavePostfix))) { Associativity assoc = assoc_group.getAssociativity(); - - if ((assoc == Associativity.LEFT || assoc == Associativity.NON_ASSOC) && (hasPostfix || canHavePostfix)) { + + if ((assoc == Associativity.LEFT || assoc == Associativity.NON_ASSOC) && + (hasPostfix || canHavePostfix)) { for (int group : config.binary_rules.keySet()) { if (group > rule.getPrecedence()) { if (arity == null || arity == 3) @@ -592,7 +604,8 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { } } } - if ((assoc == Associativity.RIGHT || assoc == Associativity.NON_ASSOC) && (hasPrefix || canHavePostfix)) { + if ((assoc == Associativity.RIGHT || assoc == Associativity.NON_ASSOC) && + (hasPrefix || canHavePostfix)) { for (int group : config.binary_rules.keySet()) { if (group > rule.getPrecedence()) { if (arity == null || arity == 2) @@ -635,8 +648,9 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { if (arity == null || arity != 4) { boolean isBinary = rule.isLeftRecursive() && rule.isRightRecursive(); - boolean canBeBinary = ((rule.isLeftRecursive() || rule.isILeftRecursive()) && rule.isIRightRecursive()) - || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); + boolean canBeBinary = + ((rule.isLeftRecursive() || rule.isILeftRecursive()) && rule.isIRightRecursive()) + || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); Set binary_rules = config.binary_rules.get(prec_level.getLhs()); Set prefix_rules = config.prefix_rules.get(prec_level.getLhs()); @@ -659,8 +673,9 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { + (iprefix_rules == null ? 0 : iprefix_rules.size()); if (rule.getAssociativity() != Associativity.UNDEFINED) { - - if (isBinary && (rule.getAssociativity() == Associativity.LEFT || rule.getAssociativity() == Associativity.NON_ASSOC)) { + + if (isBinary && (rule.getAssociativity() == Associativity.LEFT || + rule.getAssociativity() == Associativity.NON_ASSOC)) { // As associatvity is defined, rule.getPrecedence() is unique; // therefore, maintaining <_>_rules as precedence sets, for each precedence level // should sufficient @@ -672,8 +687,9 @@ else if (n != 3) config.groups.put(prec_level.getLhs(), 4); } } - - if (isBinary && (rule.getAssociativity() == Associativity.RIGHT || rule.getAssociativity() == Associativity.NON_ASSOC)) { + + if (isBinary && (rule.getAssociativity() == Associativity.RIGHT || + rule.getAssociativity() == Associativity.NON_ASSOC)) { if (right_rec + iright_rec >= 2) { Integer n = config.groups.get(prec_level.getLhs()); if (n == null) @@ -683,8 +699,9 @@ else if (n != 2) } } - - if (!(isBinary || canBeBinary) && rule.isRightRecursive() && rule.getAssociativity() == Associativity.NON_ASSOC) { + + if (!(isBinary || canBeBinary) && rule.isRightRecursive() && + rule.getAssociativity() == Associativity.NON_ASSOC) { if (left_rec + ileft_rec >= 1) { Integer n = config.groups.get(prec_level.getLhs()); if (n == null) @@ -765,9 +782,10 @@ else if (n != 3) .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) .build(); } - + public RuntimeRule transform(RuntimeRule rule) { - return new Visitor(rule, leftOrRightRecursiveNonterminals, headsWithLabeledRules, configs, config_op).transform(); + return new Visitor(rule, leftOrRightRecursiveNonterminals, headsWithLabeledRules, configs, + config_op).transform(); } private static class Visitor implements ISymbolVisitor { @@ -815,9 +833,14 @@ private static class Visitor implements ISymbolVisitor { private Expression[] lret; private Expression[] rret; - - public Visitor(RuntimeRule rule, Set leftOrRightRecursiveNonterminals, Map> headsWithLabeledRules, - Map configs, OP config_op) { + + public Visitor( + RuntimeRule rule, + Set leftOrRightRecursiveNonterminals, + Map> headsWithLabeledRules, + Map configs, + OP config_op + ) { this.rule = rule; this.leftOrRightRecursiveNonterminals = leftOrRightRecursiveNonterminals; this.headsWithLabeledRules = headsWithLabeledRules; @@ -901,10 +924,11 @@ private void excepts2() { n += 1 << i; } - + if (!leftOrRightRecursiveNonterminals.contains(rule.getHead().getName())) xlcond = or(equal(var("l"), integer(-1)), lShiftANDEqZero(integer(n), var("l"))); - else xlcond = or(equal(get(var("l"), 1), integer(-1)), lShiftANDEqZero(integer(n), get(var("l"), 1))); + else xlcond = or(equal(get(var("l"), 1), integer(-1)), + lShiftANDEqZero(integer(n), get(var("l"), 1))); } } } @@ -948,7 +972,9 @@ private void precedence1() { // Priority and associativity l1 = integer(precedenceLevel.getRhs() + 1); r2 = integer(precedenceLevel.getRhs() + 1); break; - default: throw new RuntimeException("Unexpected associativity: " + associativityGroup.getAssociativity()); + default: + throw new RuntimeException( + "Unexpected associativity: " + associativityGroup.getAssociativity()); } // Rule for propagation of a precedence level @@ -970,11 +996,13 @@ else if (precedenceLevel.hasPrefixUnary()) r2 = integer(precedence); // Rule for propagation of a precedence level - l2 = nUseMin? var("l") : precedenceLevel.hasPrefixUnaryBelow()? pr(precedence, precedenceLevel.prefixUnaryBelow, true) : integer(0); - r1 = nUseMin? var("r") : precedenceLevel.hasPostfixUnaryBelow()? pr(precedence, precedenceLevel.postfixUnaryBelow, false) : integer(0); + l2 = nUseMin ? var("l") : precedenceLevel.hasPrefixUnaryBelow() ? pr(precedence, + precedenceLevel.prefixUnaryBelow, true) : integer(0); + r1 = nUseMin ? var("r") : precedenceLevel.hasPostfixUnaryBelow() ? pr(precedence, + precedenceLevel.postfixUnaryBelow, false) : integer(0); } - - } else if (associativityGroup == null && precedenceLevel.getLhs() == precedenceLevel.getRhs()) { // Can use precedence climbing + // Can use precedence climbing + } else if (associativityGroup == null && precedenceLevel.getLhs() == precedenceLevel.getRhs()) { boolean first = precedenceLevel.getUndefined() == 0; int il1 = -1; int ir2 = -1; switch(associativity) { @@ -1007,22 +1035,25 @@ else if (precedenceLevel.hasPrefixUnary()) // Rule for propagation of a precedence level if (precedenceLevel.hasPostfixUnaryBelow()) - r1 = nUseMin? var("r") : pr(precedenceLevel.hasPostfixUnary()? precedence : il1, precedenceLevel.postfixUnaryBelow, false); + r1 = nUseMin ? var("r") : pr(precedenceLevel.hasPostfixUnary() ? precedence : il1, + precedenceLevel.postfixUnaryBelow, false); else if (precedenceLevel.hasPostfixUnary()) - r1 = integer(first? 0 : precedence); - else + r1 = integer(first ? 0 : precedence); + else r1 = l1; - + if (precedenceLevel.hasPrefixUnaryBelow()) - l2 = nUseMin? var("l") : pr(precedenceLevel.hasPrefixUnary()? precedence : ir2, precedenceLevel.prefixUnaryBelow, true); + l2 = nUseMin ? var("l") : pr(precedenceLevel.hasPrefixUnary() ? precedence : ir2, + precedenceLevel.prefixUnaryBelow, true); else if (precedenceLevel.hasPrefixUnary()) - l2 = integer(first? 0 : precedence); - else + l2 = integer(first ? 0 : precedence); + else l2 = r2; } else { // No precedence climbing int undefined = precedenceLevel.getUndefined(); - boolean useUndefined = (associativityGroup == null || (associativityGroup != null && associativityGroup.getPrecedence() == precedence)) - && undefined != -1; + boolean useUndefined = (associativityGroup == null || (associativityGroup != null && + associativityGroup.getPrecedence() == + precedence)) && undefined != -1; switch((associativityGroup != null && associativity == Associativity.UNDEFINED)? associativityGroup.getAssociativity() : associativity) { @@ -1030,29 +1061,37 @@ else if (precedenceLevel.hasPrefixUnary()) l1 = integer(useUndefined? undefined : precedence); r2 = integer(precedence); // Rule for propagation of a precedence level - l2 = nUseMin? var("l") : precedenceLevel.hasPrefixUnaryBelow()? pr(precedence, precedenceLevel.prefixUnaryBelow, true) : integer(0); - r1 = nUseMin? var("r") : precedenceLevel.hasPostfixUnaryBelow()? pr(precedence, precedenceLevel.postfixUnaryBelow, false) : integer(useUndefined? undefined : 0); + l2 = nUseMin ? var("l") : precedenceLevel.hasPrefixUnaryBelow() ? pr(precedence, + precedenceLevel.prefixUnaryBelow, true) : integer(0); + r1 = nUseMin ? var("r") : precedenceLevel.hasPostfixUnaryBelow() ? pr(precedence, + precedenceLevel.postfixUnaryBelow, false) : integer(useUndefined ? undefined : 0); break; case RIGHT: l1 = integer(precedence); r2 = integer(useUndefined? undefined : precedence); // Rule for propagation of a precedence level - l2 = nUseMin? var("l") : precedenceLevel.hasPrefixUnaryBelow()? pr(precedence, precedenceLevel.prefixUnaryBelow, true) : integer(useUndefined? undefined : 0); - r1 = nUseMin? var("r") : precedenceLevel.hasPostfixUnaryBelow()? pr(precedence, precedenceLevel.postfixUnaryBelow, false) : integer(0); + l2 = nUseMin ? var("l") : precedenceLevel.hasPrefixUnaryBelow() ? pr(precedence, + precedenceLevel.prefixUnaryBelow, true) : integer(useUndefined ? undefined : 0); + r1 = nUseMin ? var("r") : precedenceLevel.hasPostfixUnaryBelow() ? pr(precedence, + precedenceLevel.postfixUnaryBelow, false) : integer(0); break; case NON_ASSOC: l1 = integer(precedence); r2 = integer(precedence); // Rule for propagation of a precedence level - l2 = nUseMin? var("l") : precedenceLevel.hasPrefixUnaryBelow()? pr(precedence, precedenceLevel.prefixUnaryBelow, true) : integer(0); - r1 = nUseMin? var("r") : precedenceLevel.hasPostfixUnaryBelow()? pr(precedence, precedenceLevel.postfixUnaryBelow, false) : integer(0); + l2 = nUseMin ? var("l") : precedenceLevel.hasPrefixUnaryBelow() ? pr(precedence, + precedenceLevel.prefixUnaryBelow, true) : integer(0); + r1 = nUseMin ? var("r") : precedenceLevel.hasPostfixUnaryBelow() ? pr(precedence, + precedenceLevel.postfixUnaryBelow, false) : integer(0); break; case UNDEFINED: // Not in the associativity group l1 = integer(undefined); r2 = integer(undefined); // Rule for propagation of a precedence level - l2 = nUseMin? var("l") : precedenceLevel.hasPrefixUnaryBelow()? pr(precedence, precedenceLevel.prefixUnaryBelow, true) : integer(undefined); - r1 = nUseMin? var("r") : precedenceLevel.hasPostfixUnaryBelow()? pr(precedence, precedenceLevel.postfixUnaryBelow, false) : integer(undefined); + l2 = nUseMin ? var("l") : precedenceLevel.hasPrefixUnaryBelow() ? pr(precedence, + precedenceLevel.prefixUnaryBelow, true) : integer(undefined); + r1 = nUseMin ? var("r") : precedenceLevel.hasPostfixUnaryBelow() ? pr(precedence, + precedenceLevel.postfixUnaryBelow, false) : integer(undefined); break; default: throw new RuntimeException("Unexpected associativity: " + associativity); } @@ -1077,10 +1116,12 @@ else if (precedenceLevel.hasPrefixUnary()) case LEFT: if (rule.isLeftRecursive()) { if (!climbing) - preconditions.add(predicate(notEqual(integer(associativityGroup.getPrecedence()), var("r")))); - + preconditions.add( + predicate(notEqual(integer(associativityGroup.getPrecedence()), var("r")))); + if (!associativityGroup.getAssocMap().isEmpty()) - for (Map.Entry entry : associativityGroup.getAssocMap().entrySet()) + for (Map.Entry entry : associativityGroup.getAssocMap() + .entrySet()) if (precedence != entry.getKey()) preconditions.add(predicate(notEqual(integer(entry.getKey()), var("r")))); } @@ -1088,30 +1129,39 @@ else if (precedenceLevel.hasPrefixUnary()) case RIGHT: if (rule.isRightRecursive()) { if (!climbing) - preconditions.add(predicate(notEqual(integer(associativityGroup.getPrecedence()), var("l")))); - + preconditions.add( + predicate(notEqual(integer(associativityGroup.getPrecedence()), var("l")))); + if (!associativityGroup.getAssocMap().isEmpty()) - for (Map.Entry entry : associativityGroup.getAssocMap().entrySet()) - if (precedence != entry.getKey() && !(climbing && entry.getKey() == associativityGroup.getPrecedence())) + for (Map.Entry entry : associativityGroup.getAssocMap() + .entrySet()) + if (precedence != entry.getKey() && + !(climbing && entry.getKey() == associativityGroup.getPrecedence())) preconditions.add(predicate(notEqual(integer(entry.getKey()), var("l")))); } break; case NON_ASSOC: if (!climbing) - preconditions.add(predicate(notEqual(integer(associativityGroup.getPrecedence()), var("r")))); + preconditions.add( + predicate(notEqual(integer(associativityGroup.getPrecedence()), var("r")))); if (!climbing) - preconditions.add(predicate(notEqual(integer(associativityGroup.getPrecedence()), var("l")))); - + preconditions.add( + predicate(notEqual(integer(associativityGroup.getPrecedence()), var("l")))); + if (!associativityGroup.getAssocMap().isEmpty()) { - for (Map.Entry entry : associativityGroup.getAssocMap().entrySet()) { - if (precedence != entry.getKey() && !(climbing && entry.getKey() == associativityGroup.getPrecedence())) { + for (Map.Entry entry : associativityGroup.getAssocMap() + .entrySet()) { + if (precedence != entry.getKey() && + !(climbing && entry.getKey() == associativityGroup.getPrecedence())) { preconditions.add(predicate(notEqual(integer(entry.getKey()), var("r")))); preconditions.add(predicate(notEqual(integer(entry.getKey()), var("l")))); } } } break; - default: throw new RuntimeException("Unexpected associativity: " + associativityGroup.getAssociativity()); + default: + throw new RuntimeException( + "Unexpected associativity: " + associativityGroup.getAssociativity()); } if (precedence != associativityGroup.getPrecedence()) { @@ -1219,7 +1269,7 @@ private void precedence2() { // Priority and associativity @SuppressWarnings("unused") boolean canBeBinary = ((rule.isLeftRecursive() || rule.isILeftRecursive()) && rule.isIRightRecursive()) - || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); + || (rule.isILeftRecursive() && (rule.isRightRecursive() || rule.isIRightRecursive())); boolean canBePrefix = false; boolean canBePostfix = false; @@ -1243,9 +1293,11 @@ private void precedence2() { // Priority and associativity // 1. Expressions for the left and/or right recursive uses if (assoc_group != null) { - - if ((rule.isILeftRecursive() || rule.isIRightRecursive() && assoc_group.getAssociativity() != Associativity.NON_ASSOC)) - throw new RuntimeException("Not yet implemented: indirect recursion inside a left or right associativity group"); + + if ((rule.isILeftRecursive() || + rule.isIRightRecursive() && assoc_group.getAssociativity() != Associativity.NON_ASSOC)) + throw new RuntimeException( + "Not yet implemented: indirect recursion inside a left or right associativity group"); // Local to an associativity group int arity = config.groups.get(prec_level.getLhs()) == null? 1 : config.groups.get(prec_level.getLhs()); @@ -1304,12 +1356,15 @@ private void precedence2() { // Priority and associativity if (rule.isRightRecursive()) { if (prec_level.hasPrefixUnaryBelow()) { if (larity == 2) - ret = tuple(minimum(prec_level.getLhs(), rprec), integer(0)); // as unconstrained left end + // as unconstrained left end + ret = tuple(minimum(prec_level.getLhs(), rprec), integer(0)); else { if (this.larity == 2) - ret = tuple(minimum(undefined != -1? undefined : prec, rprec), integer(0)); // as unconstrained left end + // as unconstrained left end + ret = tuple(minimum(undefined != -1? undefined : prec, rprec), integer(0)); else - ret = minimum(undefined != -1? undefined : prec, rprec); // as unconstrained left end + // as unconstrained left end + ret = minimum(undefined != -1? undefined : prec, rprec); } } else { if (larity == 2) @@ -1342,8 +1397,10 @@ private void precedence2() { // Priority and associativity lcond = or(negative, and(notEqual(lprec, integer(prec)), greaterEq(lprec, integer(prec_level.getLhs())))); if (parity == 2) - rarg = tuple(integer(prec_level.getRhs()), - integer(assoc_group.getPrecedence() != -1? assoc_group.getPrecedence() : prec)); // as constrained right end + rarg = tuple(integer(prec_level.getRhs()), + // as constrained right end + integer(assoc_group.getPrecedence() != -1 ? + assoc_group.getPrecedence() : prec)); if (prec_level.hasPrefixUnaryBelow()) { if (larity == 2) @@ -1451,7 +1508,8 @@ private void precedence2() { // Priority and associativity rarg = tuple(integer(prec_level.getRhs()), integer(0)); // as right end is unconstrained else { if (this.parity == 2) - rarg = tuple(integer(undefined != -1? undefined : prec), integer(0)); // as right end is unconstrained + // as right end is unconstrained + rarg = tuple(integer(undefined != -1? undefined : prec), integer(0)); else rarg = integer(undefined != -1? undefined : prec); // as right end is unconstrained } @@ -1460,7 +1518,8 @@ private void precedence2() { // Priority and associativity if (prec_level.hasPrefixUnaryBelow()) { if (larity == 2) - ret = tuple(minimum(prec_level.getLhs(), rprec), integer(prec)); // as constrained left end + // as constrained left end + ret = tuple(minimum(prec_level.getLhs(), rprec), integer(prec)); else { if (this.larity == 2) ret = tuple(minimum(prec, rprec), integer(0)); // as constrained left end @@ -1503,8 +1562,9 @@ private void precedence2() { // Priority and associativity rcond = and(greaterEq(integer(prec_level.getRhs()), pprec), not(equal(parity == 2? passoc : pprec, integer(prec)))); - - int newprec = assoc_group.getPrecedence() != -1? assoc_group.getPrecedence() : prec; + + int newprec = + assoc_group.getPrecedence() != -1 ? assoc_group.getPrecedence() : prec; if (prec_level.hasPrefixUnaryBelow()) { if (larity == 2) ret = tuple(minimum(prec_level.getLhs(), rprec), integer(newprec)); @@ -1529,10 +1589,12 @@ private void precedence2() { // Priority and associativity if (larity == 2) { lcond = and(or(negative, greaterEq(lprec, integer(prec_level.getLhs()))), - or(and(lessEq(lassoc, integer(0)), notEqual(lassoc, neg(integer(prec)))), + or(and(lessEq(lassoc, integer(0)), + notEqual(lassoc, neg(integer(prec)))), and(greater(lassoc, integer(0)), not(and(greaterEq(integer(assoc_group.getRhs()), lassoc), - greaterEq(lassoc, integer(assoc_group.getLhs()))))))); + greaterEq(lassoc, + integer(assoc_group.getLhs()))))))); ret = tuple(integer(0), neg(integer(prec))); } else { @@ -1556,8 +1618,9 @@ private void precedence2() { // Priority and associativity } rcond = not(equal(parity == 2? passoc : pprec, integer(prec))); - - int newprec = assoc_group.getPrecedence() != -1? assoc_group.getPrecedence() : prec; + + int newprec = + assoc_group.getPrecedence() != -1 ? assoc_group.getPrecedence() : prec; if (prec_level.hasPrefixUnaryBelow()) { if (larity == 2) ret = tuple(minimum(prec_level.getLhs(), rprec), integer(newprec)); @@ -1592,7 +1655,8 @@ private void precedence2() { // Priority and associativity } break; - case NON_ASSOC: // restricts both ends (in contrast to other associativity groups applies regardless ends) + // restricts both ends (in contrast to other associativity groups applies regardless ends) + case NON_ASSOC: if (larity == 1 && parity == 1 && !config.hasPrefix(prec_level.getLhs()) && !config.hasPostfix(prec_level.getLhs())) { @@ -1629,19 +1693,25 @@ private void precedence2() { // Priority and associativity and(greater(lassoc, integer(0)), or(equal(lassoc, integer(prec)), not(and(greaterEq(integer(assoc_group.getRhs()), lassoc), - greaterEq(lassoc, integer(assoc_group.getLhs()))))))), + greaterEq(lassoc, integer(assoc_group.getLhs()))))))), or(negative, greaterEq(lprec, integer(prec_level.getLhs())))); else lcond = and(or(and(lessEq(larity == 2? lassoc : lprec, integer(0)), assoc_group.getLhs() == assoc_group.getRhs()? - notEqual(larity == 2? lassoc : lprec, neg(integer(assoc_group.getLhs()))) - : not(and(greaterEq(neg(integer(assoc_group.getLhs())), larity == 2? lassoc : lprec), - greaterEq(larity == 2? lassoc : lprec, neg(integer(assoc_group.getRhs())))))), + notEqual(larity == 2? lassoc : lprec, + neg(integer(assoc_group.getLhs()))) + : not(and(greaterEq(neg(integer(assoc_group.getLhs())), + larity == 2? lassoc : lprec), + greaterEq(larity == 2? lassoc : lprec, + neg(integer(assoc_group.getRhs())))))), and(greater(larity == 2? lassoc : lprec, integer(0)), assoc_group.getLhs() == assoc_group.getRhs()? - notEqual(larity == 2? lassoc : lprec, integer(assoc_group.getLhs())) - : not(and(greaterEq(integer(assoc_group.getRhs()), larity == 2? lassoc : lprec), - greaterEq(larity == 2? lassoc : lprec, integer(assoc_group.getLhs())))))), + notEqual(larity == 2? lassoc : lprec, + integer(assoc_group.getLhs())) + : not(and(greaterEq(integer(assoc_group.getRhs()), + larity == 2? lassoc : lprec), + greaterEq(larity == 2? lassoc : lprec, + integer(assoc_group.getLhs())))))), or(negative, greaterEq(lprec, integer(prec_level.getLhs())))); if (rule.isILeftRecursive() && canBePrefix) @@ -1656,18 +1726,23 @@ private void precedence2() { // Priority and associativity greaterEq(integer(prec_level.getRhs()), pprec)); else rcond = and(assoc_group.getLhs() == assoc_group.getRhs()? - notEqual(parity == 2? passoc : pprec, integer(assoc_group.getLhs())) - : not(and(greaterEq(integer(assoc_group.getRhs()), parity == 2? passoc : pprec), - greaterEq(parity == 2? passoc : pprec, integer(assoc_group.getLhs())))), - greaterEq(integer(prec_level.getRhs()), pprec)); + notEqual(parity == 2? passoc : pprec, integer(assoc_group.getLhs())) + : not(and(greaterEq(integer(assoc_group.getRhs()), + parity == 2? passoc : pprec), + greaterEq(parity == 2? passoc : pprec, + integer(assoc_group.getLhs())))), + greaterEq(integer(prec_level.getRhs()), pprec)); } if (rule.isILeftRecursive() && canBePrefix) { rcond = ifThenElse(equal(var("l"), undef()), assoc_group.getLhs() == assoc_group.getRhs()? - notEqual(parity == 2? passoc : pprec, integer(assoc_group.getLhs())) - : not(and(greaterEq(integer(assoc_group.getRhs()), parity == 2? passoc : pprec), - greaterEq(parity == 2? passoc : pprec, integer(assoc_group.getLhs())))), + notEqual(parity == 2? passoc : pprec, + integer(assoc_group.getLhs())) + : not(and(greaterEq(integer(assoc_group.getRhs()), + parity == 2? passoc : pprec), + greaterEq(parity == 2? passoc : pprec, + integer(assoc_group.getLhs())))), rcond); // TODO: should become post-condition } @@ -1706,15 +1781,19 @@ private void precedence2() { // Priority and associativity if (rule.isIRightRecursive() && canBePostfix) { if (rule.isLeftRecursive()) ret = ifThenElse(equal(var("r"), undef()), - larity == 2? tuple(integer(0), neg(integer(prec))) - : (this.larity == 2? tuple(neg(integer(prec)), integer(0)) : neg(integer(prec))), + larity == 2 ? tuple(integer(0), neg(integer(prec))) + : (this.larity == 2 ? tuple(neg(integer(prec)), integer(0)) + : neg(integer(prec))), ret); else if (rule.isILeftRecursive()) ret = ifThenElse(equal(var("r"), undef()), ifThenElse(equal(var("l"), undef()), - larity == 2? tuple(integer(0), integer(0)) : integer(0), - larity == 2? tuple(integer(0), neg(integer(prec))) - : (this.larity == 2? tuple(neg(integer(prec)), integer(0)) : neg(integer(prec)))), + larity == 2 ? tuple(integer(0), integer(0)) + : integer(0), + larity == 2 ? tuple(integer(0), neg(integer(prec))) + : (this.larity == 2 ? + tuple(neg(integer(prec)), integer(0)) : + neg(integer(prec)))), ret); else throw new RuntimeException("Shouldn't have happened!"); @@ -1733,7 +1812,8 @@ else if (rule.isILeftRecursive()) rcond = assoc_group.getLhs() == assoc_group.getRhs()? notEqual(parity == 2? passoc : pprec, integer(assoc_group.getLhs())) : not(and(greaterEq(integer(assoc_group.getRhs()), parity == 2? passoc : pprec), - greaterEq(parity == 2? passoc : pprec, integer(assoc_group.getLhs())))); + greaterEq(parity == 2? passoc : pprec, + integer(assoc_group.getLhs())))); // Normal postfix if (rule.isLeftRecursive() && !(rule.isRightRecursive() || rule.isIRightRecursive())) { @@ -1764,7 +1844,8 @@ else if (rule.isILeftRecursive()) if (rule.isILeftRecursive() && canBePrefix) { lcond = or(equal(var("l"), undef()), lcond); - rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); // TODO: should become post-condition + // TODO: should become post-condition + rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); } } @@ -1782,7 +1863,8 @@ else if (rule.isILeftRecursive()) ret = minimum(prec, rprec); if (rule.isIRightRecursive() && canBePostfix) - ret = ifThenElse(equal(var("r"), undef()), this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); + ret = ifThenElse(equal(var("r"), undef()), + this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); } else { // In this case, r-variable is not used if (this.larity == 2) @@ -1806,7 +1888,8 @@ else if (rule.isILeftRecursive()) if (rule.isILeftRecursive() && canBePrefix) { lcond = or(equal(var("l"), undef()), lcond); - rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); // TODO: should become post-condition + // TODO: should become post-condition + rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); } } @@ -1824,7 +1907,8 @@ else if (rule.isILeftRecursive()) ret = minimum(prec, rprec); if (rule.isIRightRecursive() && canBePostfix) - ret = ifThenElse(equal(var("r"), undef()), this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); + ret = ifThenElse(equal(var("r"), undef()), + this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); } else { if (this.larity == 2) ret = tuple(integer(prec), integer(0)); @@ -1907,7 +1991,8 @@ else if (rule.isILeftRecursive()) if (rule.isILeftRecursive() && canBePrefix) { lcond = or(equal(var("l"), undef()), lcond); - rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); // TODO: should become post-condition + // TODO: should become post-condition + rcond = ifThenElse(equal(var("l"), undef()), TRUE, rcond); } } @@ -1925,7 +2010,8 @@ else if (rule.isILeftRecursive()) ret = minimum(prec, rprec); if (rule.isIRightRecursive() && canBePostfix) - ret = ifThenElse(equal(var("r"), undef()), this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); + ret = ifThenElse(equal(var("r"), undef()), + this.larity == 2? tuple(integer(0), integer(0)) : integer(0), ret); } else { if (this.larity == 2) @@ -1948,7 +2034,8 @@ else if (rule.isILeftRecursive()) if (assoc_group == null && prec_level.getLhs() != prec_level.getRhs()) { if (rule.isILeftRecursive() || rule.isIRightRecursive()) { - System.out.println("Warning: not yet implemented: indirect recursion inside a group of the same precedence with multiple rules: " + rule); + System.out.println("Warning: not yet implemented: indirect recursion inside a group of the same " + + "precedence with multiple rules: " + rule); } // Local to an associativity group @@ -2132,7 +2219,8 @@ private static Expression pr(int current, Integer[] indices, boolean prefix) { List list = Arrays.asList(indices); Collections.reverse(list); - return pr2(var("l"), integer(current), list.stream().map(i -> integer(i + 1)).toArray(Expression[]::new)); + return pr2(var("l"), integer(current), + list.stream().map(i -> integer(i + 1)).toArray(Expression[]::new)); } else { if (indices.length == 0) @@ -2144,7 +2232,8 @@ private static Expression pr(int current, Integer[] indices, boolean prefix) { List list = Arrays.asList(indices); Collections.reverse(list); - return pr2(var("r"), integer(current), list.stream().map(i -> integer(i + 1)).toArray(Expression[]::new)); + return pr2(var("r"), integer(current), + list.stream().map(i -> integer(i + 1)).toArray(Expression[]::new)); } } @@ -2170,7 +2259,8 @@ public RuntimeRule transform() { switch(config_op) { case _1: if (isLeftOrRightRecursiveNonterminal && isHeadWithLabeledRules) - builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters("l", "r", "_not").build()); + builder = rule.copyBuilderButWithHead( + rule.getHead().copy().addParameters("l", "r", "_not").build()); else if (isLeftOrRightRecursiveNonterminal) builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters("l", "r").build()); else if (isHeadWithLabeledRules) @@ -2238,7 +2328,8 @@ else if (isHeadWithLabeledRules) } if (isHeadWithLabeledRules) - builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters(params).addParameters("_not").build()); + builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters(params) + .addParameters("_not").build()); else builder = rule.copyBuilderButWithHead(rule.getHead().copy().addParameters(params).build()); } @@ -2272,7 +2363,8 @@ else if (isHeadWithLabeledRules) postconditions.add(DataDependentCondition.predicate(xlcond)); if (!preconditions.isEmpty() && !postconditions.isEmpty()) - symbols.add(sym.copy().addPreConditions(preconditions).addPostConditions(postconditions).build()); + symbols.add(sym.copy().addPreConditions(preconditions).addPostConditions(postconditions) + .build()); else if (!postconditions.isEmpty()) symbols.add(sym.copy().addPostConditions(postconditions).build()); else if (!preconditions.isEmpty()) @@ -2381,8 +2473,9 @@ public Symbol visit(Code symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - - return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override @@ -2395,8 +2488,9 @@ public Symbol visit(Conditional symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - - return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions( + symbol).build(); } @Override @@ -2404,8 +2498,9 @@ public Symbol visit(IfThen symbol) { Symbol sym = symbol.getThenPart().accept(this); if (sym == symbol.getThenPart()) return symbol; - - return new IfThen.Builder(symbol.getExpression(), sym).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new IfThen.Builder(symbol.getExpression(), sym).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override @@ -2415,8 +2510,9 @@ public Symbol visit(IfThenElse symbol) { if (thenPart == symbol.getThenPart() && elsePart == symbol.getElsePart()) return symbol; - - return new IfThenElse.Builder(symbol.getExpression(), thenPart, elsePart).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new IfThenElse.Builder(symbol.getExpression(), thenPart, elsePart).setLabel(symbol.getLabel()) + .addConditions(symbol).build(); } @Override @@ -2429,11 +2525,12 @@ public Symbol visit(Ignore symbol) { @Override public Symbol visit(Nonterminal symbol) { - - boolean isUseOfLeftOrRight = leftOrRightRecursiveNonterminals.contains(symbol.getName()); // recursive symbol with precedence, i.e., it has parameters and needs arguments + // recursive symbol with precedence, i.e., it has parameters and needs arguments + boolean isUseOfLeftOrRight = leftOrRightRecursiveNonterminals.contains(symbol.getName()); Configuration config = configs.get(symbol.getName()); - boolean isUseOfLeftOrRightEnd = false; // // symbol that introduces indirection, i.e., it has parameters and needs arguments + // symbol that introduces indirection, i.e., it has parameters and needs arguments + boolean isUseOfLeftOrRightEnd = false; List pends = new ArrayList<>(); @@ -2449,10 +2546,12 @@ public Symbol visit(Nonterminal symbol) { Map labels = headsWithLabeledRules.get(symbol.getName()); if (!isUseOfLeftOrRight && labels == null && !isUseOfLeftOrRightEnd) return symbol; - - boolean isRecursiveUseOfLeftOrRight = isUseOfLeftOrRight && symbol.getName().equals(rule.getHead().getName()); - - boolean isIndirectRecursiveUseOfLeftOrRight = isUseOfLeftOrRightEnd && pends.contains(rule.getHead().getName()); + + boolean isRecursiveUseOfLeftOrRight = isUseOfLeftOrRight && symbol.getName().equals( + rule.getHead().getName()); + + boolean isIndirectRecursiveUseOfLeftOrRight = isUseOfLeftOrRightEnd && pends.contains( + rule.getHead().getName()); Expression _not = null; Expression[] arguments = null; @@ -2500,7 +2599,8 @@ else if (arguments != null) int n = 0; for (Map.Entry entry : c.right_rec_rules.entrySet()) { - if (rule.getPrecedence() != -1 && rule.getPrecedence() > entry.getValue().getPrecedenceLevel().getRhs()) { + if (rule.getPrecedence() != -1 && + rule.getPrecedence() > entry.getValue().getPrecedenceLevel().getRhs()) { n = 1 << labels.get(entry.getKey()); } } @@ -2530,7 +2630,8 @@ else if (arguments != null) int parity = config.parity; if (config.leftEnds.contains(rule.getHead().getName()) - || config.rightEnds.contains(rule.getHead().getName())) { // TODO: if precedence also applies to X, use larg and rarg + // TODO: if precedence also applies to X, use larg and rarg + || config.rightEnds.contains(rule.getHead().getName())) { List ends = configs.get(rule.getHead().getName()).pends; @@ -2555,8 +2656,10 @@ else if (arguments != null) } else if (canBeFromRight) { variable = "r"; arguments = new Expression[] { var("p" + i) }; - boolean hasPrefixBelow = config.rightEndsPrefixBelow.contains(rule.getHead().getName()); - boolean canBecomePostfix = config.rightEndsThatCanLeadToPostfix.contains(rule.getHead().getName()); + boolean hasPrefixBelow = config.rightEndsPrefixBelow.contains( + rule.getHead().getName()); + boolean canBecomePostfix = config.rightEndsThatCanLeadToPostfix.contains( + rule.getHead().getName()); if (hasPrefixBelow || canBecomePostfix) rret[i] = var("r"); else @@ -2578,9 +2681,11 @@ else if (canBeFromLeft) arguments = new Expression[] { get(var("p" + i), 1) }; else if (canBeFromRight) { arguments = new Expression[] { var("p" + i) }; - - boolean hasPrefixBelow = config.rightEndsPrefixBelow.contains(rule.getHead().getName()); - boolean canBecomePostfix = config.rightEndsThatCanLeadToPostfix.contains(rule.getHead().getName()); + + boolean hasPrefixBelow = config.rightEndsPrefixBelow.contains( + rule.getHead().getName()); + boolean canBecomePostfix = config.rightEndsThatCanLeadToPostfix.contains( + rule.getHead().getName()); if (hasPrefixBelow || canBecomePostfix) rret[i] = var("r"); @@ -2588,10 +2693,10 @@ else if (canBeFromRight) { variable = ""; } } else - arguments = new Expression[] { parity == 2? tuple(integer(0), integer(0)) : integer(0) }; + arguments = new Expression[]{parity == 2 ? tuple(integer(0), integer(0)) : integer(0)}; } else - arguments = new Expression[] { parity == 2? tuple(integer(0), integer(0)) : integer(0) }; + arguments = new Expression[]{parity == 2 ? tuple(integer(0), integer(0)) : integer(0)}; } if (isUseOfLeftOrRightEnd) { // . ::= alpha X alpha @@ -2633,11 +2738,14 @@ else if (canBeFromRight) { Statement binding = null; Statement lbinding = null; Statement rbinding = null; - - if (isIndirectRecursiveUseOfLeftOrRight) { // TODO: if precedence also applies to X, propagate argument from E - - boolean canReachLeft = configs.get(rule.getHead().getName()).leftEnds.contains(symbol.getName()); - boolean canReachRight = configs.get(rule.getHead().getName()).rightEnds.contains(symbol.getName()); + + // TODO: if precedence also applies to X, propagate argument from E + if (isIndirectRecursiveUseOfLeftOrRight) { + + boolean canReachLeft = configs.get(rule.getHead().getName()).leftEnds.contains( + symbol.getName()); + boolean canReachRight = configs.get(rule.getHead().getName()).rightEnds.contains( + symbol.getName()); if (isFirst && isLast) { // E ::= X if (pends.size() == 1) { @@ -2650,8 +2758,11 @@ else if (canBeFromRight) { variable = "l"; arguments = new Expression[] { larg }; } else { - boolean prefixBelow = configs.get(rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + boolean prefixBelow = configs.get( + rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); + boolean canBecomePostfix = configs.get( + rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains( + symbol.getName()); if (prefixBelow || canBecomePostfix) variable = "r"; else @@ -2669,8 +2780,11 @@ else if (canBeFromRight) { binding = varDeclStat("l", get(var(variable), i)); arguments[i] = larg; } else { - boolean prefixBelow = configs.get(rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + boolean prefixBelow = configs.get( + rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); + boolean canBecomePostfix = configs.get( + rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains( + symbol.getName()); if (prefixBelow || canBecomePostfix) binding = varDeclStat("r", get(var(variable), i)); else @@ -2683,7 +2797,8 @@ else if (canBeFromRight) { variable = "l" + symbol.getName().toLowerCase(); if (canReachLeft && canReachRight) { binding = varDeclStat("l", get(var(variable), 0)); - arguments = new Expression[] { tuple(larg, config.parity == 2? tuple(integer(0), integer(0)) : integer(0)) }; + arguments = new Expression[]{ tuple(larg, + config.parity == 2 ? tuple(integer(0), integer(0)) : integer(0)) }; } else { variable = "l"; arguments = new Expression[] { larg }; @@ -2693,7 +2808,8 @@ else if (canBeFromRight) { variable = "l" + symbol.getName().toLowerCase(); if (canReachLeft && canReachRight) { binding = varDeclStat("l", get(get(var(variable), i), 0)); - arguments[i] = tuple(larg, config.parity == 2? tuple(integer(0), integer(0)) : integer(0)); + arguments[i] = tuple(larg, + config.parity == 2 ? tuple(integer(0), integer(0)) : integer(0)); } else { binding = varDeclStat("l", get(var(variable), i)); arguments[i] = larg; @@ -2703,15 +2819,18 @@ else if (canBeFromRight) { if (pends.size() == 1) { variable = "r" + symbol.getName().toLowerCase(); - boolean prefixBelow = configs.get(rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + boolean prefixBelow = configs.get( + rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); + boolean canBecomePostfix = configs.get( + rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); if (canReachLeft && canReachRight) { if (prefixBelow || canBecomePostfix) binding = varDeclStat("r", get(var(variable), 1)); else variable = ""; - arguments = new Expression[] { tuple(config.parity == 2? tuple(integer(0), integer(0)) : integer(0), rarg) }; + arguments = new Expression[]{tuple( + config.parity == 2 ? tuple(integer(0), integer(0)) : integer(0), rarg)}; } else { if (prefixBelow || canBecomePostfix) variable = "r"; @@ -2722,15 +2841,18 @@ else if (canBeFromRight) { } else { int i = config.pends.indexOf(rule.getHead().getName()); variable = "r" + symbol.getName(); - boolean prefixBelow = configs.get(rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + boolean prefixBelow = configs.get( + rule.getHead().getName()).rightEndsPrefixBelow.contains(symbol.getName()); + boolean canBecomePostfix = configs.get( + rule.getHead().getName()).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); if (canReachLeft && canReachRight) { if (prefixBelow || canBecomePostfix) binding = varDeclStat("r", get(get(var(variable), i), 1)); else variable = ""; - arguments[i] = tuple(config.parity == 2? tuple(integer(0), integer(0)) : integer(0), rarg); + arguments[i] = tuple( + config.parity == 2 ? tuple(integer(0), integer(0)) : integer(0), rarg); } else { if (prefixBelow || canBecomePostfix) binding = varDeclStat("r", get(var(variable), i)); @@ -2740,8 +2862,8 @@ else if (canBeFromRight) { } } } - - } else if (isUseOfLeftOrRightEnd) { // TODO: if precedence also applies to X, use larg and rarg to propagate down + // TODO: if precedence also applies to X, use larg and rarg to propagate down + } else if (isUseOfLeftOrRightEnd) { if (isFirst && isLast) { // X ::= Y List ends = config.pends; for (String end : ends) { @@ -2759,24 +2881,32 @@ else if (canBeFromRight) { arguments[i] = var("p" + i); if (canBeFromLeft && canBeFromRight) { - lret[config.pends.indexOf(end)] = ends.size() == 1? get(var(variable), 0) : get(get(var(variable), i), 0); - - boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + lret[config.pends.indexOf(end)] = ends.size() == 1 ? get(var(variable), + 0) : get(get(var(variable), i), 0); + + boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains( + symbol.getName()); + boolean canBecomePostfix = configs.get( + end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); if (hasPrefixBelow || canBecomePostfix) - rret[config.pends.indexOf(end)] = ends.size() == 1? get(var(variable), 1) : get(get(var(variable), i), 1); + rret[config.pends.indexOf(end)] = ends.size() == 1 ? get(var(variable), + 1) : get(get(var(variable), i), 1); } else if (canBeFromLeft) { variable = "l"; - lret[config.pends.indexOf(end)] = ends.size() == 1? var(variable) : get(var(variable), i); + lret[config.pends.indexOf(end)] = ends.size() == 1 ? var(variable) : get( + var(variable), i); } else { variable = "r"; - boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains( + symbol.getName()); + boolean canBecomePostfix = configs.get( + end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); if (hasPrefixBelow || canBecomePostfix) - rret[config.pends.indexOf(end)] = ends.size() == 1? var(variable) : get(var(variable), i); + rret[config.pends.indexOf(end)] = ends.size() == 1 ? var(variable) : get( + var(variable), i); else variable = ""; } @@ -2793,14 +2923,18 @@ else if (canBeFromRight) { int i = ends.indexOf(end); // Note: shouldn't look up the left and right ends of the head - boolean canBeFromLeft = configs.get(end).leftEnds.contains(rule.getHead().getName()); - boolean canBeFromRight = configs.get(end).rightEnds.contains(rule.getHead().getName()); + boolean canBeFromLeft = configs.get(end).leftEnds.contains( + rule.getHead().getName()); + boolean canBeFromRight = configs.get(end).rightEnds.contains( + rule.getHead().getName()); variable = "l"; if (canBeFromLeft && canBeFromRight) { - arguments[i] = tuple(get(var("p" + i), 0), parity == 2? tuple(integer(0), integer(0)) : integer(0)); - lret[config.pends.indexOf(end)] = ends.size() == 1? get(var("l"), 0) : get(get(var("l"), i), 0); + arguments[i] = tuple(get(var("p" + i), 0), + parity == 2 ? tuple(integer(0), integer(0)) : integer(0)); + lret[config.pends.indexOf(end)] = ends.size() == 1 ? get(var("l"), 0) : get( + get(var("l"), i), 0); } else if (canBeFromLeft) { arguments[i] = var("p" + i); lret[config.pends.indexOf(end)] = ends.size() == 1? var("l") : get(var("l"), i); @@ -2821,30 +2955,39 @@ else if (canBeFromRight) { int i = ends.indexOf(end); // Note: shouldn't look up the left and right ends of the head - boolean canBeFromLeft = configs.get(end).leftEnds.contains(rule.getHead().getName()); - boolean canBeFromRight = configs.get(end).rightEnds.contains(rule.getHead().getName()); + boolean canBeFromLeft = configs.get(end).leftEnds.contains( + rule.getHead().getName()); + boolean canBeFromRight = configs.get(end).rightEnds.contains( + rule.getHead().getName()); variable = "r"; if (canBeFromLeft && canBeFromRight) { - arguments[i] = tuple(parity == 2? tuple(integer(0), integer(0)) : integer(0), get(var("p" + i), 1)); - - boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); - + arguments[i] = tuple(parity == 2 ? tuple(integer(0), integer(0)) : integer(0), + get(var("p" + i), 1)); + + boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains( + symbol.getName()); + boolean canBecomePostfix = configs.get( + end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + if (hasPrefixBelow || canBecomePostfix) - rret[config.pends.indexOf(end)] = ends.size() == 1? get(var("r"), 1) : get(get(var("r"), i), 1); + rret[config.pends.indexOf(end)] = ends.size() == 1 ? get(var("r"), 1) : get( + get(var("r"), i), 1); else variable = ""; } else if (canBeFromRight) { arguments[i] = var("p" + i); - - boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains(symbol.getName()); - boolean canBecomePostfix = configs.get(end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); + + boolean hasPrefixBelow = configs.get(end).rightEndsPrefixBelow.contains( + symbol.getName()); + boolean canBecomePostfix = configs.get( + end).rightEndsThatCanLeadToPostfix.contains(symbol.getName()); if (hasPrefixBelow || canBecomePostfix) - rret[config.pends.indexOf(end)] = ends.size() == 1? var("r") : get(var("r"), i); + rret[config.pends.indexOf(end)] = ends.size() == 1 ? var("r") : get( + var("r"), i); else variable = ""; } else if (canBeFromLeft) { @@ -2883,7 +3026,8 @@ else if (canBeFromRight) { if (arguments != null && _not != null) newone = variable.isEmpty()? symbol.copy().apply(arguments).apply(_not).build() - : symbol.copy().apply(arguments).apply(_not).setVariable(variable).build(); + : symbol.copy().apply(arguments).apply(_not).setVariable(variable) + .build(); else if (arguments != null) { newone = variable.isEmpty()? symbol.copy().apply(arguments).build() : symbol.copy().apply(arguments).setVariable(variable).build(); @@ -2919,8 +3063,9 @@ public Symbol visit(While symbol) { Symbol body = symbol.getBody().accept(this); if (body == symbol.getBody()) return symbol; - - return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override diff --git a/src/org/iguana/grammar/transformation/DesugarStartSymbol.java b/src/org/iguana/grammar/transformation/DesugarStartSymbol.java index f16bb7379..91f668e35 100644 --- a/src/org/iguana/grammar/transformation/DesugarStartSymbol.java +++ b/src/org/iguana/grammar/transformation/DesugarStartSymbol.java @@ -24,7 +24,8 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { RuntimeGrammar.Builder builder = new RuntimeGrammar.Builder(grammar); for (Start start : starts) { - Nonterminal startNonterminal = new Nonterminal.Builder(start.getName()).setNodeType(NonterminalNodeType.Start).build(); + Nonterminal startNonterminal = new Nonterminal.Builder(start.getName()).setNodeType( + NonterminalNodeType.Start).build(); RuntimeRule startRule = RuntimeRule.withHead(startNonterminal) // TODO: For now we use the label top, but would be good to allow configuring it. diff --git a/src/org/iguana/grammar/transformation/DesugarState.java b/src/org/iguana/grammar/transformation/DesugarState.java index 6659e2c22..8e417ad2b 100644 --- a/src/org/iguana/grammar/transformation/DesugarState.java +++ b/src/org/iguana/grammar/transformation/DesugarState.java @@ -147,7 +147,8 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { int i = 0; List>> nonterminal_bindings = bindings.get(nonterminal); for (RuntimeRule rule : grammar.getAlternatives(nonterminal)) { - newRules.add(transform(rule, uses, nonterminal_bindings == null? new HashMap<>() : nonterminal_bindings.get(i++), returns)); + newRules.add(transform(rule, uses, + nonterminal_bindings == null ? new HashMap<>() : nonterminal_bindings.get(i++), returns)); } } return RuntimeGrammar.builder().addRules(newRules).setLayout(grammar.getLayout()) @@ -158,8 +159,13 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { .setRegularExpressionDefinitions(grammar.getRegularExpressionDefinitions()) .build(); } - - private RuntimeRule transform(RuntimeRule rule, Map> uses, Map> bindings, Map> returns) { + + private RuntimeRule transform( + RuntimeRule rule, + Map> uses, + Map> bindings, + Map> returns + ) { if (rule.getBody() == null) return rule; @@ -224,7 +230,12 @@ public static class DesugarStateVisitor implements ISymbolVisitor { private final Map> bindings; private final RuntimeGrammar grammar; - DesugarStateVisitor(Map> uses, Map> returns, Map> bindings, RuntimeGrammar grammar) { + DesugarStateVisitor( + Map> uses, + Map> returns, + Map> bindings, + RuntimeGrammar grammar + ) { this.uses = uses; this.returns = returns; this.bindings = bindings; @@ -249,8 +260,9 @@ public Symbol visit(Code symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - - return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override @@ -263,7 +275,8 @@ public Symbol visit(Conditional symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions( + symbol).build(); } @Override diff --git a/src/org/iguana/grammar/transformation/EBNFToBNF.java b/src/org/iguana/grammar/transformation/EBNFToBNF.java index ddd9bfb04..1cf55d8b7 100644 --- a/src/org/iguana/grammar/transformation/EBNFToBNF.java +++ b/src/org/iguana/grammar/transformation/EBNFToBNF.java @@ -86,8 +86,9 @@ public RuntimeRule rewrite(RuntimeRule rule, Set newRules) { Set state = new HashSet<>(); new FreeVariableVisitor(state).compute(rule); - - EBNFVisitor ebnf_visitor = new EBNFVisitor(state, newRules, rule.getLayout(), rule.getLayoutStrategy(), ebnfLefts, ebnfRights); + + EBNFVisitor ebnf_visitor = new EBNFVisitor(state, newRules, rule.getLayout(), rule.getLayoutStrategy(), + ebnfLefts, ebnfRights); for (Symbol s : rule.getBody()) builder.addSymbol(s.accept(ebnf_visitor)); @@ -174,15 +175,18 @@ public Symbol visit(Alt symbol) { parameters = freeVars.toArray(new String[0]); arguments = freeVars.stream().map(v -> AST.var(v)).toArray(Expression[]::new); } - - Nonterminal newNt = parameters == null? new Nonterminal.Builder(symbol.getName()).setNodeType(NonterminalNodeType.Alt).build() - : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType(NonterminalNodeType.Alt).build(); - - symbols.forEach(x -> addedRules.add(RuntimeRule.withHead(newNt).addSymbol(x).setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setDefinition(symbol) - .build())); + + Nonterminal newNt = parameters == null ? new Nonterminal.Builder(symbol.getName()).setNodeType( + NonterminalNodeType.Alt).build() + : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType( + NonterminalNodeType.Alt).build(); + + symbols.forEach(x -> addedRules.add(RuntimeRule.withHead(newNt).addSymbol(x).setLayout(layout) + .setLayoutStrategy(strategy) + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setDefinition(symbol) + .build())); Builder copyBuilder = arguments == null? newNt.copy() : newNt.copy().apply(arguments); return copyBuilder.addConditions(symbol).setLabel(symbol.getLabel()).build(); @@ -208,9 +212,11 @@ public Symbol visit(Opt symbol) { parameters = freeVars.toArray(new String[0]); arguments = freeVars.stream().map(v -> AST.var(v)).toArray(Expression[]::new); } - - Nonterminal newNt = parameters == null? new Nonterminal.Builder(symbol.getName()).setNodeType(NonterminalNodeType.Opt).build() - : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType(NonterminalNodeType.Opt).build(); + + Nonterminal newNt = parameters == null ? new Nonterminal.Builder(symbol.getName()).setNodeType( + NonterminalNodeType.Opt).build() + : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType( + NonterminalNodeType.Opt).build(); addedRules.add(RuntimeRule.withHead(newNt).addSymbol(in).setLayout(layout).setLayoutStrategy(strategy) .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) @@ -253,33 +259,38 @@ public Symbol visit(Plus symbol) { parameters = freeVars.toArray(new String[0]); arguments = freeVars.stream().map(v -> AST.var(v)).toArray(Expression[]::new); } - - List seperators = symbol.getSeparators().stream().map(sep -> sep.accept(this)).collect(Collectors.toList()); - Nonterminal newNt = parameters == null? new Nonterminal.Builder(getName(S, symbol.getSeparators(), layout) + "+").setNodeType(NonterminalNodeType.Plus).build() - : new Nonterminal.Builder(getName(S, symbol.getSeparators(), layout) + "+").addParameters(parameters).setNodeType(NonterminalNodeType.Plus).build(); - + List seperators = symbol.getSeparators().stream().map(sep -> sep.accept(this)).collect( + Collectors.toList()); + + Nonterminal newNt = parameters == null ? new Nonterminal.Builder( + getName(S, symbol.getSeparators(), layout) + "+").setNodeType(NonterminalNodeType.Plus).build() + : new Nonterminal.Builder(getName(S, symbol.getSeparators(), layout) + "+").addParameters(parameters) + .setNodeType(NonterminalNodeType.Plus).build(); + addedRules.add(RuntimeRule.withHead(newNt) - .addSymbol(arguments != null? new Nonterminal.Builder(newNt).apply(arguments).build() : newNt) - .addSymbols(seperators) - .addSymbols(S).setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.LEFT_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setLeftEnd(newNt.getName()) - .setRightEnd(S.getName()) - .setLeftEnds(ebnfLefts.containsKey(newNt.getName())? ebnfLefts.get(newNt.getName()) : new HashSet<>()) - .setRightEnds(ebnfRights.containsKey(newNt.getName())? ebnfRights.get(newNt.getName()) : new HashSet<>()) - .setDefinition(symbol) - .build()); + .addSymbol(arguments != null ? new Nonterminal.Builder(newNt).apply(arguments).build() : newNt) + .addSymbols(seperators) + .addSymbols(S).setLayout(layout).setLayoutStrategy(strategy) + .setRecursion(Recursion.LEFT_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setLeftEnd(newNt.getName()) + .setRightEnd(S.getName()) + .setLeftEnds(ebnfLefts.containsKey(newNt.getName()) ? ebnfLefts.get(newNt.getName()) : new HashSet<>()) + .setRightEnds( + ebnfRights.containsKey(newNt.getName()) ? ebnfRights.get(newNt.getName()) : new HashSet<>()) + .setDefinition(symbol) + .build()); addedRules.add(RuntimeRule.withHead(newNt).addSymbol(S) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setLeftEnd(S.getName()) - .setRightEnd(S.getName()) - .setLeftEnds(ebnfLefts.containsKey(newNt.getName())? ebnfLefts.get(newNt.getName()) : new HashSet<>()) - .setRightEnds(ebnfRights.containsKey(newNt.getName())? ebnfRights.get(newNt.getName()) : new HashSet<>()) - .setDefinition(symbol) - .build()); + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setLeftEnd(S.getName()) + .setRightEnd(S.getName()) + .setLeftEnds(ebnfLefts.containsKey(newNt.getName()) ? ebnfLefts.get(newNt.getName()) : new HashSet<>()) + .setRightEnds( + ebnfRights.containsKey(newNt.getName()) ? ebnfRights.get(newNt.getName()) : new HashSet<>()) + .setDefinition(symbol) + .build()); Builder copyBuilder = arguments == null? newNt.copy() : newNt.copy().apply(arguments); return copyBuilder.addConditions(symbol).setLabel(symbol.getLabel()).build(); @@ -303,19 +314,22 @@ public Symbol visit(Group symbol) { parameters = freeVars.toArray(new String[0]); arguments = freeVars.stream().map(v -> AST.var(v)).toArray(Expression[]::new); } - - Nonterminal newNt = parameters == null? new Nonterminal.Builder(symbol.getName()).setNodeType(NonterminalNodeType.Seq).build() - : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType(NonterminalNodeType.Seq).build(); - + + Nonterminal newNt = parameters == null ? new Nonterminal.Builder(symbol.getName()).setNodeType( + NonterminalNodeType.Seq).build() + : new Nonterminal.Builder(symbol.getName()).addParameters(parameters).setNodeType( + NonterminalNodeType.Seq).build(); + addedRules.add(RuntimeRule.withHead(newNt).addSymbols(symbols).setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setLeftEnd(symbols.get(0).getName()) - .setRightEnd(symbols.get(symbols.size() - 1).getName()) - .setLeftEnds(ebnfLefts.containsKey(newNt.getName())? ebnfLefts.get(newNt.getName()) : new HashSet<>()) - .setRightEnds(ebnfRights.containsKey(newNt.getName())? ebnfRights.get(newNt.getName()) : new HashSet<>()) - .setDefinition(symbol) - .build()); + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setLeftEnd(symbols.get(0).getName()) + .setRightEnd(symbols.get(symbols.size() - 1).getName()) + .setLeftEnds(ebnfLefts.containsKey(newNt.getName()) ? ebnfLefts.get(newNt.getName()) : new HashSet<>()) + .setRightEnds( + ebnfRights.containsKey(newNt.getName()) ? ebnfRights.get(newNt.getName()) : new HashSet<>()) + .setDefinition(symbol) + .build()); Builder copyBuilder = arguments == null? newNt.copy() : newNt.copy().apply(arguments); return copyBuilder.addConditions(symbol).setLabel(symbol.getLabel()).build(); @@ -344,26 +358,29 @@ public Symbol visit(Star symbol) { } String base = getName(symbol.getSymbol(), symbol.getSeparators(), layout); - Nonterminal newNt = parameters != null? new Nonterminal.Builder(base + "*").addParameters(parameters).setNodeType(NonterminalNodeType.Star).build() - : new Nonterminal.Builder(base + "*").setNodeType(NonterminalNodeType.Star).build(); - + Nonterminal newNt = parameters != null ? new Nonterminal.Builder(base + "*").addParameters(parameters) + .setNodeType(NonterminalNodeType.Star).build() + : new Nonterminal.Builder(base + "*").setNodeType(NonterminalNodeType.Star).build(); + addedRules.add(RuntimeRule.withHead(newNt).addSymbols(S) - .setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setLeftEnd(S.getName()) - .setRightEnd(S.getName()) - .setLeftEnds(ebnfLefts.containsKey(newNt.getName())? ebnfLefts.get(newNt.getName()): new HashSet<>()) - .setRightEnds(ebnfRights.containsKey(newNt.getName())? ebnfRights.get(newNt.getName()): new HashSet<>()) - .setDefinition(symbol) - .build()); + .setLayout(layout).setLayoutStrategy(strategy) + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setLeftEnd(S.getName()) + .setRightEnd(S.getName()) + .setLeftEnds(ebnfLefts.containsKey(newNt.getName()) ? ebnfLefts.get(newNt.getName()) : new HashSet<>()) + .setRightEnds( + ebnfRights.containsKey(newNt.getName()) ? ebnfRights.get(newNt.getName()) : new HashSet<>()) + .setDefinition(symbol) + .build()); addedRules.add(RuntimeRule.withHead(newNt) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setLeftEnds(ebnfLefts.containsKey(newNt.getName())? ebnfLefts.get(newNt.getName()): new HashSet<>()) - .setRightEnds(ebnfRights.containsKey(newNt.getName())? ebnfRights.get(newNt.getName()): new HashSet<>()) - .setDefinition(symbol) - .build()); + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setLeftEnds(ebnfLefts.containsKey(newNt.getName()) ? ebnfLefts.get(newNt.getName()) : new HashSet<>()) + .setRightEnds( + ebnfRights.containsKey(newNt.getName()) ? ebnfRights.get(newNt.getName()) : new HashSet<>()) + .setDefinition(symbol) + .build()); Builder copyBuilder = arguments == null? newNt.copy() : newNt.copy().apply(arguments); return copyBuilder.addConditions(symbol).setLabel(symbol.getLabel()).build(); @@ -416,13 +433,14 @@ public Symbol visit(IfThen symbol) { } Nonterminal newNt = new Nonterminal.Builder("IF_" + counter++).addParameters(parameters).build(); - - addedRules.add(RuntimeRule.withHead(newNt).addSymbol(thenPart.copy().addPreCondition(DataDependentCondition.predicate(AST.var(id))).build()) - .setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setDefinition(symbol) - .build()); + + addedRules.add(RuntimeRule.withHead(newNt).addSymbol( + thenPart.copy().addPreCondition(DataDependentCondition.predicate(AST.var(id))).build()) + .setLayout(layout).setLayoutStrategy(strategy) + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setDefinition(symbol) + .build()); // FIXME: epsilon rule can have a condition addedRules.add(RuntimeRule.withHead(newNt) @@ -476,20 +494,22 @@ public Symbol visit(IfThenElse symbol) { } Nonterminal newNt = new Nonterminal.Builder("IF_THEN_ELSE_" + counter++).addParameters(parameters).build(); - - addedRules.add(RuntimeRule.withHead(newNt).addSymbol(thenPart.copy().addPreCondition(DataDependentCondition.predicate(AST.var(id))).build()) - .setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setDefinition(symbol) - .build()); - - addedRules.add(RuntimeRule.withHead(newNt).addSymbol(elsePart.copy().addPreCondition(DataDependentCondition.predicate(AST.not(AST.var(id)))).build()) - .setLayout(layout).setLayoutStrategy(strategy) - .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) - .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) - .setDefinition(symbol) - .build()); + + addedRules.add(RuntimeRule.withHead(newNt).addSymbol( + thenPart.copy().addPreCondition(DataDependentCondition.predicate(AST.var(id))).build()) + .setLayout(layout).setLayoutStrategy(strategy) + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setDefinition(symbol) + .build()); + + addedRules.add(RuntimeRule.withHead(newNt).addSymbol( + elsePart.copy().addPreCondition(DataDependentCondition.predicate(AST.not(AST.var(id)))).build()) + .setLayout(layout).setLayoutStrategy(strategy) + .setRecursion(Recursion.NON_REC).setAssociativity(Associativity.UNDEFINED) + .setPrecedence(-1).setPrecedenceLevel(PrecedenceLevel.getFirstAndDone()) + .setDefinition(symbol) + .build()); return newNt.copy().apply(arguments).addConditions(symbol).setLabel(symbol.getLabel()).build(); } @@ -528,8 +548,9 @@ public Symbol visit(Code symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - - return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new Code.Builder(sym, symbol.getStatements()).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override @@ -542,8 +563,9 @@ public Symbol visit(Conditional symbol) { Symbol sym = symbol.getSymbol().accept(this); if (sym == symbol.getSymbol()) return symbol; - - return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new Conditional.Builder(sym, symbol.getExpression()).setLabel(symbol.getLabel()).addConditions( + symbol).build(); } @Override @@ -577,8 +599,9 @@ public Symbol visit(While symbol) { Symbol body = symbol.getBody().accept(this); if (body == symbol.getBody()) return symbol; - - return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol).build(); + + return new While.Builder(symbol.getExpression(), body).setLabel(symbol.getLabel()).addConditions(symbol) + .build(); } @Override @@ -587,5 +610,4 @@ public Symbol visit(Return symbol) { } } - } diff --git a/src/org/iguana/grammar/transformation/FindLabelsUsedInExcepts.java b/src/org/iguana/grammar/transformation/FindLabelsUsedInExcepts.java index af89d6f29..c3ac484bb 100644 --- a/src/org/iguana/grammar/transformation/FindLabelsUsedInExcepts.java +++ b/src/org/iguana/grammar/transformation/FindLabelsUsedInExcepts.java @@ -40,7 +40,8 @@ public Void visit(Align symbol) { } @Override - public Void visit(Block symbol) { // Currently, also expected to be desugared as part of data-dependent EBNF constructs + // Currently, also expected to be desugared as part of data-dependent EBNF constructs + public Void visit(Block symbol) { throw new RuntimeException("Unexpected symbol: " + symbol); } @@ -62,12 +63,14 @@ public Void visit(Conditional symbol) { } @Override - public Void visit(IfThen symbol) { // Currently, also expected to be desugared as part of data-dependent EBNF constructs + // Currently, also expected to be desugared as part of data-dependent EBNF constructs + public Void visit(IfThen symbol) { throw new RuntimeException("Unexpected symbol: " + symbol); } @Override - public Void visit(IfThenElse symbol) { // Currently, also expected to be desugared as part of data-dependent EBNF constructs + // Currently, also expected to be desugared as part of data-dependent EBNF constructs + public Void visit(IfThenElse symbol) { throw new RuntimeException("Unexpected symbol: " + symbol); } @@ -103,7 +106,8 @@ public Void visit(Terminal symbol) { } @Override - public Void visit(While symbol) { // Currently, also expected to be desugared as part of data-dependent EBNF constructs + // Currently, also expected to be desugared as part of data-dependent EBNF constructs + public Void visit(While symbol) { throw new RuntimeException("Unexpected symbol: " + symbol); } diff --git a/src/org/iguana/grammar/transformation/LayoutWeaver.java b/src/org/iguana/grammar/transformation/LayoutWeaver.java index 1dad0267f..3b94658b4 100644 --- a/src/org/iguana/grammar/transformation/LayoutWeaver.java +++ b/src/org/iguana/grammar/transformation/LayoutWeaver.java @@ -47,7 +47,8 @@ public class LayoutWeaver implements GrammarTransformation { public RuntimeGrammar transform(RuntimeGrammar grammar) { Symbol layout = grammar.getLayout(); - RuntimeGrammar.Builder builder = RuntimeGrammar.builder().setLayout(layout).setStartSymbols(grammar.getStartSymbols()); + RuntimeGrammar.Builder builder = RuntimeGrammar.builder().setLayout(layout).setStartSymbols( + grammar.getStartSymbols()); for (RuntimeRule rule : grammar.getRules()) { RuntimeRule.Builder ruleBuilder = RuntimeRule.withHead(rule.getHead()) @@ -69,7 +70,8 @@ public RuntimeGrammar transform(RuntimeGrammar grammar) { if (layout == null) { builder.addRule(ruleBuilder.addSymbol(rule.symbolAt(0)).build()); } else { - builder.addRule(ruleBuilder.addSymbol(layout).addSymbol(rule.symbolAt(0)).addSymbol(layout).build()); + builder.addRule(ruleBuilder.addSymbol(layout).addSymbol(rule.symbolAt(0)).addSymbol(layout) + .build()); } continue; } @@ -142,7 +144,8 @@ private void addLayout(Symbol layout, RuntimeRule rule, RuntimeRule.Builder rule private Set getIgnoreLayoutConditions(Symbol s) { Set conditions = new LinkedHashSet<>(); for (Condition c : s.getPostConditions()) { - if (c.getType() == ConditionType.NOT_FOLLOW_IGNORE_LAYOUT || c.getType() == ConditionType.FOLLOW_IGNORE_LAYOUT) { + if (c.getType() == ConditionType.NOT_FOLLOW_IGNORE_LAYOUT || + c.getType() == ConditionType.FOLLOW_IGNORE_LAYOUT) { conditions.add(c); } } diff --git a/src/org/iguana/grammar/transformation/TopLevelPrecedenceNonterminals.java b/src/org/iguana/grammar/transformation/TopLevelPrecedenceNonterminals.java index c29282f29..10f66a3a9 100644 --- a/src/org/iguana/grammar/transformation/TopLevelPrecedenceNonterminals.java +++ b/src/org/iguana/grammar/transformation/TopLevelPrecedenceNonterminals.java @@ -34,6 +34,7 @@ private static boolean isPrecedenceRule(Rule rule) { List alternatives = rule.getPriorityLevels().get(0).getAlternatives(); if (alternatives.stream().anyMatch(alternative -> alternative.getAssociativity() != Associativity.UNDEFINED)) return true; - return alternatives.stream().flatMap(alternative -> alternative.seqs().stream()).anyMatch(sequence -> sequence.getAssociativity() != Associativity.UNDEFINED); + return alternatives.stream().flatMap(alternative -> alternative.seqs().stream()) + .anyMatch(sequence -> sequence.getAssociativity() != Associativity.UNDEFINED); } } diff --git a/src/org/iguana/grammar/transformation/VarToInt.java b/src/org/iguana/grammar/transformation/VarToInt.java index f4e656bea..90cbb3476 100644 --- a/src/org/iguana/grammar/transformation/VarToInt.java +++ b/src/org/iguana/grammar/transformation/VarToInt.java @@ -25,7 +25,8 @@ import java.util.*; -public class VarToInt implements GrammarTransformation, IAbstractASTVisitor, ISymbolVisitor, IConditionVisitor { +public class VarToInt implements GrammarTransformation, IAbstractASTVisitor, ISymbolVisitor, + IConditionVisitor { private Map> mapping; @@ -174,7 +175,8 @@ public Symbol visit(Nonterminal symbol) { .addExcepts(symbol.getExcepts()) .build(); - org.iguana.datadependent.ast.Expression[] arguments = new org.iguana.datadependent.ast.Expression[symbol.getArguments().length]; + org.iguana.datadependent.ast.Expression[] arguments = + new org.iguana.datadependent.ast.Expression[symbol.getArguments().length]; int i = 0; for (org.iguana.datadependent.ast.Expression e : symbol.getArguments()) @@ -270,7 +272,8 @@ public AbstractAST visit(Not not) { @Override public AbstractAST visit(Tuple expression) { - org.iguana.datadependent.ast.Expression[] expressions = new org.iguana.datadependent.ast.Expression[expression.getElements().length]; + org.iguana.datadependent.ast.Expression[] expressions = + new org.iguana.datadependent.ast.Expression[expression.getElements().length]; int i = 0; for (org.iguana.datadependent.ast.Expression e : expression.getElements()) @@ -296,7 +299,8 @@ public AbstractAST visit(Name expression) { @Override public AbstractAST visit(Call expression) { - org.iguana.datadependent.ast.Expression[] arguments = new org.iguana.datadependent.ast.Expression[expression.getArguments().length]; + org.iguana.datadependent.ast.Expression[] arguments = + new org.iguana.datadependent.ast.Expression[expression.getArguments().length]; int i = 0; for (org.iguana.datadependent.ast.Expression e : expression.getArguments()) arguments[i++] = (org.iguana.datadependent.ast.Expression) e.accept(this); @@ -325,7 +329,8 @@ public AbstractAST visit(Call expression) { case "pr1": return AST.pr1(arguments[0], arguments[1], arguments[2]); case "pr2": - org.iguana.datadependent.ast.Expression[] rest = new org.iguana.datadependent.ast.Expression[arguments.length - 2]; + org.iguana.datadependent.ast.Expression[] rest = + new org.iguana.datadependent.ast.Expression[arguments.length - 2]; System.arraycopy(arguments, 2, rest, 0, arguments.length - 2); return AST.pr2(arguments[0], arguments[1], rest); case "pr3": @@ -486,7 +491,8 @@ public AbstractAST visit(org.iguana.datadependent.ast.Expression.IfThenElse expr public AbstractAST visit(VariableDeclaration declaration) { int i = current.size(); current.put(declaration.getName(), i); - return AST.varDecl(declaration.getName(), i, (org.iguana.datadependent.ast.Expression) declaration.getExpression().accept(this)); + return AST.varDecl(declaration.getName(), i, + (org.iguana.datadependent.ast.Expression) declaration.getExpression().accept(this)); } @Override @@ -527,7 +533,8 @@ public AbstractAST visit(Expression statement) { @Override public Condition visit(DataDependentCondition condition) { - return DataDependentCondition.predicate((org.iguana.datadependent.ast.Expression) condition.getExpression().accept(this)); + return DataDependentCondition.predicate( + (org.iguana.datadependent.ast.Expression) condition.getExpression().accept(this)); } @Override diff --git a/src/org/iguana/gss/DefaultGSSNode.java b/src/org/iguana/gss/DefaultGSSNode.java index 0bab81687..e0bda1d9f 100644 --- a/src/org/iguana/gss/DefaultGSSNode.java +++ b/src/org/iguana/gss/DefaultGSSNode.java @@ -63,7 +63,15 @@ public DefaultGSSNode(GSSEdge firstGSSEdge, int inputIndex) { } @Override - public void addGSSEdge(Input input, BodyGrammarSlot returnSlot, int i, GSSNode destination, T w, Environment env, IguanaRuntime runtime) { + public void addGSSEdge( + Input input, + BodyGrammarSlot returnSlot, + int i, + GSSNode destination, + T w, + Environment env, + IguanaRuntime runtime + ) { if (this == destination && w.isDummy()) { if (!(firstGSSEdge instanceof CyclicDummyGSSEdges)) { addGSSEdge(firstGSSEdge); @@ -87,7 +95,14 @@ private void addGSSEdge(GSSEdge edge) { restGSSEdges.add(edge); } - private void iterateOverPoppedElements(GSSEdge edge, BodyGrammarSlot returnSlot, GSSNode destination, Input input, Environment env, IguanaRuntime runtime) { + private void iterateOverPoppedElements( + GSSEdge edge, + BodyGrammarSlot returnSlot, + GSSNode destination, + Input input, + Environment env, + IguanaRuntime runtime + ) { if (firstPoppedElement != null) processPoppedElement(firstPoppedElement, edge, returnSlot, destination, input, env, runtime); @@ -122,7 +137,8 @@ private T addPoppedElements(EndGrammarSlot slot, T child, Object value, ResultOp int rightIndex = child.getRightExtent(); // Only one node is added and there is an ambiguity - if (rightIndex == firstPoppedElement.getRightExtent() && Objects.equals(value, firstPoppedElement.getValue())) { + if (rightIndex == firstPoppedElement.getRightExtent() && + Objects.equals(value, firstPoppedElement.getValue())) { ops.convert(firstPoppedElement, child, slot, value); return null; } else { @@ -148,7 +164,15 @@ private T addPoppedElements(EndGrammarSlot slot, T child, Object value, ResultOp } } - private void processPoppedElement(T poppedElement, GSSEdge edge, BodyGrammarSlot returnSlot, GSSNode destination, Input input, Environment env, IguanaRuntime runtime) { + private void processPoppedElement( + T poppedElement, + GSSEdge edge, + BodyGrammarSlot returnSlot, + GSSNode destination, + Input input, + Environment env, + IguanaRuntime runtime + ) { if (returnSlot.testFollow(input.charAt(poppedElement.getRightExtent()))) { T result = addDescriptor(input, this, poppedElement, edge, returnSlot, runtime); if (result != null) { @@ -177,13 +201,20 @@ private void iterateOverEdges(Input input, T result, IguanaRuntime runtime) { } } - private void processEdge(Input input, T node, GSSEdge edge, BodyGrammarSlot returnSlot, IguanaRuntime runtime) { + private void processEdge( + Input input, + T node, + GSSEdge edge, + BodyGrammarSlot returnSlot, + IguanaRuntime runtime + ) { if (!returnSlot.testFollow(input.charAt(node.getRightExtent()))) return; T result = addDescriptor(input, this, node, edge, returnSlot, runtime); if (result != null) { Environment env = runtime.getEnvironment(); - runtime.scheduleDescriptor(returnSlot, edge.getDestination() != null? edge.getDestination() : this, result, env); + runtime.scheduleDescriptor(returnSlot, edge.getDestination() != null ? edge.getDestination() : this, result, + env); } } @@ -196,7 +227,14 @@ private void processEdge(Input input, T node, GSSEdge edge, BodyGrammarSlot r * (2.2) if no, creates one and returns it * */ - private T addDescriptor(Input input, GSSNode source, T result, GSSEdge edge, BodyGrammarSlot returnSlot, IguanaRuntime runtime) { + private T addDescriptor( + Input input, + GSSNode source, + T result, + GSSEdge edge, + BodyGrammarSlot returnSlot, + IguanaRuntime runtime + ) { int inputIndex = result.isDummy() ? source.getInputIndex() : result.getRightExtent(); Environment env = edge.getEnv() == null ? runtime.getEmptyEnvironment() : edge.getEnv(); GSSNode destination = edge.getDestination() != null ? edge.getDestination() : source; @@ -206,7 +244,8 @@ private T addDescriptor(Input input, GSSNode source, T result, GSSEdge edg runtime.setEnvironment(env); - if (returnSlot.getConditions().execute(input, returnSlot, source, inputIndex, runtime.getEvaluatorContext(), runtime)) { + if (returnSlot.getConditions().execute(input, returnSlot, source, inputIndex, runtime.getEvaluatorContext(), + runtime)) { EnvironmentPool.returnToPool(env); return null; } diff --git a/src/org/iguana/gss/GSSNode.java b/src/org/iguana/gss/GSSNode.java index 5ae1572bb..a7f1973bd 100644 --- a/src/org/iguana/gss/GSSNode.java +++ b/src/org/iguana/gss/GSSNode.java @@ -16,7 +16,15 @@ public interface GSSNode { Object[] getData(); - void addGSSEdge(Input input, BodyGrammarSlot returnSlot, int i, GSSNode destination, T w, Environment env, IguanaRuntime runtime); + void addGSSEdge( + Input input, + BodyGrammarSlot returnSlot, + int i, + GSSNode destination, + T w, + Environment env, + IguanaRuntime runtime + ); boolean pop(Input input, EndGrammarSlot slot, T child, IguanaRuntime runtime); diff --git a/src/org/iguana/gss/StartGSSNode.java b/src/org/iguana/gss/StartGSSNode.java index 1500baae1..57f3b9f99 100644 --- a/src/org/iguana/gss/StartGSSNode.java +++ b/src/org/iguana/gss/StartGSSNode.java @@ -48,7 +48,15 @@ public Object[] getData() { } @Override - public void addGSSEdge(Input input, BodyGrammarSlot returnSlot, int i, GSSNode destination, T w, Environment env, IguanaRuntime runtime) { + public void addGSSEdge( + Input input, + BodyGrammarSlot returnSlot, + int i, + GSSNode destination, + T w, + Environment env, + IguanaRuntime runtime + ) { throw new UnsupportedOperationException(); } diff --git a/src/org/iguana/iggy/IggyParseTreeToGrammarVisitor.java b/src/org/iguana/iggy/IggyParseTreeToGrammarVisitor.java index 7aaa3b138..4a16b22cf 100644 --- a/src/org/iguana/iggy/IggyParseTreeToGrammarVisitor.java +++ b/src/org/iguana/iggy/IggyParseTreeToGrammarVisitor.java @@ -107,7 +107,8 @@ public Rule visitContextFreeRule(IggyParseTree.ContextFreeRule node) { } } Nonterminal nonterminal = new Nonterminal.Builder(nonterminalName.getName()) - .addParameters(parameters.map(identifiers -> identifiers.stream().map(AbstractSymbol::toString).collect(Collectors.toList())).orElse(Collections.emptyList())) + .addParameters(parameters.map(identifiers -> identifiers.stream().map(AbstractSymbol::toString) + .collect(Collectors.toList())).orElse(Collections.emptyList())) .setNodeType(nonterminalNodeType) .build(); diff --git a/src/org/iguana/iggy/gen/IggyParseTreeBuilder.java b/src/org/iguana/iggy/gen/IggyParseTreeBuilder.java index 11b3d23e4..3fb69c8e9 100644 --- a/src/org/iguana/iggy/gen/IggyParseTreeBuilder.java +++ b/src/org/iguana/iggy/gen/IggyParseTreeBuilder.java @@ -16,7 +16,12 @@ public IggyParseTreeBuilder(Input input) { } @Override - public NonterminalNode nonterminalNode(RuntimeRule rule, List children, int leftExtent, int rightExtent) { + public NonterminalNode nonterminalNode( + RuntimeRule rule, + List children, + int leftExtent, + int rightExtent + ) { java.lang.String name = rule.getHead().getName(); java.lang.String label = rule.getLabel(); diff --git a/src/org/iguana/parser/IguanaParser.java b/src/org/iguana/parser/IguanaParser.java index 31d53d72a..96d559c7a 100644 --- a/src/org/iguana/parser/IguanaParser.java +++ b/src/org/iguana/parser/IguanaParser.java @@ -74,7 +74,8 @@ public void parse(Input input, Symbol symbol) { } public void parse(Input input, Start start) { - parse(input, Nonterminal.withName(assertStartSymbolNotNull(start).getName()), new ParseOptions.Builder().setGlobal(false).build()); + parse(input, Nonterminal.withName(assertStartSymbolNotNull(start).getName()), new ParseOptions.Builder() + .setGlobal(false).build()); } public void parse(Input input, Nonterminal nonterminal) { @@ -119,7 +120,8 @@ public ParseTreeNode getParseTree(boolean allowAmbiguities, boolean ignoreLayout if (sppf == null) return null; if (allowAmbiguities) { - AmbiguousSPPFToParseTreeVisitor visitor = new AmbiguousSPPFToParseTreeVisitor<>(getParseTreeBuilder(input), ignoreLayout, parserResultOps); + AmbiguousSPPFToParseTreeVisitor visitor = + new AmbiguousSPPFToParseTreeVisitor<>(getParseTreeBuilder(input), ignoreLayout, parserResultOps); long start = System.nanoTime(); ParseTreeNode node = (ParseTreeNode) sppf.accept(visitor).getValues().get(0); long end = System.nanoTime(); @@ -127,7 +129,8 @@ public ParseTreeNode getParseTree(boolean allowAmbiguities, boolean ignoreLayout return node; } - DefaultSPPFToParseTreeVisitor visitor = new DefaultSPPFToParseTreeVisitor<>(getParseTreeBuilder(input), input, ignoreLayout, parserResultOps); + DefaultSPPFToParseTreeVisitor visitor = + new DefaultSPPFToParseTreeVisitor<>(getParseTreeBuilder(input), input, ignoreLayout, parserResultOps); long start = System.nanoTime(); this.parseTree = sppf.accept(visitor); long end = System.nanoTime(); diff --git a/src/org/iguana/parser/IguanaRecognizer.java b/src/org/iguana/parser/IguanaRecognizer.java index 73a85c340..eda9ea3bb 100644 --- a/src/org/iguana/parser/IguanaRecognizer.java +++ b/src/org/iguana/parser/IguanaRecognizer.java @@ -57,7 +57,8 @@ public boolean recognize(Input input, Nonterminal nonterminal) { } public boolean recognize(Input input, Start start) { - return recognize(input, Nonterminal.withName(assertStartSymbolNotNull(start).getName()), Collections.emptyMap(), false); + return recognize(input, Nonterminal.withName(assertStartSymbolNotNull(start).getName()), Collections.emptyMap(), + false); } public boolean recognize(Input input, Nonterminal start, Map map, boolean global) { diff --git a/src/org/iguana/parser/IguanaRuntime.java b/src/org/iguana/parser/IguanaRuntime.java index 0ec521c29..1fbd46b7a 100644 --- a/src/org/iguana/parser/IguanaRuntime.java +++ b/src/org/iguana/parser/IguanaRuntime.java @@ -83,7 +83,8 @@ public T run(Input input, Nonterminal start, GrammarGraph grammarGraph, Map(startSlot, 0); } @@ -124,7 +125,8 @@ private T runParserLoop(StartGSSNode startGSSNode, Input input) { while (hasDescriptor()) { Descriptor descriptor = nextDescriptor(); logger.processDescriptor(descriptor); - descriptor.getGrammarSlot().execute(input, descriptor.getGSSNode(), descriptor.getResult(), descriptor.getEnv(), this); + descriptor.getGrammarSlot().execute(input, descriptor.getGSSNode(), descriptor.getResult(), + descriptor.getEnv(), this); } int inputLength = input.length() - 1; @@ -143,8 +145,15 @@ private void clearState(GrammarGraph grammarGraph) { parseErrors.clear(); } - public void recordParseError(int inputIndex, Input input, GrammarSlot slot, GSSNode gssNode, String description) { - ParseError error = new ParseError<>(slot, gssNode, inputIndex, input.getLineNumber(inputIndex), input.getColumnNumber(inputIndex), description); + public void recordParseError( + int inputIndex, + Input input, + GrammarSlot slot, + GSSNode gssNode, + String description + ) { + ParseError error = new ParseError<>(slot, gssNode, inputIndex, input.getLineNumber(inputIndex), + input.getColumnNumber(inputIndex), description); parseErrors.add(error); logger.error(error); } @@ -160,7 +169,11 @@ private void recoverFromError(GSSEdge edge, ErrorTransition errorTransition, // Collects all the GSS edges with the label of the form X = alpha . Error beta that are reachable // from the current GSS node to the start symbol GSS node. - private void getErrorSlot(GSSNode gssNode, List, ErrorTransition>> result, Set> visited) { + private void getErrorSlot( + GSSNode gssNode, + List, ErrorTransition>> result, + Set> visited + ) { if (visited.contains(gssNode)) return; visited.add(gssNode); if (gssNode == null) return; @@ -230,9 +243,10 @@ public Environment getEmptyEnvironment() { public GSSEdge createGSSEdge(BodyGrammarSlot returnSlot, T result, GSSNode gssNode, Environment env) { if (result.isDummy()) { if (env.isEmpty()) { - return gssNode != null? new DummyGSSEdge<>(returnSlot, gssNode) : new CyclicDummyGSSEdges<>(); + return gssNode != null ? new DummyGSSEdge<>(returnSlot, gssNode) : new CyclicDummyGSSEdges<>(); } else { - return gssNode != null? new DummyGSSEdgeWithEnv<>(returnSlot, gssNode, env) : new CyclicDummyGSSEdgesWithEnv<>(env); + return gssNode != null ? new DummyGSSEdgeWithEnv<>(returnSlot, gssNode, env) + : new CyclicDummyGSSEdgesWithEnv<>(env); } } @@ -328,12 +342,14 @@ private static void printStats(GrammarGraph grammarGraph) { if (poppedElementStats == null) System.out.println("Popped Elements: empty"); else - System.out.printf("Popped Elements (min: %d, max: %d, mean: %.2f)%n", (int) poppedElementStats[0], (int) poppedElementStats[1], poppedElementStats[2]); + System.out.printf("Popped Elements (min: %d, max: %d, mean: %.2f)%n", (int) poppedElementStats[0], + (int) poppedElementStats[1], poppedElementStats[2]); if (gssEdgesStats == null) System.out.println("GSS Edges: empty"); else - System.out.printf("GSS Edges (min: %d, max: %d, mean: %.2f)%n", (int) gssEdgesStats[0], (int) gssEdgesStats[1], gssEdgesStats[2]); + System.out.printf("GSS Edges (min: %d, max: %d, mean: %.2f)%n", (int) gssEdgesStats[0], + (int) gssEdgesStats[1], gssEdgesStats[2]); System.out.println("---------------"); } } @@ -350,7 +366,8 @@ private static void printGSSInfo(GrammarGraph grammarGraph) { gssNodes.sort(edgeComparator); for (GSSNode gssNode : gssNodes) { - System.out.println(gssNode + ", edges: " + gssNode.countGSSEdges() + ", poppedElements: " + gssNode.countPoppedElements()); + System.out.println( + gssNode + ", edges: " + gssNode.countGSSEdges() + ", poppedElements: " + gssNode.countPoppedElements()); } } diff --git a/src/org/iguana/parser/ParseError.java b/src/org/iguana/parser/ParseError.java index 3bdb2b454..a31145239 100644 --- a/src/org/iguana/parser/ParseError.java +++ b/src/org/iguana/parser/ParseError.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -36,63 +36,71 @@ public class ParseError { - private final GrammarSlot slot; - private final int inputIndex; - private final int lineNumber; - private final int columnNumber; - private final GSSNode gssNode; - private final String description; - - public ParseError(GrammarSlot slot, GSSNode gssNode, int inputIndex, int lineNumber, int columnNumber, String description) { - this.slot = slot; - this.inputIndex = inputIndex; - this.lineNumber = lineNumber; - this.columnNumber = columnNumber; - this.description = description; - this.gssNode = gssNode; + private final GrammarSlot slot; + private final int inputIndex; + private final int lineNumber; + private final int columnNumber; + private final GSSNode gssNode; + private final String description; + + public ParseError( + GrammarSlot slot, + GSSNode gssNode, + int inputIndex, + int lineNumber, + int columnNumber, + String description + ) { + this.slot = slot; + this.inputIndex = inputIndex; + this.lineNumber = lineNumber; + this.columnNumber = columnNumber; + this.description = description; + this.gssNode = gssNode; + } + + public int getInputIndex() { + return inputIndex; + } + + public GrammarSlot getGrammarSlot() { + return slot; + } + + public int getLineNumber() { + return lineNumber; + } + + public int getColumnNumber() { + return columnNumber; } - - public int getInputIndex() { - return inputIndex; - } - - public GrammarSlot getGrammarSlot() { - return slot; - } - - public int getLineNumber() { - return lineNumber; - } - - public int getColumnNumber() { - return columnNumber; - } - - public String getDescription() { - return description; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (!(obj instanceof ParseError)) return false; - ParseError other = (ParseError) obj; - return inputIndex == other.inputIndex && - lineNumber == other.lineNumber && - columnNumber == other.columnNumber; - } - - public GSSNode getGssNode() { - return gssNode; - } - - @Override - public int hashCode() { - return Objects.hash(inputIndex, lineNumber, columnNumber); - } - - @Override + + public String getDescription() { + return description; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof ParseError)) return false; + ParseError other = (ParseError) obj; + return inputIndex == other.inputIndex && + lineNumber == other.lineNumber && + columnNumber == other.columnNumber; + } + + public GSSNode getGssNode() { + return gssNode; + } + + @Override + public int hashCode() { + return Objects.hash(inputIndex, lineNumber, columnNumber); + } + + @Override public String toString() { - return String.format("Parse error at input index: %d, line: %d, column: %d, grammar rule: %s, description: %s", inputIndex, lineNumber, columnNumber, slot, description); + return String.format("Parse error at input index: %d, line: %d, column: %d, grammar rule: %s, description: %s", + inputIndex, lineNumber, columnNumber, slot, description); } } diff --git a/src/org/iguana/parsetree/DefaultParseTreeBuilder.java b/src/org/iguana/parsetree/DefaultParseTreeBuilder.java index fa2ea71df..4254b6f05 100644 --- a/src/org/iguana/parsetree/DefaultParseTreeBuilder.java +++ b/src/org/iguana/parsetree/DefaultParseTreeBuilder.java @@ -28,7 +28,12 @@ public TerminalNode terminalNode(Terminal terminal, int leftExtent, int rightExt } @Override - public NonterminalNode nonterminalNode(RuntimeRule rule, List children, int leftExtent, int rightExtent) { + public NonterminalNode nonterminalNode( + RuntimeRule rule, + List children, + int leftExtent, + int rightExtent + ) { return new NonterminalNode(rule, children, leftExtent, rightExtent); } diff --git a/src/org/iguana/parsetree/VisitResult.java b/src/org/iguana/parsetree/VisitResult.java index 0923564ef..7846701ce 100644 --- a/src/org/iguana/parsetree/VisitResult.java +++ b/src/org/iguana/parsetree/VisitResult.java @@ -478,13 +478,15 @@ public CreateParseTreeVisitor(ParseTreeBuilder parseTreeBuilder) { @Override public java.util.List visit(Empty result, PackedNode packedNode) { RuntimeRule rule = packedNode.getGrammarSlot().getRule(); - return CollectionsUtil.list(parseTreeBuilder.nonterminalNode(rule, (java.util.List) result.getValues(), packedNode.getLeftExtent(), packedNode.getRightExtent())); + return CollectionsUtil.list(parseTreeBuilder.nonterminalNode(rule, (java.util.List) result.getValues(), + packedNode.getLeftExtent(), packedNode.getRightExtent())); } @Override public java.util.List visit(Single result, PackedNode packedNode) { RuntimeRule rule = packedNode.getGrammarSlot().getRule(); - return CollectionsUtil.list((parseTreeBuilder.nonterminalNode(rule, (java.util.List) result.getValues(), packedNode.getLeftExtent(), packedNode.getRightExtent()))); + return CollectionsUtil.list((parseTreeBuilder.nonterminalNode(rule, (java.util.List) result.getValues(), + packedNode.getLeftExtent(), packedNode.getRightExtent()))); } @Override @@ -498,12 +500,14 @@ public java.util.List visit(List result, PackedNode packedNode) { } } RuntimeRule rule = packedNode.getGrammarSlot().getRule(); - return CollectionsUtil.list(parseTreeBuilder.nonterminalNode(rule, values, packedNode.getLeftExtent(), packedNode.getRightExtent())); + return CollectionsUtil.list(parseTreeBuilder.nonterminalNode(rule, values, packedNode.getLeftExtent(), + packedNode.getRightExtent())); } @Override public java.util.List visit(EBNF result, PackedNode packedNode) { - T ebnfNode = parseTreeBuilder.metaSymbolNode(result.getSymbol(), (java.util.List) result.getValues(), packedNode.getLeftExtent(), packedNode.getRightExtent()); + T ebnfNode = parseTreeBuilder.metaSymbolNode(result.getSymbol(), (java.util.List) result.getValues(), + packedNode.getLeftExtent(), packedNode.getRightExtent()); return CollectionsUtil.list(ebnfNode); } @@ -511,7 +515,8 @@ public java.util.List visit(EBNF result, PackedNode packedNode) { public java.util.List visit(ListOfResult result, PackedNode packedNode) { Set set = new LinkedHashSet<>(); for (VisitResult vResult :result.getVisitResults()) { - set.add(parseTreeBuilder.nonterminalNode(packedNode.getGrammarSlot().getRule(), (java.util.List) vResult.getValues(), packedNode.getLeftExtent(), packedNode.getRightExtent())); + set.add(parseTreeBuilder.nonterminalNode(packedNode.getGrammarSlot().getRule(), + (java.util.List) vResult.getValues(), packedNode.getLeftExtent(), packedNode.getRightExtent())); } return CollectionsUtil.list(parseTreeBuilder.ambiguityNode(set)); } diff --git a/src/org/iguana/regex/InlineReferences.java b/src/org/iguana/regex/InlineReferences.java index b0fe11556..96e78cb81 100644 --- a/src/org/iguana/regex/InlineReferences.java +++ b/src/org/iguana/regex/InlineReferences.java @@ -22,7 +22,8 @@ public static Map inline(Map references : referencesMap.values()) { for (String reference : references) { if (!referencesMap.containsKey(reference)) { - throw new RuntimeException(reference + " refers to a name which is not a defined regular expression"); + throw new RuntimeException( + reference + " refers to a name which is not a defined regular expression"); } } } diff --git a/src/org/iguana/regex/Seq.java b/src/org/iguana/regex/Seq.java index 9606e7334..5f0d39059 100644 --- a/src/org/iguana/regex/Seq.java +++ b/src/org/iguana/regex/Seq.java @@ -98,7 +98,8 @@ public int hashCode() { @Override public String toString() { if (symbols.stream().allMatch(c -> c instanceof Char)) - return "'" + symbols.stream().map(c -> Char.getName(((Char) c).getValue())).collect(Collectors.joining("")) + "'"; + return "'" + symbols.stream().map(c -> Char.getName(((Char) c).getValue())) + .collect(Collectors.joining("")) + "'"; return "(" + symbols.stream().map(a -> a.toString()).collect(Collectors.joining(" ")) + ")"; } diff --git a/src/org/iguana/regex/automaton/AutomatonOperations.java b/src/org/iguana/regex/automaton/AutomatonOperations.java index 778cdce65..2bbffcd2a 100644 --- a/src/org/iguana/regex/automaton/AutomatonOperations.java +++ b/src/org/iguana/regex/automaton/AutomatonOperations.java @@ -324,8 +324,8 @@ public static Automaton minimize(CharRange[] alphabet, State[] states, State sta State q1 = states[i].getState(alphabet[t]); State q2 = states[j].getState(alphabet[t]); - // If both states i and j have no outgoing transitions on the interval t, continue with the - // next transition. + // If both states i and j have no outgoing transitions on the interval t, continue with + // the next transition. if (q1 == null && q2 == null) { continue; } @@ -429,7 +429,8 @@ else if (partitionJ == null && partitionI != null) { for (State state : states) { for (Transition t : state.getTransitions()) { - newStates.get(state).addTransition(new Transition(t.getStart(), t.getEnd(), newStates.get(t.getDestination()))); + newStates.get(state).addTransition(new Transition(t.getStart(), t.getEnd(), + newStates.get(t.getDestination()))); } } diff --git a/src/org/iguana/regex/matcher/DFAMatcherFactory.java b/src/org/iguana/regex/matcher/DFAMatcherFactory.java index 59b40b10d..c2ea87bb6 100644 --- a/src/org/iguana/regex/matcher/DFAMatcherFactory.java +++ b/src/org/iguana/regex/matcher/DFAMatcherFactory.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -36,53 +36,54 @@ import java.util.Map; public class DFAMatcherFactory implements MatcherFactory { - - private Map matcherCache = new HashMap<>(); - private Map backwardsMatcherCache = new HashMap<>(); + + private final Map matcherCache = new HashMap<>(); + private final Map backwardsMatcherCache = new HashMap<>(); public org.iguana.regex.matcher.Matcher getMatcher(RegularExpression regex) { - - if (regex == Epsilon.getInstance()) - return epsilonMatcher(); - + + if (regex == Epsilon.getInstance()) + return epsilonMatcher(); + if (regex instanceof Char) return characterMatcher((Char) regex); - + if (regex instanceof CharRange) return characterRangeMatcher((CharRange) regex); - + return matcherCache.computeIfAbsent(regex, DFAMatcher::new); } - + public org.iguana.regex.matcher.Matcher getBackwardsMatcher(RegularExpression regex) { - + if (regex instanceof Char) return characterBackwardsMatcher((Char) regex); - + if (regex instanceof CharRange) return characterRangeBackwardsMatcher((CharRange) regex); - + return backwardsMatcherCache.computeIfAbsent(regex, DFABackwardsMatcher::new); } - + public static org.iguana.regex.matcher.Matcher characterMatcher(Char c) { return (input, i) -> input.charAt(i) == c.getValue() ? 1 : -1; } - + public static org.iguana.regex.matcher.Matcher characterBackwardsMatcher(Char c) { - return (input, i) -> i == 0 ? -1 : ( input.charAt(i - 1) == c.getValue() ? 1 : -1 ); + return (input, i) -> i == 0 ? -1 : (input.charAt(i - 1) == c.getValue() ? 1 : -1); } - + public static org.iguana.regex.matcher.Matcher characterRangeMatcher(CharRange range) { return (input, i) -> input.charAt(i) >= range.getStart() && input.charAt(i) <= range.getEnd() ? 1 : -1; } - + public static org.iguana.regex.matcher.Matcher characterRangeBackwardsMatcher(CharRange range) { - return (input, i) -> i == 0 ? -1 : ( input.charAt(i - 1) >= range.getStart() && input.charAt(i - 1) <= range.getEnd() ? 1 : -1 ); + return (input, i) -> i == 0 ? -1 + : (input.charAt(i - 1) >= range.getStart() && input.charAt(i - 1) <= range.getEnd() ? 1 : -1); } - + public static Matcher epsilonMatcher() { - return (input, i) -> 0; + return (input, i) -> 0; } - + } diff --git a/src/org/iguana/regex/visitor/InlineReferencesVisitor.java b/src/org/iguana/regex/visitor/InlineReferencesVisitor.java index ff531370f..6fdf9ee31 100644 --- a/src/org/iguana/regex/visitor/InlineReferencesVisitor.java +++ b/src/org/iguana/regex/visitor/InlineReferencesVisitor.java @@ -55,13 +55,15 @@ public RegularExpression visit(org.iguana.regex.Opt o) { @Override public RegularExpression visit(org.iguana.regex.Alt alt) { - List newSymbols = alt.getSymbols().stream().map(symbol -> symbol.accept(this)).collect(Collectors.toList()); + List newSymbols = alt.getSymbols().stream().map(symbol -> symbol.accept(this)) + .collect(Collectors.toList()); return alt.copy().setSymbols((List) newSymbols).build(); } @Override public RegularExpression visit(org.iguana.regex.Seq seq) { - List newSymbols = seq.getSymbols().stream().map(symbol -> symbol.accept(this)).collect(Collectors.toList()); + List newSymbols = seq.getSymbols().stream().map(symbol -> symbol.accept(this)) + .collect(Collectors.toList()); return seq.copy().setSymbols((List) newSymbols).build(); } diff --git a/src/org/iguana/result/ParserResultOps.java b/src/org/iguana/result/ParserResultOps.java index b1f75cd97..551fe59e9 100644 --- a/src/org/iguana/result/ParserResultOps.java +++ b/src/org/iguana/result/ParserResultOps.java @@ -15,16 +15,24 @@ public class ParserResultOps implements ResultOps { private static final NonPackedNode dummyNode = new NonPackedNode() { @Override - public PackedNode getChildAt(int index) { throw new UnsupportedOperationException(); } + public PackedNode getChildAt(int index) { + throw new UnsupportedOperationException(); + } @Override - public int childrenCount() { throw new UnsupportedOperationException(); } + public int childrenCount() { + throw new UnsupportedOperationException(); + } @Override - public GrammarSlot getGrammarSlot() { throw new UnsupportedOperationException(); } + public GrammarSlot getGrammarSlot() { + throw new UnsupportedOperationException(); + } @Override - public int getLeftExtent() { throw new UnsupportedOperationException(); } + public int getLeftExtent() { + throw new UnsupportedOperationException(); + } @Override public int getRightExtent() { @@ -37,7 +45,9 @@ public boolean isDummy() { } @Override - public R accept(SPPFVisitor visitor) { throw new UnsupportedOperationException(); } + public R accept(SPPFVisitor visitor) { + throw new UnsupportedOperationException(); + } @Override public void setAmbiguous(boolean ambiguous) { @@ -90,7 +100,12 @@ public NonPackedNode error(BodyGrammarSlot slot, int start, int end) { } @Override - public NonPackedNode merge(NonPackedNode current, NonPackedNode result1, NonPackedNode result2, BodyGrammarSlot slot) { + public NonPackedNode merge( + NonPackedNode current, + NonPackedNode result1, + NonPackedNode result2, + BodyGrammarSlot slot + ) { if (result1 == dummyNode) return result2; @@ -123,7 +138,8 @@ public NonPackedNode convert(NonPackedNode current, NonPackedNode result, EndGra if (value == null) current = new NonterminalNode(slot, result, result.getLeftExtent(), result.getRightExtent()); else - current = new NonterminalNodeWithValue(slot, result, result.getLeftExtent(), result.getRightExtent(), value); + current = new NonterminalNodeWithValue(slot, result, result.getLeftExtent(), result.getRightExtent(), + value); logger.nonterminalNodeAdded((NonterminalNode) current); } else { diff --git a/src/org/iguana/result/RecognizerResultOps.java b/src/org/iguana/result/RecognizerResultOps.java index 236c30ae1..6ce8515db 100644 --- a/src/org/iguana/result/RecognizerResultOps.java +++ b/src/org/iguana/result/RecognizerResultOps.java @@ -49,12 +49,22 @@ public RecognizerResult error(BodyGrammarSlot slot, int start, int end) { } @Override - public RecognizerResult merge(RecognizerResult current, RecognizerResult result1, RecognizerResult result2, BodyGrammarSlot slot) { + public RecognizerResult merge( + RecognizerResult current, + RecognizerResult result1, + RecognizerResult result2, + BodyGrammarSlot slot + ) { return result2; } @Override - public RecognizerResult convert(RecognizerResult current, RecognizerResult result, EndGrammarSlot slot, Object value) { + public RecognizerResult convert( + RecognizerResult current, + RecognizerResult result, + EndGrammarSlot slot, + Object value + ) { if (current == null) { if (value == null) { return result; diff --git a/src/org/iguana/sppf/NonterminalNodeWithValue.java b/src/org/iguana/sppf/NonterminalNodeWithValue.java index 8c4ec7c6d..516e69d1a 100644 --- a/src/org/iguana/sppf/NonterminalNodeWithValue.java +++ b/src/org/iguana/sppf/NonterminalNodeWithValue.java @@ -6,7 +6,13 @@ public class NonterminalNodeWithValue extends NonterminalNode { private final Object value; - public NonterminalNodeWithValue(EndGrammarSlot slot, NonPackedNode child, int leftExtent, int rightExtent, Object value) { + public NonterminalNodeWithValue( + EndGrammarSlot slot, + NonPackedNode child, + int leftExtent, + int rightExtent, + Object value + ) { super(slot, child, leftExtent, rightExtent); this.value = value; } diff --git a/src/org/iguana/traversal/AmbiguousSPPFToParseTreeVisitor.java b/src/org/iguana/traversal/AmbiguousSPPFToParseTreeVisitor.java index d4c66d5b0..b629cd183 100644 --- a/src/org/iguana/traversal/AmbiguousSPPFToParseTreeVisitor.java +++ b/src/org/iguana/traversal/AmbiguousSPPFToParseTreeVisitor.java @@ -27,7 +27,11 @@ public class AmbiguousSPPFToParseTreeVisitor implements SPPFVisitor createNodeVisitor; - public AmbiguousSPPFToParseTreeVisitor(ParseTreeBuilder parseTreeBuilder, boolean ignoreLayout, ParserResultOps resultOps) { + public AmbiguousSPPFToParseTreeVisitor( + ParseTreeBuilder parseTreeBuilder, + boolean ignoreLayout, + ParserResultOps resultOps + ) { this.parseTreeBuilder = parseTreeBuilder; this.ignoreLayout = ignoreLayout; this.resultOps = resultOps; @@ -43,7 +47,8 @@ public VisitResult visit(TerminalNode node) { } return convertedNodes.computeIfAbsent(node, key -> { if (node.getLeftExtent() == node.getRightExtent()) return empty(); - Object terminalNode = parseTreeBuilder.terminalNode(node.getGrammarSlot().getTerminal(), node.getLeftExtent(), node.getRightExtent()); + Object terminalNode = parseTreeBuilder.terminalNode(node.getGrammarSlot().getTerminal(), + node.getLeftExtent(), node.getRightExtent()); return single(terminalNode); } ); @@ -96,7 +101,8 @@ public VisitResult visit(org.iguana.sppf.NonterminalNode node) { } else { T child = children.get(0); if (child instanceof MetaSymbolNode) { // Last Plus node propagated up - result = single(parseTreeBuilder.nonterminalNode(packedNode.getGrammarSlot().getRule(), children, packedNode.getLeftExtent(), packedNode.getRightExtent())); + result = single(parseTreeBuilder.nonterminalNode(packedNode.getGrammarSlot().getRule(), + children, packedNode.getLeftExtent(), packedNode.getRightExtent())); } else { result = single(children.get(0)); } @@ -119,12 +125,17 @@ public VisitResult visit(org.iguana.sppf.NonterminalNode node) { Symbol symbol = packedNode.getGrammarSlot().getRule().getDefinition(); VisitResult visitResult = packedNode.accept(this); // This case handles X+ nodes under other EBNF nodes (See Test 14) - if (visitResult instanceof VisitResult.List && visitResult.getValues().size() == 1 && visitResult.getValues().get(0) instanceof VisitResult.EBNF) { + if (visitResult instanceof VisitResult.List && + visitResult.getValues().size() == 1 && + visitResult.getValues().get(0) instanceof VisitResult.EBNF) { VisitResult.EBNF ebnfChild = (VisitResult.EBNF) visitResult.getValues().get(0); - T ebnfResult = parseTreeBuilder.metaSymbolNode(ebnfChild.getSymbol(), (List) ebnfChild.getValues(), node.getLeftExtent(), node.getRightExtent()); - result = single(parseTreeBuilder.metaSymbolNode(symbol, singletonList(ebnfResult), node.getLeftExtent(), node.getRightExtent())); + T ebnfResult = parseTreeBuilder.metaSymbolNode(ebnfChild.getSymbol(), + (List) ebnfChild.getValues(), node.getLeftExtent(), node.getRightExtent()); + result = single(parseTreeBuilder.metaSymbolNode(symbol, singletonList(ebnfResult), + node.getLeftExtent(), node.getRightExtent())); } else { - result = single(parseTreeBuilder.metaSymbolNode(symbol, (List) visitResult.getValues(), node.getLeftExtent(), node.getRightExtent())); + result = single(parseTreeBuilder.metaSymbolNode(symbol, (List) visitResult.getValues(), + node.getLeftExtent(), node.getRightExtent())); } break; diff --git a/src/org/iguana/traversal/DefaultSPPFToParseTreeVisitor.java b/src/org/iguana/traversal/DefaultSPPFToParseTreeVisitor.java index 28307a518..12787a454 100644 --- a/src/org/iguana/traversal/DefaultSPPFToParseTreeVisitor.java +++ b/src/org/iguana/traversal/DefaultSPPFToParseTreeVisitor.java @@ -19,12 +19,10 @@ import static java.util.Collections.emptyList; /** - * * Unambiguous Nonterminal nodes have only one child. * Unambiguous Intermediate nodes two children: - * - The left child is an intermediate node and the right child a nonterminal or terminal node - * - Both left and right children are nonterminal or terminal nodes - * + * - The left child is an intermediate node and the right child a nonterminal or terminal node + * - Both left and right children are nonterminal or terminal nodes */ public class DefaultSPPFToParseTreeVisitor implements SPPFVisitor { @@ -33,7 +31,12 @@ public class DefaultSPPFToParseTreeVisitor implements SPPFVisitor { private final boolean ignoreLayout; private final ParserResultOps resultOps; - public DefaultSPPFToParseTreeVisitor(ParseTreeBuilder parseTreeBuilder, Input input, boolean ignoreLayout, ParserResultOps resultOps) { + public DefaultSPPFToParseTreeVisitor( + ParseTreeBuilder parseTreeBuilder, + Input input, + boolean ignoreLayout, + ParserResultOps resultOps + ) { this.parseTreeBuilder = parseTreeBuilder; this.input = input; this.ignoreLayout = ignoreLayout; @@ -45,7 +48,8 @@ public T visit(TerminalNode node) { if (ignoreLayout && node.getGrammarSlot().getTerminal().getNodeType() == TerminalNodeType.Layout) { return null; } - return parseTreeBuilder.terminalNode(node.getGrammarSlot().getTerminal(), node.getLeftExtent(), node.getRightExtent()); + return parseTreeBuilder.terminalNode(node.getGrammarSlot().getTerminal(), node.getLeftExtent(), + node.getRightExtent()); } @Override @@ -197,7 +201,8 @@ private T convertSeq(NonPackedNode node, Group symbol, int leftExtent, int right } private T convertStart(NonPackedNode node, Start symbol, int leftExtent, int rightExtent) { - List children = new ArrayList<>(ignoreLayout ? 3 : 1); // Layout is inserted before and after the start symbol + List children = new ArrayList<>( + ignoreLayout ? 3 : 1); // Layout is inserted before and after the start symbol addChildren(node.accept(this), children); reverse(children); return parseTreeBuilder.metaSymbolNode(symbol, children, leftExtent, rightExtent); @@ -230,8 +235,7 @@ private NonterminalNode convertUnderPlus(Plus plus, IntermediateNode node, List< if (leftChild instanceof IntermediateNode) { return convertUnderPlus(plus, (IntermediateNode) leftChild, children); - } - else { + } else { if (leftChild instanceof NonterminalNode) { RuntimeRule rule = ((NonterminalNode) leftChild).getRule(); if (rule.getDefinition() != null && plus.getName().equals(rule.getDefinition().getName())) { diff --git a/src/org/iguana/traversal/SymbolToSymbolVisitor.java b/src/org/iguana/traversal/SymbolToSymbolVisitor.java index a029d6061..56661d713 100644 --- a/src/org/iguana/traversal/SymbolToSymbolVisitor.java +++ b/src/org/iguana/traversal/SymbolToSymbolVisitor.java @@ -17,7 +17,8 @@ import java.util.List; import java.util.stream.Collectors; -public interface SymbolToSymbolVisitor extends ISymbolVisitor, IConditionVisitor, RegularExpressionVisitor { +public interface SymbolToSymbolVisitor + extends ISymbolVisitor, IConditionVisitor, RegularExpressionVisitor { @Override default Symbol visit(Align symbol) { @@ -227,7 +228,8 @@ default List visitPostConditions(Symbol symbol) { } default RegularExpression visitRegularExpression(RegularExpression regex) { - List newChildren = regex.getChildren().stream().map(r -> r.accept(this)).collect(Collectors.toList()); + List newChildren = regex.getChildren().stream().map(r -> r.accept(this)) + .collect(Collectors.toList()); RegularExpression newRegex = regex.copy().setChildren(newChildren).build(); if (newRegex.equals(regex)) { return regex; diff --git a/src/org/iguana/traversal/ToSlotActionConditionVisitor.java b/src/org/iguana/traversal/ToSlotActionConditionVisitor.java index 3e2b508cf..29301c76f 100644 --- a/src/org/iguana/traversal/ToSlotActionConditionVisitor.java +++ b/src/org/iguana/traversal/ToSlotActionConditionVisitor.java @@ -2,25 +2,25 @@ * Copyright (c) 2015, Ali Afroozeh and Anastasia Izmaylova, Centrum Wiskunde & Informatica (CWI) * All rights reserved. * - * Redistribution and use in source and binary forms, with or without + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - * 1. Redistributions of source code must retain the above copyright notice, this + * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or + * 2. Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * */ @@ -44,174 +44,245 @@ public class ToSlotActionConditionVisitor implements IConditionVisitor { - private final MatcherFactory factory; - - private final Map cachePositional = new HashMap<>(); - - private final Map cacheRegular = new HashMap<>(); + private final MatcherFactory factory; - public ToSlotActionConditionVisitor(MatcherFactory factory) { - this.factory = factory; - } - - @Override - public SlotAction visit(DataDependentCondition condition) { - return new SlotAction() { + private final Map cachePositional = new HashMap<>(); + + private final Map cacheRegular = new HashMap<>(); + + public ToSlotActionConditionVisitor(MatcherFactory factory) { + this.factory = factory; + } + + @Override + public SlotAction visit(DataDependentCondition condition) { + return new SlotAction() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { Object value = condition.getExpression().interpret(ctx, input); if (!(value instanceof Boolean)) throw new RuntimeException("Data dependent condition should evaluate to a boolean value."); return (!(Boolean) value); } - - @Override - public String toString() { - return condition.toString(); - } - }; - } - - @Override - public SlotAction visit(PositionalCondition condition) { - return cachePositional.computeIfAbsent(condition, ToSlotActionConditionVisitor::create); - } - - private static SlotAction create(PositionalCondition condition) { - switch (condition.getType()) { - case START_OF_LINE: - return new SlotAction() { - - @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + + @Override + public String toString() { + return condition.toString(); + } + }; + } + + @Override + public SlotAction visit(PositionalCondition condition) { + return cachePositional.computeIfAbsent(condition, ToSlotActionConditionVisitor::create); + } + + private static SlotAction create(PositionalCondition condition) { + switch (condition.getType()) { + case START_OF_LINE: + return new SlotAction() { + + @Override + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return !input.isStartOfLine(rightExtent); } - @Override - public String toString() { - return condition.getType().getDescription(); - } - }; + @Override + public String toString() { + return condition.getType().getDescription(); + } + }; - case END_OF_LINE: - return new SlotAction() { + case END_OF_LINE: + return new SlotAction() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return !input.isEndOfLine(rightExtent); } - @Override - public String toString() { - return condition.getType().getDescription(); - } - }; + @Override + public String toString() { + return condition.getType().getDescription(); + } + }; - case END_OF_FILE: - return new SlotAction() { + case END_OF_FILE: + return new SlotAction() { @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return !input.isEndOfFile(rightExtent); } - @Override - public String toString() { - return condition.getType().getDescription(); - } - }; + @Override + public String toString() { + return condition.getType().getDescription(); + } + }; + + default: + throw new RuntimeException(); + } + } - default: - throw new RuntimeException(); - } - } + @Override + public SlotAction visit(RegularExpressionCondition condition) { + return cacheRegular.computeIfAbsent(condition, c -> create(c, factory)); + } - @Override - public SlotAction visit(RegularExpressionCondition condition) { - return cacheRegular.computeIfAbsent(condition, c -> create(c, factory)); - } - - private static SlotAction create(RegularExpressionCondition condition, MatcherFactory factory) { - - switch (condition.getType()) { - case FOLLOW: - case FOLLOW_IGNORE_LAYOUT: - return new SlotAction() { - final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); + private static SlotAction create(RegularExpressionCondition condition, MatcherFactory factory) { + + switch (condition.getType()) { + case FOLLOW: + case FOLLOW_IGNORE_LAYOUT: + return new SlotAction() { + final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return matcher.match(input, rightExtent) == -1; } - @Override - public String toString() { - return condition.getType().getDescription(); - } - }; - - case NOT_FOLLOW: - case NOT_FOLLOW_IGNORE_LAYOUT: - return new SlotAction() { - final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); + @Override + public String toString() { + return condition.getType().getDescription(); + } + }; + + case NOT_FOLLOW: + case NOT_FOLLOW_IGNORE_LAYOUT: + return new SlotAction() { + final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return matcher.match(input, rightExtent) >= 0; } - @Override - public String toString() { return condition.getType().toString(); } - }; - - case MATCH: - throw new RuntimeException("Unsupported"); - - case NOT_MATCH: - return new SlotAction() { - final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); + @Override + public String toString() { + return condition.getType().toString(); + } + }; + + case MATCH: + throw new RuntimeException("Unsupported"); + + case NOT_MATCH: + return new SlotAction() { + final Matcher matcher = factory.getMatcher(condition.getRegularExpression()); @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return matcher.match(input, gssNode.getInputIndex(), rightExtent); } - @Override - public String toString() { return condition.getType().toString(); } - }; - - case NOT_PRECEDE: - return new SlotAction() { - final Matcher matcher = factory.getBackwardsMatcher(condition.getRegularExpression()); + @Override + public String toString() { + return condition.getType().toString(); + } + }; + + case NOT_PRECEDE: + return new SlotAction() { + final Matcher matcher = factory.getBackwardsMatcher(condition.getRegularExpression()); @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return matcher.match(input, rightExtent) >= 0; } - @Override - public String toString() { return condition.getType().toString(); } - }; - - case PRECEDE: - return new SlotAction() { - final Matcher matcher = factory.getBackwardsMatcher(condition.getRegularExpression()); + @Override + public String toString() { + return condition.getType().toString(); + } + }; + + case PRECEDE: + return new SlotAction() { + final Matcher matcher = factory.getBackwardsMatcher(condition.getRegularExpression()); @Override - public boolean execute(Input input, BodyGrammarSlot slot, GSSNode gssNode, int leftExtent, int rightExtent, IEvaluatorContext ctx) { + public boolean execute( + Input input, + BodyGrammarSlot slot, + GSSNode gssNode, + int leftExtent, + int rightExtent, + IEvaluatorContext ctx + ) { return matcher.match(input, rightExtent) == -1; } - @Override - public String toString() { return condition.getType().toString(); } - }; - - default: - throw new RuntimeException("Unexpected error occurred."); - } - } + @Override + public String toString() { + return condition.getType().toString(); + } + }; + + default: + throw new RuntimeException("Unexpected error occurred."); + } + } } diff --git a/src/org/iguana/traversal/exception/AmbiguityException.java b/src/org/iguana/traversal/exception/AmbiguityException.java index 86fb5422e..cb7033a62 100644 --- a/src/org/iguana/traversal/exception/AmbiguityException.java +++ b/src/org/iguana/traversal/exception/AmbiguityException.java @@ -22,6 +22,7 @@ public String toString() { int lineNumber = input.getLineNumber(node.getRightExtent()); int columnNumber = input.getColumnNumber(node.getRightExtent()); String ambiguousSubstring = input.subString(node.getLeftExtent(), node.getRightExtent()); - return String.format("Ambiguity found for node %s at (%d, %d): '%s'", node, lineNumber, columnNumber, ambiguousSubstring); + return String.format("Ambiguity found for node %s at (%d, %d): '%s'", node, lineNumber, columnNumber, + ambiguousSubstring); } } diff --git a/src/org/iguana/traversal/idea/GenerateBasicFiles.java b/src/org/iguana/traversal/idea/GenerateBasicFiles.java index 35474c108..6e18c4cfd 100644 --- a/src/org/iguana/traversal/idea/GenerateBasicFiles.java +++ b/src/org/iguana/traversal/idea/GenerateBasicFiles.java @@ -69,8 +69,9 @@ public static void generate(String language, String extension, String path) { writer.println(); writer.println("public class " + language + "Lang extends Language {"); writer.println(" public static final " + language + "Lang instance = new " + language + "Lang();"); - writer.println(" public static final Icon file = IconLoader.getIcon(\"/" + language.toLowerCase() + "/gen/icons/icon.png\");"); - writer.println(" private " + language + "Lang() { super(\""+ language + "\"); }"); + writer.println(" public static final Icon file = IconLoader.getIcon(\"/" + language.toLowerCase() + + "/gen/icons/icon.png\");"); + writer.println(" private " + language + "Lang() { super(\"" + language + "\"); }"); writer.println("}"); writer.println(); writer.close(); @@ -91,7 +92,8 @@ public static void generate(String language, String extension, String path) { writer.println("import javax.swing.*;"); writer.println(); writer.println("public class " + language + "FileType extends LanguageFileType {"); - writer.println(" public static final " + language + "FileType instance = new " + language + "FileType();"); + writer.println( + " public static final " + language + "FileType instance = new " + language + "FileType();"); writer.println(" private " + language + "FileType() { super(" + language + "Lang.instance); }"); writer.println(); writer.println(" public String getName() { return \"" + language + "\"; }"); @@ -118,7 +120,9 @@ public static void generate(String language, String extension, String path) { writer.println("import com.intellij.openapi.fileTypes.FileTypeFactory;"); writer.println(); writer.println("public class " + language + "FileTypeFactory extends FileTypeFactory {"); - writer.println(" public void createFileTypes(FileTypeConsumer fileTypeConsumer) { fileTypeConsumer.consume(" + language + "FileType.instance, \"" + extension + "\"); }"); + writer.println( + " public void createFileTypes(FileTypeConsumer fileTypeConsumer) { fileTypeConsumer.consume(" + + language + "FileType.instance, \"" + extension + "\"); }"); writer.println("}"); writer.println(); writer.close(); @@ -139,7 +143,8 @@ public static void generate(String language, String extension, String path) { writer.println("import " + language.toLowerCase() + ".gen.lang." + language + "Lang;"); writer.println(); writer.println("public class " + language + "ElementType extends IElementType {"); - writer.println(" public " + language + "ElementType(String debugName) { super(debugName, " + language + "Lang.instance); }"); + writer.println(" public " + language + "ElementType(String debugName) { super(debugName, " + language + + "Lang.instance); }"); writer.println("}"); writer.println(); writer.close(); @@ -160,8 +165,10 @@ public static void generate(String language, String extension, String path) { writer.println("import " + language.toLowerCase() + ".gen.lang." + language + "Lang;"); writer.println(); writer.println("public class " + language + "TokenType extends IElementType {"); - writer.println(" public " + language + "TokenType(String debugName) { super(debugName, " + language + "Lang.instance); }"); - writer.println(" public String toString() { return \"" + language + "TokenType.\" + super.toString(); }"); + writer.println(" public " + language + "TokenType(String debugName) { super(debugName, " + language + + "Lang.instance); }"); + writer.println( + " public String toString() { return \"" + language + "TokenType.\" + super.toString(); }"); writer.println("}"); writer.println(); writer.close(); diff --git a/src/org/iguana/traversal/idea/GenerateBasicHighlighter.java b/src/org/iguana/traversal/idea/GenerateBasicHighlighter.java index c82a0bfab..79270df7e 100644 --- a/src/org/iguana/traversal/idea/GenerateBasicHighlighter.java +++ b/src/org/iguana/traversal/idea/GenerateBasicHighlighter.java @@ -72,8 +72,11 @@ public static void generate(String language, String path, Set tokenTypes color = "HighlighterColors.TEXT"; else color = "DefaultLanguageHighlighterColors." + color; - writer.println((i == 0? " if " : " else if ") + "(tokenType.equals(" + language + "TokenTypes." + tokenType + "))"); - writer.println(" return new TextAttributesKey[] {TextAttributesKey.createTextAttributesKey(\"" + tokenType + "\", " + color + ")};"); + writer.println((i == 0 ? " if " : " else if ") + "(tokenType.equals(" + language + + "TokenTypes." + tokenType + "))"); + writer.println( + " return new TextAttributesKey[] {TextAttributesKey.createTextAttributesKey(\"" + + tokenType + "\", " + color + ")};"); i++; } } @@ -101,7 +104,9 @@ public static void generate(String language, String path, Set tokenTypes writer.println("import com.intellij.openapi.vfs.VirtualFile;"); writer.println(); writer.println("public class " + language + "SyntaxHighlighterFactory extends SyntaxHighlighterFactory {"); - writer.println(" public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { return new " + language + "SyntaxHighlighter(); }"); + writer.println( + " public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) { " + + "return new " + language + "SyntaxHighlighter(); }"); writer.println("}"); writer.println(); writer.close(); @@ -114,14 +119,22 @@ public static void generate(String language, String path, Set tokenTypes private static String getColor(String tokenType) { switch (tokenType) { - case "OPERATOR": return "OPERATION_SIGN"; - case "OPEN_BRACE": return "BRACES"; - case "CLOSE_BRACE": return "BRACES"; - case "OPEN_PARENTHESIS": return "PARENTHESES"; - case "CLOSE_PARENTHESIS": return "PARENTHESES"; - case "OPEN_BRACKET": return "BRACKETS"; - case "CLOSE_BRACKET": return "BRACKETS"; - case "BAD_CHARACTER": return "BAD_CHARACTER"; + case "OPERATOR": + return "OPERATION_SIGN"; + case "OPEN_BRACE": + return "BRACES"; + case "CLOSE_BRACE": + return "BRACES"; + case "OPEN_PARENTHESIS": + return "PARENTHESES"; + case "CLOSE_PARENTHESIS": + return "PARENTHESES"; + case "OPEN_BRACKET": + return "BRACKETS"; + case "CLOSE_BRACKET": + return "BRACKETS"; + case "BAD_CHARACTER": + return "BAD_CHARACTER"; default: if (tokenType.toUpperCase().contains("COMMENT")) return "LINE_COMMENT"; diff --git a/src/org/iguana/traversal/idea/GenerateElements.java b/src/org/iguana/traversal/idea/GenerateElements.java index 5bb5f7f5e..8fef2c554 100644 --- a/src/org/iguana/traversal/idea/GenerateElements.java +++ b/src/org/iguana/traversal/idea/GenerateElements.java @@ -49,7 +49,7 @@ public class GenerateElements { * gen.psi.impl.* */ - enum NUM { ONE, MORE_THAN_ONE, ONE_AND_MORE } + enum NUM {ONE, MORE_THAN_ONE, ONE_AND_MORE} public static void generate(List rules, String language, String path) { Map> elements = new LinkedHashMap<>(); @@ -83,17 +83,24 @@ private static void generateElementTypes(Map> elements, Stri writer.println("public interface " + language + "ElementTypes {"); writer.println(); // ebnf related types, also data-dependent - writer.println(" public IElementType LIST = new " + language + "ElementType(\"LIST\");"); // * and while - writer.println(" public IElementType OPT = new " + language + "ElementType(\"OPT\");"); // ? and if-then - writer.println(" public IElementType ALT = new " + language + "ElementType(\"ALT\");"); // | and if-then-else - writer.println(" public IElementType SEQ = new " + language + "ElementType(\"SEQ\");"); // () and {} + // * and while + writer.println(" public IElementType LIST = new " + language + "ElementType(\"LIST\");"); + // ? and if-then + writer.println(" public IElementType OPT = new " + language + "ElementType(\"OPT\");"); + // | and if-then-else + writer.println(" public IElementType ALT = new " + language + "ElementType(\"ALT\");"); + // () and {} + writer.println(" public IElementType SEQ = new " + language + "ElementType(\"SEQ\");"); writer.println(); for (String head : elements.keySet()) { for (String label : elements.get(head)) { if (label.equals("Impl")) - writer.println(" public IElementType " + head.toUpperCase() + " = new " + language + "ElementType(\"" + head.toUpperCase() + "\");"); + writer.println(" public IElementType " + head.toUpperCase() + " = new " + language + + "ElementType(\"" + head.toUpperCase() + "\");"); else - writer.println(" public IElementType " + head.toUpperCase() + "_" + label.toUpperCase() + " = new " + language + "ElementType(\"" + head.toUpperCase() + "_" + label.toUpperCase() + "\");"); + writer.println( + " public IElementType " + head.toUpperCase() + "_" + label.toUpperCase() + " = new " + + language + "ElementType(\"" + head.toUpperCase() + "_" + label.toUpperCase() + "\");"); } } writer.println(); @@ -105,10 +112,12 @@ private static void generateElementTypes(Map> elements, Stri writer.println(" case \"SEQ\": return SEQ;"); for (String head : elements.keySet()) { for (String label : elements.get(head)) { - if (label.equals("Impl")) - writer.println(" case \"" + head.toUpperCase() + "\": return " + head.toUpperCase() + ";"); + if (label.equals("Impl")) writer.println( + " case \"" + head.toUpperCase() + "\": return " + head.toUpperCase() + ";"); else - writer.println(" case \"" + head.toUpperCase() + "_" + label.toUpperCase() + "\": return " + head.toUpperCase() + "_" + label.toUpperCase() + ";"); + writer.println( + " case \"" + head.toUpperCase() + "_" + label.toUpperCase() + "\": return " + + head.toUpperCase() + "_" + label.toUpperCase() + ";"); } } writer.println(" }"); @@ -118,13 +127,16 @@ private static void generateElementTypes(Map> elements, Stri writer.println(" class Factory {"); writer.println(" public static PsiElement createElement(ASTNode node) {"); writer.println(" IElementType type = node.getElementType();"); - writer.println(" if (type == LIST || type == OPT || type == ALT || type == SEQ) return new EbnfElementImpl(node);"); + writer.println(" if (type == LIST || type == OPT || type == ALT || type == SEQ) " + + "return new EbnfElementImpl(node);"); for (String head : elements.keySet()) { for (String label : elements.get(head)) { if (label.equals("Impl")) - writer.println(" if (type == " + head.toUpperCase() + ") return new " + head + "Impl(node);"); + writer.println( + " if (type == " + head.toUpperCase() + ") return new " + head + "Impl(node);"); else - writer.println(" if (type == " + head.toUpperCase() + "_" + label.toUpperCase() + ") return new " + head + label + "Impl(node);"); + writer.println(" if (type == " + head.toUpperCase() + "_" + label.toUpperCase() + + ") return new " + head + label + "Impl(node);"); } } writer.println(" throw new RuntimeException(\"Should not have happened!\");"); @@ -176,7 +188,8 @@ private static void generatePhiElements(List rules, String language break; case MORE_THAN_ONE: break; - case ONE_AND_MORE: throw new RuntimeException("Should not happen!"); + case ONE_AND_MORE: + throw new RuntimeException("Should not happen!"); } } } @@ -223,9 +236,13 @@ public void compute(String language, String path) { num = NUM.ONE; else switch (num) { - case ONE: num = NUM.MORE_THAN_ONE; break; - case MORE_THAN_ONE: break; - default: throw new RuntimeException("Should not happen!"); + case ONE: + num = NUM.MORE_THAN_ONE; + break; + case MORE_THAN_ONE: + break; + default: + throw new RuntimeException("Should not happen!"); } children.put(child, num); } @@ -436,24 +453,30 @@ else if (reference) switch (num) { case ONE: if (symbol.endsWith("$Ebnf")) - writer.println(" List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); + writer.println( + " List get" + symbol.substring(0, symbol.lastIndexOf("$")) + + "List();"); else writer.println(" I" + symbol + " get" + symbol + "();"); break; case MORE_THAN_ONE: if (symbol.endsWith("$Ebnf")) - writer.println(" List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); + writer.println(" List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); else writer.println(" List getAll" + symbol + "();"); break; case ONE_AND_MORE: if (symbol.endsWith("$Ebnf")) - writer.println(" List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); + writer.println( + " List get" + symbol.substring(0, symbol.lastIndexOf("$")) + + "List();"); else writer.println(" I" + symbol + " get" + symbol + "();"); if (symbol.endsWith("$Ebnf")) - writer.println(" List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); + writer.println(" List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + "List();"); else writer.println(" List getAll" + symbol + "();"); break; @@ -488,7 +511,8 @@ else if (reference) writer.println("import java.util.ArrayList;"); writer.println("import " + language.toLowerCase() + ".gen.psi.IEbnfElement;"); writer.println(); - writer.println("public class EbnfElementImpl" + " extends ASTWrapperPsiElement implements IEbnfElement {"); + writer.println( + "public class EbnfElementImpl" + " extends ASTWrapperPsiElement implements IEbnfElement {"); writer.println(); writer.println(" public EbnfElementImpl(ASTNode node) { super(node); }"); writer.println(); @@ -496,7 +520,8 @@ else if (reference) writer.println(); writer.println(" public List" + " getElements" + "() {"); writer.println(" List flattened = new ArrayList<>();"); - writer.println(" for (PsiElement e : PsiTreeUtil.getChildrenOfTypeAsList(this, PsiElement.class)) {"); + writer.println( + " for (PsiElement e : PsiTreeUtil.getChildrenOfTypeAsList(this, PsiElement.class)) {"); writer.println(" if (e instanceof IEbnfElement) "); writer.println(" flattened.addAll(((IEbnfElement) e).getElements());"); writer.println(" else "); @@ -518,7 +543,7 @@ else if (reference) for (Map.Entry> entry : elements.get(head).entrySet()) { - String name = head + (entry.getKey().equals("Impl")? entry.getKey() : entry.getKey() + "Impl"); + String name = head + (entry.getKey().equals("Impl") ? entry.getKey() : entry.getKey() + "Impl"); file = new File(path + language.toLowerCase() + "/gen/psi/impl/" + name + ".java"); boolean declaration = head.endsWith("$Declaration"); @@ -542,7 +567,8 @@ else if (reference) writer.println("import com.intellij.util.IncorrectOperationException;"); writer.println(); if (declaration || reference) - writer.println("import " + language.toLowerCase() + ".gen.utils." + language + "ElementFactory;"); + writer.println( + "import " + language.toLowerCase() + ".gen.utils." + language + "ElementFactory;"); if (reference) writer.println("import " + language.toLowerCase() + ".gen.utils." + language + "Util;"); writer.println(); @@ -551,7 +577,8 @@ else if (reference) writer.println(); writer.println("import " + language.toLowerCase() + ".gen.psi.*;"); writer.println(); - writer.println("public class " + name + " extends ASTWrapperPsiElement implements I" + head + " {"); + writer.println( + "public class " + name + " extends ASTWrapperPsiElement implements I" + head + " {"); writer.println(); writer.println(" public " + name + "(ASTNode node) { super(node); }"); writer.println(); @@ -567,67 +594,110 @@ else if (reference) case ONE: if (num2 == null) { if (symbol.endsWith("$Ebnf")) - writer.println(" public List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); + writer.println(" public List get" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); else - writer.println(" public I" + symbol + " get" + symbol + "() { return null; }"); + writer.println( + " public I" + symbol + " get" + symbol + "() { return null; }"); } else { if (symbol.endsWith("$Ebnf")) - writer.println(" public List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return findNotNullChildByClass(IEbnfElement.class).getElements(); }"); + writer.println(" public List get" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return findNotNullChildByClass(" + + "IEbnfElement.class).getElements(); }"); else - writer.println(" public I" + symbol + " get" + symbol + "() { return findNotNullChildByClass(I" + symbol + ".class); }"); + writer.println(" public I" + symbol + " get" + symbol + + "() { return findNotNullChildByClass(I" + symbol + + ".class); }"); } break; case MORE_THAN_ONE: if (num2 == null) { if (symbol.endsWith("$Ebnf")) - writer.println(" public List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); + writer.println(" public List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); else - writer.println(" public List getAll" + symbol + "() { return null; }"); + writer.println(" public List getAll" + symbol + + "() { return null; }"); } else { if (symbol.endsWith("$Ebnf")) { - writer.println(" public List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() {"); - writer.println(" List> result = new ArrayList<>();"); - writer.println(" for (IEbnfElement e : PsiTreeUtil.getChildrenOfTypeAsList(this, IEbnfElement.class))"); + writer.println(" public List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + "List() {"); + writer.println( + " List> result = new ArrayList<>();"); + writer.println( + " for (IEbnfElement e : PsiTreeUtil.getChildrenOfTypeAsList(" + + "this, IEbnfElement.class))"); writer.println(" result.add(e.getElements());"); writer.println(" return result;"); writer.println(" }"); } else - writer.println(" public List getAll" + symbol + "() { return PsiTreeUtil.getChildrenOfTypeAsList(this, I" + symbol + ".class); }"); + writer.println(" public List getAll" + symbol + + "() { return PsiTreeUtil.getChildrenOfTypeAsList(this, I" + + symbol + ".class); }"); } break; case ONE_AND_MORE: if (num2 == null) { if (symbol.endsWith("$Ebnf")) { - writer.println(" public List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); - writer.println(" public List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); + writer.println(" public List get" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); + writer.println(" public List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); } else { - writer.println(" public I" + symbol + " get" + symbol + "() { return null; }"); - writer.println(" public List getAll" + symbol + "() { return null; }"); + writer.println( + " public I" + symbol + " get" + symbol + "() { return null; }"); + writer.println(" public List getAll" + symbol + + "() { return null; }"); } } else { switch (num2) { case ONE: if (symbol.endsWith("$Ebnf")) { - writer.println(" public List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return findNotNullChildByClass(IEbnfElement.class).getElements(); }"); - writer.println(" public List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); + writer.println(" public List get" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return findNotNullChildByClass(" + + "IEbnfElement.class).getElements(); }"); + writer.println(" public List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); } else { - writer.println(" public I" + symbol + " get" + symbol + "() { return findNotNullChildByClass(I" + symbol + ".class); }"); - writer.println(" public List getAll" + symbol + "() { return null; }"); + writer.println(" public I" + symbol + " get" + symbol + + "() { return findNotNullChildByClass(I" + symbol + + ".class); }"); + writer.println(" public List getAll" + symbol + + "() { return null; }"); } break; case MORE_THAN_ONE: case ONE_AND_MORE: if (symbol.endsWith("$Ebnf")) { - writer.println(" public List get" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() { return null; }"); - writer.println(" public List> getAll" + symbol.substring(0, symbol.lastIndexOf("$")) + "List() {"); - writer.println(" List> result = new ArrayList<>();"); - writer.println(" for (IEbnfElement e : PsiTreeUtil.getChildrenOfTypeAsList(this, IEbnfElement.class))"); + writer.println(" public List get" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() { return null; }"); + writer.println(" public List> getAll" + + symbol.substring(0, symbol.lastIndexOf("$")) + + "List() {"); + writer.println( + " List> result = new ArrayList<>();"); + writer.println( + " for (IEbnfElement e : " + + "PsiTreeUtil.getChildrenOfTypeAsList(this, " + + "IEbnfElement.class))"); writer.println(" result.add(e.getElements());"); writer.println(" return result;"); writer.println(" }"); } else { - writer.println(" public I" + symbol + " get" + symbol + "() { return null; }"); - writer.println(" public List getAll" + symbol + "() { return PsiTreeUtil.getChildrenOfTypeAsList(this, I" + symbol + ".class); }"); + writer.println(" public I" + symbol + " get" + symbol + + "() { return null; }"); + writer.println(" public List getAll" + symbol + + "() { return PsiTreeUtil.getChildrenOfTypeAsList" + + "(this, I" + + symbol + ".class); }"); } break; } @@ -641,8 +711,10 @@ else if (reference) writer.println(); writer.println(" public String getName() { return getResult().getText(); }"); writer.println(); - writer.println(" public PsiElement setName(String name) throws IncorrectOperationException {"); - writer.println(" ASTNode node = " + language + "ElementFactory.create" + head.substring(0, head.length() - 12) + "(getProject(), name);"); + writer.println( + " public PsiElement setName(String name) throws IncorrectOperationException {"); + writer.println(" ASTNode node = " + language + "ElementFactory.create" + + head.substring(0, head.length() - 12) + "(getProject(), name);"); writer.println(" ASTNode first = getResult().getFirstChildNode();"); writer.println(" getResult().replaceChild(first, node);"); writer.println(" return this;"); @@ -651,32 +723,43 @@ else if (reference) if (reference) { writer.println(); - writer.println(" public PsiReference[] getReferences() { return new PsiReference[] {this}; }"); + writer.println( + " public PsiReference[] getReferences() { return new PsiReference[] {this}; }"); writer.println(); writer.println(" public PsiReference getReference() { return this; }"); writer.println(); writer.println(" public PsiElement getElement() { return this; }"); writer.println(); - writer.println(" public TextRange getRangeInElement() { return new TextRange(0, getTextLength()); }"); + writer.println( + " public TextRange getRangeInElement() { return new TextRange(0, " + + "getTextLength()); }"); writer.println(); writer.println(" public PsiElement resolve() {"); - writer.println(" PsiElement element = " + language + "Util.find" + head.substring(0, head.length() - 10) + "(getProject(), this);"); + writer.println(" PsiElement element = " + language + "Util.find" + + head.substring(0, head.length() - 10) + "(getProject(), this);"); writer.println(" return element;"); writer.println(" }"); writer.println(); writer.println(" public String getCanonicalText() { return this.getText(); }"); writer.println(); - writer.println(" public PsiElement handleElementRename(String name) throws IncorrectOperationException {"); - writer.println(" ASTNode node = " + language + "ElementFactory.create" + head.substring(0, head.length() - 10) + "(getProject(), name);"); + writer.println( + " public PsiElement handleElementRename(String name) throws " + + "IncorrectOperationException {"); + writer.println(" ASTNode node = " + language + "ElementFactory.create" + + head.substring(0, head.length() - 10) + "(getProject(), name);"); writer.println(" ASTNode first = getResult().getFirstChildNode();"); writer.println(" getResult().replaceChild(first, node);"); writer.println(" return this;"); writer.println(" }"); writer.println(); - writer.println(" public PsiElement bindToElement(PsiElement element) throws IncorrectOperationException { return null; }"); + writer.println( + " public PsiElement bindToElement(PsiElement element) throws " + + "IncorrectOperationException { return null; }"); writer.println(); writer.println(" public boolean isReferenceTo(PsiElement element) {"); - writer.println(" return element instanceof " + head.substring(0, head.length() - 10) + "$DeclarationImpl"); + writer.println( + " return element instanceof " + head.substring(0, head.length() - 10) + + "$DeclarationImpl"); writer.println(" && element.getTextLength() == this.getTextLength()"); writer.println(" && element.getText().equals(this.getText());"); writer.println(" }"); diff --git a/src/org/iguana/traversal/idea/GenerateJFlex.java b/src/org/iguana/traversal/idea/GenerateJFlex.java index d62a53cba..8e013fca1 100644 --- a/src/org/iguana/traversal/idea/GenerateJFlex.java +++ b/src/org/iguana/traversal/idea/GenerateJFlex.java @@ -66,7 +66,12 @@ class GenerateJFlex implements RegularExpressionVisitor { private final StringBuffer rules; private final StringBuffer tokens; - public GenerateJFlex(String language, String path, Map regularExpressions, Set seenTokenTypes) { + public GenerateJFlex( + String language, + String path, + Map regularExpressions, + Set seenTokenTypes + ) { this.language = language; this.path = path; this.regularExpressions = regularExpressions; @@ -99,13 +104,13 @@ public void generate() { seenTokenTypes.add("Keyword"); tokens.append(" IElementType Keyword = new " + language + "TokenType(\"Keyword\");") - .append("\n"); + .append("\n"); regularExpressions.entrySet().stream() .filter(entry -> entry.getKey().startsWith("|keyword|:")) .forEach(entry -> { String regex = entry.getValue().accept(this); rules.append(regex + getLookaheads(entry.getValue().getLookaheads())) - .append("\t{ return " + language + "TokenTypes.Keyword; }").append("\n"); + .append("\t{ return " + language + "TokenTypes.Keyword; }").append("\n"); }); regularExpressions.entrySet().stream() @@ -115,13 +120,15 @@ public void generate() { if (!seenTokenTypes.contains(tokenType)) { seenTokenTypes.add(tokenType); - tokens.append(" IElementType " + tokenType + " = new " + language + "TokenType(\"" + tokenType + "\");") - .append("\n"); + tokens.append( + " IElementType " + tokenType + " = new " + language + "TokenType(\"" + tokenType + + "\");") + .append("\n"); } macros.append(tokenType + "=" + entry.getValue().accept(this)).append("\n"); rules.append("{" + tokenType + "} " + getLookaheads(entry.getValue().getLookaheads())) - .append("\t{ return " + language + "TokenTypes." + tokenType + "; }").append("\n"); + .append("\t{ return " + language + "TokenTypes." + tokenType + "; }").append("\n"); }); regularExpressions.entrySet().stream() @@ -132,12 +139,14 @@ public void generate() { if (!seenTokenTypes.contains(tokenType)) { seenTokenTypes.add(tokenType); - tokens.append(" IElementType " + tokenType + " = new " + language + "TokenType(\"" + tokenType + "\");") - .append("\n"); + tokens.append( + " IElementType " + tokenType + " = new " + language + "TokenType(\"" + tokenType + + "\");") + .append("\n"); } rules.append(regex + getLookaheads(entry.getValue().getLookaheads())) - .append("\t{ return " + language + "TokenTypes." + tokenType + "; }").append("\n"); + .append("\t{ return " + language + "TokenTypes." + tokenType + "; }").append("\n"); }); rules.append("[^]").append("\t { return " + language + "TokenTypes.BAD_CHARACTER; }\n"); @@ -232,7 +241,7 @@ public String visit(Char c) { @Override public String visit(org.iguana.regex.CharRange r) { - return "[" + getRange(r) + "]"; + return "[" + getRange(r) + "]"; } @Override @@ -252,14 +261,15 @@ public String visit(org.iguana.regex.Opt o) { @Override public String visit(org.iguana.regex.Alt symbol) { - Map> parition = symbol.getSymbols().stream().collect(Collectors.partitioningBy(s -> isCharClass(s))); + Map> parition = symbol.getSymbols().stream().collect( + Collectors.partitioningBy(s -> isCharClass(s))); List charClasses = parition.get(true); List other = parition.get(false); StringBuilder sb = new StringBuilder(); if (!charClasses.isEmpty() && !other.isEmpty()) { - int left = charClasses.size(); + int left = charClasses.size(); int right = other.stream().map(s -> (RegularExpression) s).mapToInt(r -> r.length()).max().getAsInt(); sb.append("("); @@ -268,17 +278,17 @@ public String visit(org.iguana.regex.Alt symbol sb.append("|"); sb.append(other.stream().map(s -> s.accept(this)).collect(Collectors.joining("|"))); } else { - sb.append(other.stream().sorted(RegularExpression.lengthComparator()).map(s -> s.accept(this)).collect(Collectors.joining("|"))); + sb.append(other.stream().sorted(RegularExpression.lengthComparator()).map(s -> s.accept(this)) + .collect(Collectors.joining("|"))); sb.append("|"); sb.append("[" + charClasses.stream().map(s -> asCharClass(s)).collect(Collectors.joining()) + "]"); } sb.append(")"); - } - else if (!charClasses.isEmpty()) { + } else if (!charClasses.isEmpty()) { sb.append("[" + charClasses.stream().map(s -> asCharClass(s)).collect(Collectors.joining()) + "]"); - } - else { - sb.append("(" + other.stream().sorted(RegularExpression.lengthComparator()).map(s -> s.accept(this)).collect(Collectors.joining("|")) + ")"); + } else { + sb.append("(" + other.stream().sorted(RegularExpression.lengthComparator()).map(s -> s.accept(this)) + .collect(Collectors.joining("|")) + ")"); } return sb.toString(); @@ -309,8 +319,7 @@ private String asCharClass(RegularExpression s) { if (s instanceof Char) { Char c = (Char) s; return getChar(c.getValue()); - } - else if (s instanceof org.iguana.regex.CharRange) { + } else if (s instanceof org.iguana.regex.CharRange) { org.iguana.regex.CharRange r = (org.iguana.regex.CharRange) s; return getRange(r); } @@ -320,20 +329,34 @@ else if (s instanceof org.iguana.regex.CharRange) { private String getTokenType(String terminal) { switch (terminal) { - case "[\\(]": return "OPEN_PARENTHESIS"; - case "[\\)]": return "CLOSE_PARENTHESIS"; - case "[\\[]": return "OPEN_BRACKET"; - case "[\\]]": return "CLOSE_BRACKET"; - case "[\\{]": return "OPEN_BRACE"; - case "[\\}]": return "CLOSE_BRACE"; - case "\\*]": return "OPERATOR"; - case "[/]": return "OPERATOR"; - case "[\\+]": return "OPERATOR"; - case "[\\-]": return "OPERATOR"; - case "[&]": return "OPERATOR"; - case "[\\|]": return "OPERATOR"; - case "[=]": return "OPERATOR"; - default: return "TERMINAL"; + case "[\\(]": + return "OPEN_PARENTHESIS"; + case "[\\)]": + return "CLOSE_PARENTHESIS"; + case "[\\[]": + return "OPEN_BRACKET"; + case "[\\]]": + return "CLOSE_BRACKET"; + case "[\\{]": + return "OPEN_BRACE"; + case "[\\}]": + return "CLOSE_BRACE"; + case "\\*]": + return "OPERATOR"; + case "[/]": + return "OPERATOR"; + case "[\\+]": + return "OPERATOR"; + case "[\\-]": + return "OPERATOR"; + case "[&]": + return "OPERATOR"; + case "[\\|]": + return "OPERATOR"; + case "[=]": + return "OPERATOR"; + default: + return "TERMINAL"; } } @@ -359,7 +382,8 @@ private String getCondition(Condition condition) { return "/!(" + getRegularExpression(condition).accept(this) + ")"; case FOLLOW: return "/(" + getRegularExpression(condition).accept(this) + ")"; - default: return ""; + default: + return ""; } } diff --git a/src/org/iguana/traversal/idea/GenerateParser.java b/src/org/iguana/traversal/idea/GenerateParser.java index ab1a19589..e8e5a26e6 100644 --- a/src/org/iguana/traversal/idea/GenerateParser.java +++ b/src/org/iguana/traversal/idea/GenerateParser.java @@ -79,8 +79,12 @@ public static void generate(String language, String path) { writer.println(" public ASTNode getParserTree(IElementType root, PsiBuilder builder) {"); writer.println(" Input input = Input.fromString(builder.getOriginalText().toString());"); writer.println(" if (graph == null) {"); - writer.println(" grammar = Grammar.load(this.getClass().getClassLoader().getResourceAsStream(\"" + language.toLowerCase() + "/gen/parser/grammar/" + language + "\"));"); - writer.println(" DesugarPrecedenceAndAssociativity precedenceAndAssociativity = new DesugarPrecedenceAndAssociativity();"); + writer.println( + " grammar = Grammar.load(this.getClass().getClassLoader().getResourceAsStream(\"" + + language.toLowerCase() + "/gen/parser/grammar/" + language + "\"));"); + writer.println( + " DesugarPrecedenceAndAssociativity precedenceAndAssociativity = " + + "new DesugarPrecedenceAndAssociativity();"); writer.println(" precedenceAndAssociativity.setOP2();"); writer.println(" grammar = new EBNFToBNF().transform(grammar);"); writer.println(" grammar = precedenceAndAssociativity.transform(grammar);"); @@ -93,11 +97,13 @@ public static void generate(String language, String path) { writer.println(" if (result.isParseSuccess()) {"); writer.println(" System.out.println(\"Success...\");"); writer.println(" NonterminalNode sppf = result.asParseSuccess().getResult();"); - writer.println(" ASTNode ast = SPPFToTerms.convertNoSharing(sppf, new " + language + "TermBuilder());"); + writer.println( + " ASTNode ast = SPPFToTerms.convertNoSharing(sppf, new " + language + "TermBuilder());"); writer.println(" return ast;"); writer.println(" } else {"); writer.println(" System.out.println(\"Parse error...\");"); - writer.println(" return Factory.createErrorElement(\"Sorry, you have a getParserTree error.\");"); + writer.println( + " return Factory.createErrorElement(\"Sorry, you have a getParserTree error.\");"); writer.println(" }"); writer.println(" }"); writer.println("}"); @@ -135,11 +141,14 @@ public static void generate(String language, String path) { writer.println(); writer.println("public class " + language + "ParserDefinition implements ParserDefinition {"); writer.println(); - writer.println(" public static final IFileElementType FILE = new IFileElementType(Language.<" + language + "Lang>findInstance(" + language + "Lang.class));"); + writer.println( + " public static final IFileElementType FILE = new IFileElementType(Language.<" + language + + "Lang>findInstance(" + language + "Lang.class));"); writer.println(); writer.println(" public Lexer createLexer(Project project) { return new " + language + "Lexer(); }"); writer.println(); - writer.println(" public PsiParser createParser(Project project) { return new " + language + "Parser(); }"); + writer.println( + " public PsiParser createParser(Project project) { return new " + language + "Parser(); }"); writer.println(); writer.println(" public IFileElementType getFileNodeType() { return FILE; }"); writer.println(); @@ -149,7 +158,8 @@ public static void generate(String language, String path) { writer.println(); writer.println(" public TokenSet getStringLiteralElements() { return TokenSet.EMPTY; }"); writer.println(); - writer.println(" public PsiElement createElement(ASTNode node) { return " + language + "ElementTypes.Factory.createElement(node); }"); + writer.println(" public PsiElement createElement(ASTNode node) { return " + language + + "ElementTypes.Factory.createElement(node); }"); writer.println(); writer.println(" public PsiFile createFile(FileViewProvider viewProvider) {"); writer.println(" " + language + "File file = new " + language + "File(viewProvider);"); @@ -157,7 +167,9 @@ public static void generate(String language, String path) { writer.println(" return file;"); writer.println(" }"); writer.println(); - writer.println(" public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { return SpaceRequirements.MAY; }"); + writer.println( + " public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) " + + "{ return SpaceRequirements.MAY; }"); writer.println("}"); writer.close(); } catch (FileNotFoundException e) { @@ -179,7 +191,9 @@ public static void generate(String language, String path) { writer.println("import javax.swing.Icon;"); writer.println(); writer.println("public class " + language + "File extends PsiFileBase {"); - writer.println(" public " + language + "File(FileViewProvider viewProvider) { super(viewProvider, " + language + "Lang.instance); }"); + writer.println( + " public " + language + "File(FileViewProvider viewProvider) { super(viewProvider, " + language + + "Lang.instance); }"); writer.println(" public FileType getFileType() { return " + language + "FileType.instance; }"); writer.println(" public String toString() { return \"" + language + " file\"; }"); writer.println(" public Icon getIcon(int flags) { return super.getIcon(flags); }"); diff --git a/src/org/iguana/traversal/idea/GenerateTermBuilder.java b/src/org/iguana/traversal/idea/GenerateTermBuilder.java index 7fea73575..64109a960 100644 --- a/src/org/iguana/traversal/idea/GenerateTermBuilder.java +++ b/src/org/iguana/traversal/idea/GenerateTermBuilder.java @@ -73,26 +73,39 @@ public static void generate(String language, String path) { writer.println(" }"); writer.println(); writer.println(" @Override"); - writer.println(" public TreeElement nonterminalTerm(RuleType type, Seq children, int l, int r, Input input) {"); + writer.println( + " public TreeElement nonterminalTerm(RuleType type, Seq children, int l, int r," + + " Input input) {"); writer.println(" Rule rule = (Rule) type;"); - writer.println(" String name = rule.getHead().getName().toUpperCase() + (rule.getLabel() == null? \"\" : \"_\" + rule.getLabel().toUpperCase());"); - writer.println(" CompositeElement node = ASTFactory.composite(" + language + "ElementTypes.get(name));"); + writer.println( + " String name = rule.getHead().getName().toUpperCase() + (rule.getLabel() == " + + "null? \"\" : \"_\" + " + + "rule.getLabel().toUpperCase());"); + writer.println( + " CompositeElement node = ASTFactory.composite(" + language + "ElementTypes.get(name));"); writer.println(" Iterator iterator = children.iterator();"); - writer.println(" while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); + writer.println( + " while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); writer.println(" return node;"); writer.println(" }"); writer.println(); writer.println(" @Override"); - writer.println(" public TreeElement ambiguityTerm(scala.collection.Seq> children) { throw new RuntimeException(\"Not yet supported in the idea tree builder: ambiguity.\"); }"); + writer.println( + " public TreeElement ambiguityTerm(scala.collection.Seq> " + + "children) { throw new RuntimeException(\"Not yet supported in the idea tree builder" + + ": ambiguity.\"); }"); writer.println(); writer.println(" @Override"); - writer.println(" public TreeElement cycle(String label) { throw new RuntimeException(\"Not yet supported in the idea tree builder: cycles.\"); }"); + writer.println( + " public TreeElement cycle(String label) { throw new RuntimeException(\"Not yet supported in " + + "the idea tree builder: cycles.\"); }"); writer.println(); writer.println(" @Override"); writer.println(" public TreeElement star(Seq children) {"); writer.println(" CompositeElement node = ASTFactory.composite(" + language + "ElementTypes.LIST);"); writer.println(" Iterator iterator = children.iterator();"); - writer.println(" while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); + writer.println( + " while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); writer.println(" return node;"); writer.println(" }"); writer.println(); @@ -110,7 +123,8 @@ public static void generate(String language, String path) { writer.println(" public TreeElement group(Seq children) {"); writer.println(" CompositeElement node = ASTFactory.composite(" + language + "ElementTypes.SEQ);"); writer.println(" Iterator iterator = children.iterator();"); - writer.println(" while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); + writer.println( + " while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); writer.println(" return node;"); writer.println(" }"); writer.println(); @@ -118,12 +132,14 @@ public static void generate(String language, String path) { writer.println(" public TreeElement alt(Seq children) {"); writer.println(" CompositeElement node = ASTFactory.composite(" + language + "ElementTypes.ALT);"); writer.println(" Iterator iterator = children.iterator();"); - writer.println(" while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); + writer.println( + " while (iterator.hasNext()) node.rawAddChildrenWithoutNotifications(iterator.next());"); writer.println(" return node;"); writer.println(" }"); writer.println(); writer.println(" @Override"); - writer.println(" public TreeElement epsilon(int i) { return ASTFactory.leaf(" + language + "TokenTypes.TERMINAL, \"\"); }"); + writer.println(" public TreeElement epsilon(int i) { return ASTFactory.leaf(" + language + + "TokenTypes.TERMINAL, \"\"); }"); writer.println("}"); writer.close(); } catch (FileNotFoundException e) { diff --git a/src/org/iguana/traversal/idea/Names.java b/src/org/iguana/traversal/idea/Names.java index 0ad0815fd..a5028567e 100644 --- a/src/org/iguana/traversal/idea/Names.java +++ b/src/org/iguana/traversal/idea/Names.java @@ -123,7 +123,8 @@ public Symbol visit(IfThen symbol) { @Override public Symbol visit(IfThenElse symbol) { - return IfThenElse.ifThenElse(symbol.getExpression(), visitSymbol(symbol.getThenPart()), visitSymbol(symbol.getElsePart())); + return IfThenElse.ifThenElse(symbol.getExpression(), visitSymbol(symbol.getThenPart()), + visitSymbol(symbol.getElsePart())); } @Override diff --git a/src/org/iguana/util/ParserLogger.java b/src/org/iguana/util/ParserLogger.java index 26002955c..ad537bebb 100644 --- a/src/org/iguana/util/ParserLogger.java +++ b/src/org/iguana/util/ParserLogger.java @@ -115,7 +115,10 @@ public void pop(GSSNode gssNode, int inputIndex, T child, } public void error(ParseError error) { - if (logEnabled) logger.log("Error recorded at %s %d %s", error.getGrammarSlot(), error.getInputIndex(), error.getDescription()); + if (logEnabled) { + logger.log("Error recorded at %s %d %s", error.getGrammarSlot(), error.getInputIndex(), + error.getDescription()); + } } public void processDescriptor(Descriptor descriptor) { diff --git a/src/org/iguana/util/config/XMLConfigFileParser.java b/src/org/iguana/util/config/XMLConfigFileParser.java index 874306e1c..bf2af891f 100644 --- a/src/org/iguana/util/config/XMLConfigFileParser.java +++ b/src/org/iguana/util/config/XMLConfigFileParser.java @@ -57,7 +57,8 @@ private void getParserConfigs(Configuration.Builder builder) { break; case "EnvironmentImpl": - builder.setEnvironmentImpl(Configuration.EnvironmentImpl.valueOf(node.getTextContent().toUpperCase())); + builder.setEnvironmentImpl( + Configuration.EnvironmentImpl.valueOf(node.getTextContent().toUpperCase())); break; } } diff --git a/src/org/iguana/util/serialization/JsonSerializer.java b/src/org/iguana/util/serialization/JsonSerializer.java index b086a6c8d..7ef0772ea 100644 --- a/src/org/iguana/util/serialization/JsonSerializer.java +++ b/src/org/iguana/util/serialization/JsonSerializer.java @@ -756,7 +756,8 @@ abstract static class ContainsMixIn { abstract static class PPDeclareMixIn { @JsonCreator - PPDeclareMixIn(@JsonProperty("variable") Expression variable, @JsonProperty("value") Expression value) { } + PPDeclareMixIn(@JsonProperty("variable") Expression variable, @JsonProperty("value") Expression value) { + } } abstract static class Put3MixIn { @@ -776,7 +777,12 @@ abstract static class MapMixIn { abstract static class Pr2MixIn { @JsonCreator - Pr2MixIn(@JsonProperty("arg1") Expression arg1, @JsonProperty("arg2") Expression arg2, @JsonProperty("arg3") Expression[] arg3) { } + Pr2MixIn( + @JsonProperty("arg1") Expression arg1, + @JsonProperty("arg2") Expression arg2, + @JsonProperty("arg3") Expression[] arg3 + ) { + } } abstract static class Pr3MixIn { diff --git a/src/org/iguana/util/visualization/GrammarGraphToDot.java b/src/org/iguana/util/visualization/GrammarGraphToDot.java index 307cfff19..583fa57a4 100644 --- a/src/org/iguana/util/visualization/GrammarGraphToDot.java +++ b/src/org/iguana/util/visualization/GrammarGraphToDot.java @@ -72,7 +72,8 @@ private static void toDot(NonterminalGrammarSlot slot, DotGraph dotGraph, Set exclude) { @Override public Integer visitNonterminalNode(NonterminalNode node) { int id = nextId(); - String label = String.format("(%s, %d, %d)", node.getGrammarDefinition().getHead().getName(), node.getStart(), node.getEnd()); + String label = String.format("(%s, %d, %d)", node.getGrammarDefinition().getHead().getName(), node.getStart(), + node.getEnd()); dotGraph.addNode(newNode(id, label)); visitChildren(node, id); @@ -97,7 +98,8 @@ public Integer visitTerminalNode(TerminalNode node) { if (exclude.contains(node.getGrammarDefinition().getName())) return null; String text = input.subString(node.getStart(), node.getEnd()); - String label = String.format("(%s, %d, %d): \"%s\"", node.getGrammarDefinition().getName(), node.getStart(), node.getEnd(), text); + String label = String.format("(%s, %d, %d): \"%s\"", node.getGrammarDefinition().getName(), node.getStart(), + node.getEnd(), text); int id = nextId(); dotGraph.addNode(newNode(id, label).setShape(DotGraph.Shape.ROUNDED_RECTANGLE)); return id; diff --git a/src/org/iguana/util/visualization/SPPFToDot.java b/src/org/iguana/util/visualization/SPPFToDot.java index ce6a02972..b17d68e0a 100644 --- a/src/org/iguana/util/visualization/SPPFToDot.java +++ b/src/org/iguana/util/visualization/SPPFToDot.java @@ -42,13 +42,13 @@ public class SPPFToDot implements SPPFVisitor { private final boolean showPackedNodeLabel; - private Map ids = new HashMap<>(); + private final Map ids = new HashMap<>(); - private DotGraph dotGraph; + private final DotGraph dotGraph; protected Input input; - private Set visited = new HashSet<>(); + private final Set visited = new HashSet<>(); public static DotGraph getDotGraph(SPPFNode root, Input input) { return getDotGraph(root, input, false); @@ -72,7 +72,8 @@ public Void visit(TerminalNode node) { if (!visited.contains(node)) { visited.add(node); String matchedInput = input.subString(node.getLeftExtent(), node.getRightExtent()); - String label = String.format("(%s, %d, %d): \"%s\"", node.getGrammarSlot(), node.getLeftExtent(), node.getRightExtent(), matchedInput); + String label = String.format("(%s, %d, %d): \"%s\"", node.getGrammarSlot(), node.getLeftExtent(), + node.getRightExtent(), matchedInput); dotGraph.addNode(newNode(getId(node), label)); } @@ -86,13 +87,16 @@ public Void visit(NonterminalNode node) { String label; if (node.getValue() == null) - label = String.format("(%s, %d, %d)", node.getGrammarSlot(), node.getLeftExtent(), node.getRightExtent()); + label = String.format("(%s, %d, %d)", node.getGrammarSlot(), node.getLeftExtent(), + node.getRightExtent()); else { if (node.getValue() instanceof List) - label = String.format("(%s, %d, %d, %s)", node.getGrammarSlot(), node.getLeftExtent(), node.getRightExtent(), - "(" + listToString((List) node.getValue(), ",") + ")"); + label = String.format("(%s, %d, %d, %s)", node.getGrammarSlot(), node.getLeftExtent(), + node.getRightExtent(), + "(" + listToString((List) node.getValue(), ",") + ")"); else - label = String.format("(%s, %d, %d, %s)", node.getGrammarSlot(), node.getLeftExtent(), node.getRightExtent(), node.getValue()); + label = String.format("(%s, %d, %d, %s)", node.getGrammarSlot(), node.getLeftExtent(), + node.getRightExtent(), node.getValue()); } DotGraph.Node dotNode = newNode(getId(node), label); @@ -111,8 +115,9 @@ public Void visit(NonterminalNode node) { public Void visit(IntermediateNode node) { if (!visited.contains(node)) { visited.add(node); - - String label = String.format("(%s, %d, %d)", node.getGrammarSlot(), node.getLeftExtent(), node.getRightExtent()); + + String label = String.format("(%s, %d, %d)", node.getGrammarSlot(), node.getLeftExtent(), + node.getRightExtent()); DotGraph.Node dotNode = newNode(getId(node), label).setShape(DotGraph.Shape.RECTANGLE); if (node.isAmbiguous()) { @@ -145,7 +150,8 @@ public Void visit(ErrorNode node) { if (!visited.contains(node)) { visited.add(node); String matchedInput = input.subString(node.getLeftExtent(), node.getRightExtent()); - String label = String.format("(Error, %d, %d): \"%s\"", node.getLeftExtent(), node.getRightExtent(), matchedInput); + String label = String.format("(Error, %d, %d): \"%s\"", node.getLeftExtent(), node.getRightExtent(), + matchedInput); dotGraph.addNode(newNode(getId(node), label)); } diff --git a/src/org/iguana/utils/collections/CollectionsUtil.java b/src/org/iguana/utils/collections/CollectionsUtil.java index 7486d1676..8a047abf1 100644 --- a/src/org/iguana/utils/collections/CollectionsUtil.java +++ b/src/org/iguana/utils/collections/CollectionsUtil.java @@ -73,8 +73,9 @@ public static Map map(List> mappings) { return mappings.stream().collect(Collectors.toMap(t -> t.getFirst(), t -> t.getSecond())); } - public static Map map(List keys, List values) { - return zip(keys.stream(), values.stream(), (k, v) -> tuple(k, v)).collect(Collectors.toMap(t -> t.getFirst(), t -> t.getSecond())); + public static Map map(List keys, List values) { + return zip(keys.stream(), values.stream(), (k, v) -> tuple(k, v)).collect( + Collectors.toMap(t -> t.getFirst(), t -> t.getSecond())); } public static Stream zip(Stream as, Stream bs, BiFunction f) { @@ -117,7 +118,10 @@ public static T last(List list) { return list.get(list.size() - 1); } - public static boolean isEqual(org.iguana.utils.collections.primitive.IntIterable iterables1, IntIterable iterables2) { + public static boolean isEqual( + org.iguana.utils.collections.primitive.IntIterable iterables1, + IntIterable iterables2 + ) { org.iguana.utils.collections.primitive.IntIterator it1 = iterables1.iterator(); IntIterator it2 = iterables2.iterator(); while (it1.hasNext()) { diff --git a/src/org/iguana/utils/collections/Keys.java b/src/org/iguana/utils/collections/Keys.java index 3e3c2eab8..e0de78fe7 100644 --- a/src/org/iguana/utils/collections/Keys.java +++ b/src/org/iguana/utils/collections/Keys.java @@ -1,59 +1,69 @@ package org.iguana.utils.collections; import org.iguana.utils.collections.hash.MurmurHash3; -import org.iguana.utils.collections.key.ObjectKeyN; +import org.iguana.utils.collections.key.*; import org.iguana.utils.function.IntFunction3; import org.iguana.utils.function.IntFunction4; public class Keys { - public static org.iguana.utils.collections.key.Key from(int a, int b) { + public static Key from(int a, int b) { return from(a, b); } - public static org.iguana.utils.collections.key.Key from(int a) { return new org.iguana.utils.collections.key.IntKey1(a); } + public static Key from(int a) { + return new IntKey1(a); + } - public static org.iguana.utils.collections.key.Key from(int a, Object o) { return new org.iguana.utils.collections.key.IntObjectKey(a, o); } + public static Key from(int a, Object o) { + return new IntObjectKey(a, o); + } - public static org.iguana.utils.collections.key.Key from(int a, Object[] objects) { return new org.iguana.utils.collections.key.IntArrayKey(a, objects); } + public static Key from(int a, Object[] objects) { + return new IntArrayKey(a, objects); + } - public static org.iguana.utils.collections.key.Key from(int a, int b, Object object) { return new org.iguana.utils.collections.key.IntIntObjectKey(a, b, object); } + public static Key from(int a, int b, Object object) { + return new IntIntObjectKey(a, b, object); + } - public static org.iguana.utils.collections.key.Key from(int a, int b, int c, Object object) { return new org.iguana.utils.collections.key.IntIntIntObjectKey(a, b, c, object); } + public static Key from(int a, int b, int c, Object object) { + return new IntIntIntObjectKey(a, b, c, object); + } - public static org.iguana.utils.collections.key.Key from(Object a, Object b) { - return new org.iguana.utils.collections.key.ObjectKey2(a, b, org.iguana.utils.collections.hash.MurmurHash3.f2().apply(a, b)); + public static Key from(Object a, Object b) { + return new ObjectKey2(a, b, MurmurHash3.f2().apply(a, b)); } - public static org.iguana.utils.collections.key.Key from(int a, int b, int c) { - return from(org.iguana.utils.collections.hash.MurmurHash3.f3(), a, b, c); + public static Key from(int a, int b, int c) { + return from(MurmurHash3.f3(), a, b, c); } - public static org.iguana.utils.collections.key.Key from(org.iguana.utils.function.IntFunction3 f, int a, int b, int c) { - return new org.iguana.utils.collections.key.IntKey3(a, b, c, f.apply(a, b, c)); + public static Key from(IntFunction3 f, int a, int b, int c) { + return new IntKey3(a, b, c, f.apply(a, b, c)); } - public static org.iguana.utils.collections.key.Key from(Object a, Object b, Object c) { - return from(org.iguana.utils.collections.hash.MurmurHash3.f3(), a, b, c); + public static Key from(Object a, Object b, Object c) { + return from(MurmurHash3.f3(), a, b, c); } - public static org.iguana.utils.collections.key.Key from(IntFunction3 f, Object a, Object b, Object c) { - return new org.iguana.utils.collections.key.ObjectKey3(a, b, c, f.apply(a, b, c)); + public static Key from(IntFunction3 f, Object a, Object b, Object c) { + return new ObjectKey3(a, b, c, f.apply(a, b, c)); } - public static org.iguana.utils.collections.key.Key from(int a, int b, int c, int d) { - return from(org.iguana.utils.collections.hash.MurmurHash3.f4(), a, b, c, d); + public static Key from(int a, int b, int c, int d) { + return from(MurmurHash3.f4(), a, b, c, d); } - public static org.iguana.utils.collections.key.Key from(org.iguana.utils.function.IntFunction4 f, int a, int b, int c, int d) { - return new org.iguana.utils.collections.key.IntKey4(a, b, c, d, f.apply(a, b, c, d)); + public static Key from(org.iguana.utils.function.IntFunction4 f, int a, int b, int c, int d) { + return new IntKey4(a, b, c, d, f.apply(a, b, c, d)); } - public static org.iguana.utils.collections.key.Key from(IntFunction4 f, Object a, Object b, Object c, Object d) { - return new org.iguana.utils.collections.key.ObjectKey4(a, b, c, d, f.apply(a, b, c, d)); + public static Key from(IntFunction4 f, Object a, Object b, Object c, Object d) { + return new ObjectKey4(a, b, c, d, f.apply(a, b, c, d)); } - public static org.iguana.utils.collections.key.Key from(Object...elements) { + public static Key from(Object...elements) { return new ObjectKeyN(MurmurHash3.fn(), elements); } diff --git a/src/org/iguana/utils/input/AbstractInput.java b/src/org/iguana/utils/input/AbstractInput.java index 522f8b9f3..146ef4494 100644 --- a/src/org/iguana/utils/input/AbstractInput.java +++ b/src/org/iguana/utils/input/AbstractInput.java @@ -74,7 +74,8 @@ private void checkLineStartsInitialized() { private static void checkBounds(int index, int length) { if (index < 0 || index >= length) { - throw new IndexOutOfBoundsException("index must be greater than or equal to 0 and smaller than the input length (" + length + ")"); + throw new IndexOutOfBoundsException( + "index must be greater than or equal to 0 and smaller than the input length (" + length + ")"); } } } diff --git a/src/org/iguana/utils/visualization/DotGraph.java b/src/org/iguana/utils/visualization/DotGraph.java index 6e7d6143c..bb1993c4e 100644 --- a/src/org/iguana/utils/visualization/DotGraph.java +++ b/src/org/iguana/utils/visualization/DotGraph.java @@ -73,7 +73,11 @@ public void generate(String fileName) throws Exception { } private static String escape(String s) { - return s.replace("\\", "\\\\").replace("\t", "\\\\t").replace("\n", "\\\\n").replace("\r", "\\\\r").replace("\"", "\\\""); + return s.replace("\\", "\\\\") + .replace("\t", "\\\\t") + .replace("\n", "\\\\n") + .replace("\r", "\\\\r") + .replace("\"", "\\\""); } public enum Direction { diff --git a/src/resources/checkstyle.xml b/src/resources/checkstyle.xml index 2ff8f8000..2b7096a12 100644 --- a/src/resources/checkstyle.xml +++ b/src/resources/checkstyle.xml @@ -4,8 +4,15 @@ "https://checkstyle.org/dtds/configuration_1_3.dtd"> + + - \ No newline at end of file + + + + + +