diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigDefinition.java b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigDefinition.java index 50b5f17fc6..7a41fb359d 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigDefinition.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigDefinition.java @@ -12,6 +12,7 @@ import com.rusefi.util.LazyFile; import com.rusefi.util.SystemOut; import org.antlr.v4.runtime.*; import org.antlr.v4.runtime.tree.ParseTree; +import org.antlr.v4.runtime.tree.ParseTreeListener; import org.antlr.v4.runtime.tree.ParseTreeWalker; import org.yaml.snakeyaml.Yaml; @@ -252,18 +253,18 @@ public class ConfigDefinition { // Parse the input files { - ParseState listener = new ParseState(state.enumsReader); + ParseState parseState = new ParseState(state.enumsReader); // First process yaml files //processYamls(listener, yamlFiles); // Process firing order enum - handleFiringOrder(firingEnumFileName, listener); + handleFiringOrder(firingEnumFileName, parseState); // Load prepend files { // Ignore duplicates of definitions made during prepend phase - listener.setDefinitionPolicy(Definition.OverwritePolicy.IgnoreNew); + parseState.setDefinitionPolicy(Definition.OverwritePolicy.IgnoreNew); //for (String prependFile : prependFiles) { // TODO: fix signature define file parsing @@ -274,8 +275,8 @@ public class ConfigDefinition { // Now load the main config file { // don't allow duplicates in the main file - listener.setDefinitionPolicy(Definition.OverwritePolicy.NotAllowed); - parseFile(listener, definitionInputFile); + parseState.setDefinitionPolicy(Definition.OverwritePolicy.NotAllowed); + parseFile(parseState.getListener(), definitionInputFile); } // Write C structs @@ -635,7 +636,7 @@ public class ConfigDefinition { } } - private static void parseFile(ParseState listener, String filePath) throws IOException { + private static void parseFile(ParseTreeListener listener, String filePath) throws IOException { SystemOut.println("Parsing file (Antlr) " + filePath); CharStream in = new ANTLRInputStream(new FileInputStream(filePath)); diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/ParseState.java b/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/ParseState.java index a091987728..9a16c23de7 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/ParseState.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/ParseState.java @@ -6,6 +6,7 @@ import com.rusefi.generated.RusefiConfigGrammarBaseListener; import com.rusefi.generated.RusefiConfigGrammarParser; import com.rusefi.newparse.parsing.*; import jdk.nashorn.internal.runtime.regexp.joni.constants.StringType; +import org.antlr.v4.runtime.tree.ParseTreeListener; import org.jetbrains.annotations.Nullable; import java.io.PrintStream; @@ -13,13 +14,22 @@ import java.util.*; import java.util.regex.Pattern; import java.util.stream.Collectors; -public class ParseState extends RusefiConfigGrammarBaseListener { +public class ParseState { private final Map definitions = new HashMap<>(); private final Map structs = new HashMap<>(); private final List structList = new ArrayList<>(); private final Map typedefs = new HashMap<>(); + private static final Pattern CHAR_LITERAL = Pattern.compile("'.'"); private final EnumsReader enumsReader; + private Definition.OverwritePolicy definitionOverwritePolicy = Definition.OverwritePolicy.NotAllowed; + + private String typedefName = null; + private final Queue evalResults = new LinkedList<>(); + private Scope scope = null; + private final Stack scopes = new Stack<>(); + + private Struct lastStruct = null; public ParseState(EnumsReader enumsReader) { this.enumsReader = enumsReader; @@ -34,6 +44,10 @@ public class ParseState extends RusefiConfigGrammarBaseListener { } } + public Struct getLastStruct() { + return lastStruct; + } + private String[] resolveEnumValues(String enumName) { TreeMap valueNameById = new TreeMap<>(); @@ -67,32 +81,12 @@ public class ParseState extends RusefiConfigGrammarBaseListener { return structList; } - class Scope { - public List structFields = new ArrayList<>(); - } - - Scope scope = null; - Stack scopes = new Stack<>(); - - @Override - public void exitContent(RusefiConfigGrammarParser.ContentContext ctx) { - assert(this.scopes.empty()); - assert(this.scope == null); - - assert(this.typedefName == null); - - assert(evalResults.isEmpty()); - assert(evalStack.empty()); - } - - private Definition.OverwritePolicy definitionOverwritePolicy = Definition.OverwritePolicy.NotAllowed; - - private void addDefinition(String name, Object value) { - addDefinition(name, value, this.definitionOverwritePolicy); + public Definition findDefinition(String name) { + return definitions.getOrDefault(name, null); } public void addDefinition(String name, Object value, Definition.OverwritePolicy overwritePolicy) { - Definition existingDefinition = this.definitions.getOrDefault(name, null); + Definition existingDefinition = definitions.getOrDefault(name, null); if (existingDefinition != null) { switch (existingDefinition.overwritePolicy) { @@ -109,15 +103,32 @@ public class ParseState extends RusefiConfigGrammarBaseListener { definitions.put(name, new Definition(name, value, overwritePolicy)); } - public Definition findDefinition(String name) { - return this.definitions.getOrDefault(name, null); + private void addDefinition(String name, Object value) { + addDefinition(name, value, definitionOverwritePolicy); } public void setDefinitionPolicy(Definition.OverwritePolicy policy) { this.definitionOverwritePolicy = policy; } - private static final Pattern CHAR_LITERAL = Pattern.compile("'.'"); + public ParseTreeListener getListener() { + return new RusefiConfigGrammarBaseListener() { + + @Override + public void exitContent(RusefiConfigGrammarParser.ContentContext ctx) { + if (!scopes.empty()) + throw new IllegalStateException(); + if (scope != null) + throw new IllegalStateException(); + + if (typedefName != null) + throw new IllegalStateException(); + + if (!evalResults.isEmpty()) + throw new IllegalStateException(); + if (!evalStack.empty()) + throw new IllegalStateException(); + } private void handleIntDefinition(String name, int value) { addDefinition(name, value); @@ -135,7 +146,7 @@ public class ParseState extends RusefiConfigGrammarBaseListener { } else if (ctx.floatNum() != null) { addDefinition(name, Double.parseDouble(ctx.floatNum().getText())); } else if (ctx.numexpr() != null) { - double evalResult = this.evalResults.remove(); + double evalResult = evalResults.remove(); double floored = Math.floor(evalResult); if (Math.abs(floored - evalResult) < 0.001) { @@ -157,16 +168,14 @@ public class ParseState extends RusefiConfigGrammarBaseListener { } } - String typedefName = null; - @Override public void enterTypedef(RusefiConfigGrammarParser.TypedefContext ctx) { - this.typedefName = ctx.identifier().getText(); + typedefName = ctx.identifier().getText(); } @Override public void exitTypedef(RusefiConfigGrammarParser.TypedefContext ctx) { - this.typedefName = null; + typedefName = null; } @Override @@ -176,7 +185,7 @@ public class ParseState extends RusefiConfigGrammarBaseListener { FieldOptions options = new FieldOptions(); handleFieldOptionsList(options, ctx.fieldOptionsList()); - typedefs.put(this.typedefName, new ScalarTypedef(this.typedefName, datatype, options)); + typedefs.put(typedefName, new ScalarTypedef(typedefName, datatype, options)); } @Override @@ -196,7 +205,7 @@ public class ParseState extends RusefiConfigGrammarBaseListener { defName = defName.substring(0, defName.length() - 10); values = resolveEnumValues(defName); } else { - Definition def = this.definitions.get(defName); + Definition def = definitions.get(defName); if (def == null) { throw new RuntimeException("couldn't find definition for " + rhs); @@ -219,7 +228,7 @@ public class ParseState extends RusefiConfigGrammarBaseListener { .toArray(n -> new String[n]); // Convert back to array } - typedefs.put(this.typedefName, new EnumTypedef(this.typedefName, datatype, endBit, values)); + typedefs.put(typedefName, new EnumTypedef(typedefName, datatype, endBit, values)); } @Override @@ -229,14 +238,14 @@ public class ParseState extends RusefiConfigGrammarBaseListener { FieldOptions options = new FieldOptions(); handleFieldOptionsList(options, ctx.fieldOptionsList()); - typedefs.put(this.typedefName, new ArrayTypedef(this.typedefName, this.arrayDim, datatype, options)); + typedefs.put(typedefName, new ArrayTypedef(ParseState.this.typedefName, this.arrayDim, datatype, options)); } @Override public void exitStringTypedefSuffix(RusefiConfigGrammarParser.StringTypedefSuffixContext ctx) { - Double stringLength = this.evalResults.remove(); + Double stringLength = ParseState.this.evalResults.remove(); - this.typedefs.put(this.typedefName, new StringTypedef(this.typedefName, stringLength.intValue())); + ParseState.this.typedefs.put(ParseState.this.typedefName, new StringTypedef(ParseState.this.typedefName, stringLength.intValue())); } @Override @@ -428,14 +437,14 @@ public class ParseState extends RusefiConfigGrammarBaseListener { // iterate required for structs assert(iterate); - scope.structFields.add(new ArrayField(new StructField(structs.get(type), name), length, iterate)); + scope.structFields.add(new ArrayField<>(new StructField(structs.get(type), name), length, iterate)); return; } // Check first if we have a typedef for this type - Typedef typedef = this.typedefs.get(type); + Typedef typedef = typedefs.get(type); - FieldOptions options = null; + FieldOptions options; if (typedef != null) { if (typedef instanceof ScalarTypedef) { ScalarTypedef scTypedef = (ScalarTypedef) typedef; @@ -501,12 +510,6 @@ public class ParseState extends RusefiConfigGrammarBaseListener { scope.structFields.add(new UnusedField(Integer.parseInt(ctx.integer().getText()))); } - private Struct lastStruct = null; - - public Struct getLastStruct() { - return lastStruct; - } - @Override public void exitStruct(RusefiConfigGrammarParser.StructContext ctx) { String structName = ctx.identifier().getText(); @@ -559,12 +562,12 @@ public class ParseState extends RusefiConfigGrammarBaseListener { // Strip any @@ symbols String defName = ctx.getText().replaceAll("@", ""); - if (!this.definitions.containsKey(defName)) { + if (!definitions.containsKey(defName)) { throw new RuntimeException("Definition not found for " + ctx.getText()); } // Find the matching definition and push on to the eval stack - Definition def = this.definitions.get(defName); + Definition def = definitions.get(defName); if (!def.isNumeric()) { throw new RuntimeException("Tried to use symbol " + defName + " in an expression, but it wasn't a number"); @@ -605,11 +608,16 @@ public class ParseState extends RusefiConfigGrammarBaseListener { evalStack.push(left - right); } - private Queue evalResults = new LinkedList<>(); - @Override public void exitNumexpr(RusefiConfigGrammarParser.NumexprContext ctx) { assert(evalStack.size() == 1); evalResults.add(evalStack.pop()); } + + }; + }; + + static class Scope { + public List structFields = new ArrayList<>(); + } } diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/parsing/Type.java b/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/parsing/Type.java index fb9ed17c05..31ebf962bf 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/parsing/Type.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/newparse/parsing/Type.java @@ -27,6 +27,7 @@ public enum Type { } public static Optional findByCtype(String cType) { + // todo: better implementation of type aliases! String cTypeWithAlas = "floatms_t".equals(cType) ? "float" : cType; return Arrays.stream(Type.values()).filter(t -> t.cType.equals(cTypeWithAlas)).findFirst(); }