From 128e53d220d97225803d61d86f8e43439563181d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Tue, 26 Jul 2016 00:22:55 +0200 Subject: WIP: kicad_gen is a util to generate schematic.h files from KiCAD netlist files. Current code contains a lexer and parser for KiCAD's netlist files and code to build a tree of the netlist which can be used for generation. Contains CMake code for integrating the generation into CMake too. --- java/pom.xml | 87 ++++++ .../io/trygvis/ld/CollectingErrorListener.java | 17 ++ .../java/io/trygvis/ld/ElfinfoExprVisitor.java | 318 +++++++++++++++++++++ .../java/io/trygvis/ld/ElfinfoGnuLdListener.java | 170 +++++++++++ .../java/io/trygvis/ld/ElfinfoGnuLdVisitor.java | 75 +++++ java/src/main/java/io/trygvis/ld/LdLoader.java | 121 ++++++++ .../java/io/trygvis/ld/StringGnuLdVisitor.java | 59 ++++ 7 files changed, 847 insertions(+) create mode 100644 java/pom.xml create mode 100644 java/src/main/java/io/trygvis/ld/CollectingErrorListener.java create mode 100644 java/src/main/java/io/trygvis/ld/ElfinfoExprVisitor.java create mode 100644 java/src/main/java/io/trygvis/ld/ElfinfoGnuLdListener.java create mode 100644 java/src/main/java/io/trygvis/ld/ElfinfoGnuLdVisitor.java create mode 100644 java/src/main/java/io/trygvis/ld/LdLoader.java create mode 100644 java/src/main/java/io/trygvis/ld/StringGnuLdVisitor.java (limited to 'java') diff --git a/java/pom.xml b/java/pom.xml new file mode 100644 index 0000000..4821b17 --- /dev/null +++ b/java/pom.xml @@ -0,0 +1,87 @@ + + 4.0.0 + io.trygvis.kicad + kicad-utils + 1.0-SNAPSHOT + + + org.antlr + antlr4 + ${antlr4-runtime.version} + + + org.antlr + antlr4-runtime + ${antlr4-runtime.version} + + + com.google.code.findbugs + jsr305 + 3.0.1 + + + junit + junit + 4.12 + test + + + + 4.5.3 + + + + + maven-compiler-plugin + + 1.8 + 1.8 + + + + org.antlr + antlr4-maven-plugin + ${antlr4-runtime.version} + + + gnu + + antlr4 + + + + -package + io.trygvis.ld.antlr + + + GnuLd*.g4 + + . + target/generated-sources/antlr4/io/trygvis/ld/antlr + + + + test1 + + antlr4 + + + + -package + io.trygvis.ld.test1 + + + **/Test1*.g4 + + target/generated-sources/antlr4/io/trygvis/ld/test1 + + + + + true + target/generated-sources/antlr4 + + + + + diff --git a/java/src/main/java/io/trygvis/ld/CollectingErrorListener.java b/java/src/main/java/io/trygvis/ld/CollectingErrorListener.java new file mode 100644 index 0000000..968a02b --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/CollectingErrorListener.java @@ -0,0 +1,17 @@ +package io.trygvis.ld; + +import org.antlr.v4.runtime.BaseErrorListener; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; + +import java.util.ArrayList; +import java.util.List; + +public class CollectingErrorListener extends BaseErrorListener { + public final List errors = new ArrayList<>(); + + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + String s = line + ":" + charPositionInLine + " " + msg; + errors.add(s); + } +} diff --git a/java/src/main/java/io/trygvis/ld/ElfinfoExprVisitor.java b/java/src/main/java/io/trygvis/ld/ElfinfoExprVisitor.java new file mode 100644 index 0000000..af5bea5 --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/ElfinfoExprVisitor.java @@ -0,0 +1,318 @@ +package io.trygvis.ld; + +import io.trygvis.ld.antlr.GnuLdParser; +import io.trygvis.ld.antlr.GnuLdParserBaseVisitor; +import org.antlr.v4.runtime.tree.ParseTreeProperty; + +import java.math.BigInteger; + +class ElfinfoExprVisitor extends GnuLdParserBaseVisitor { + private BigInteger value; + private ParseTreeProperty es = new ParseTreeProperty<>(); + + public static BigInteger evaluate(GnuLdParser.Mustbe_expContext ctx) { + ElfinfoExprVisitor v = new ElfinfoExprVisitor(); + v.visitMustbe_exp(ctx); + return v.value(); + } + + @Override + public ElfinfoExprVisitor visitExpLt(GnuLdParser.ExpLtContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpBlock(GnuLdParser.ExpBlockContext ctx) { + return visitChildren(ctx); + + } + + @Override + public ElfinfoExprVisitor visitExpAbsolute(GnuLdParser.ExpAbsoluteContext ctx) { + return visitChildren(ctx); + + } + + @Override + public ElfinfoExprVisitor visitExpLog2ceil(GnuLdParser.ExpLog2ceilContext ctx) { + return visitChildren(ctx); + + } + + @Override + public ElfinfoExprVisitor visitExpAddr(GnuLdParser.ExpAddrContext ctx) { + return visitChildren(ctx); + + } + + @Override + public ElfinfoExprVisitor visitExpDataSegmentEnd(GnuLdParser.ExpDataSegmentEndContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpSub(GnuLdParser.ExpSubContext ctx) { + System.out.println("ElfinfoExprVisitor.visitExpSub"); + + ElfinfoExprVisitor ret = visitChildren(ctx); + BigInteger a = es.removeFrom(ctx.exp(0)); + BigInteger b = es.removeFrom(ctx.exp(1)); + + BigInteger x = a.subtract(b); + + es.put(ctx, x); + return ret; + } + + @Override + public ElfinfoExprVisitor visitExpDefined(GnuLdParser.ExpDefinedContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpMod(GnuLdParser.ExpModContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpInvert(GnuLdParser.ExpInvertContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAlign(GnuLdParser.ExpAlignContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpMul(GnuLdParser.ExpMulContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAnd(GnuLdParser.ExpAndContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpXor(GnuLdParser.ExpXorContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpParen(GnuLdParser.ExpParenContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpMinus(GnuLdParser.ExpMinusContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpDiv(GnuLdParser.ExpDivContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpGe(GnuLdParser.ExpGeContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpMin(GnuLdParser.ExpMinContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAlignK(GnuLdParser.ExpAlignKContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpNegate(GnuLdParser.ExpNegateContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpName(GnuLdParser.ExpNameContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpOr(GnuLdParser.ExpOrContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpTrinary(GnuLdParser.ExpTrinaryContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpOror(GnuLdParser.ExpOrorContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpDataSegmentAlign(GnuLdParser.ExpDataSegmentAlignContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpLengthExp(GnuLdParser.ExpLengthExpContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAdd(GnuLdParser.ExpAddContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpLoadaddr(GnuLdParser.ExpLoadaddrContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpGt(GnuLdParser.ExpGtContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpOrigin(GnuLdParser.ExpOriginContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpEq(GnuLdParser.ExpEqContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpMax(GnuLdParser.ExpMaxContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpLshift(GnuLdParser.ExpLshiftContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpSizeofHeaders(GnuLdParser.ExpSizeofHeadersContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpLe(GnuLdParser.ExpLeContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpNe(GnuLdParser.ExpNeContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAndand(GnuLdParser.ExpAndandContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpRshift(GnuLdParser.ExpRshiftContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpNextParen(GnuLdParser.ExpNextParenContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAlignof(GnuLdParser.ExpAlignofContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpSegmentStart(GnuLdParser.ExpSegmentStartContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpInt(GnuLdParser.ExpIntContext ctx) { + System.out.println("ElfinfoExprVisitor.visitExpInt"); + + BigInteger i = parseInt(ctx.INT().getText()); + es.put(ctx, i); + + return this; + } + + public static BigInteger parseInt(String str) { + str = str.toLowerCase(); + int base = 10; + if (str.startsWith("0x")) { + base = 16; + str = str.substring(2); + } + + int factor = 1; + if (str.endsWith("k")) { + factor = 1024; + str = str.substring(0, str.length() - 1); + } else if (str.endsWith("k")) { + factor = 1024 * 1024; + str = str.substring(0, str.length() - 1); + } + + BigInteger i = new BigInteger(str, base); + if (factor > 1) { + i = i.multiply(BigInteger.valueOf(factor)); + } + return i; + } + + @Override + public ElfinfoExprVisitor visitExpConstant(GnuLdParser.ExpConstantContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpPlus(GnuLdParser.ExpPlusContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpSizeof(GnuLdParser.ExpSizeofContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpDataSegmentRelRoEnd(GnuLdParser.ExpDataSegmentRelRoEndContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitExpAssert(GnuLdParser.ExpAssertContext ctx) { + return visitChildren(ctx); + } + + @Override + public ElfinfoExprVisitor visitMustbe_exp(GnuLdParser.Mustbe_expContext ctx) { + ElfinfoExprVisitor ret = visitChildren(ctx); + + value = es.removeFrom(ctx.exp()); + es.put(ctx, value); + + return ret; + } + + public BigInteger value() { + if (value != null) { + return value; + } + + throw new RuntimeException("Something bad happened, probably an unevaluated expression part."); + } +} diff --git a/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdListener.java b/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdListener.java new file mode 100644 index 0000000..fe40547 --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdListener.java @@ -0,0 +1,170 @@ +package io.trygvis.ld; + +import io.trygvis.ld.antlr.GnuLdParser; +import io.trygvis.ld.antlr.GnuLdParserBaseListener; +import org.antlr.v4.runtime.tree.ParseTreeProperty; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +class ElfinfoGnuLdListener extends GnuLdParserBaseListener { + public List memoryAreas = new ArrayList<>(); + + private final ParseTreeProperty expr = new ParseTreeProperty<>(); + + @Override + public void exitExpInt(GnuLdParser.ExpIntContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitExpInt: ctx.INT().getText() = " + ctx.INT().getText()); + expr.put(ctx, ElfinfoExprVisitor.parseInt(ctx.INT().getText())); + } + + @Override + public void exitExpSub(GnuLdParser.ExpSubContext ctx) { + BigInteger a = expr.get(ctx.exp(0)); + BigInteger b = expr.get(ctx.exp(1)); + BigInteger x = a.subtract(b); + expr.put(ctx, x); + } + + @Override + public void exitExpAdd(GnuLdParser.ExpAddContext ctx) { + BigInteger a = expr.get(ctx.exp(0)); + BigInteger b = expr.get(ctx.exp(1)); + BigInteger x = a.add(b); + expr.put(ctx, x); + } + + @Override + public void exitExpName(GnuLdParser.ExpNameContext ctx) { + expr.put(ctx, BigInteger.ZERO); + } + + @Override + public void exitExpAddr(GnuLdParser.ExpAddrContext ctx) { + expr.put(ctx, BigInteger.ZERO); + } + + @Override + public void exitExpSizeof(GnuLdParser.ExpSizeofContext ctx) { + expr.put(ctx, BigInteger.ZERO); + } + + @Override + public void exitExpLengthExp(GnuLdParser.ExpLengthExpContext ctx) { + LdLoader.MemoryArea ma = getMemoryArea(ctx.NAME().getText()); +// System.out.println("ma.length = " + ma.length); + expr.put(ctx, ma.length); + } + + @Override + public void exitExpOrigin(GnuLdParser.ExpOriginContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitExpOrigin: " + ctx.getText()); + LdLoader.MemoryArea ma = getMemoryArea(ctx.NAME().getText()); +// System.out.println("ma.origin = " + ma.origin); + expr.put(ctx, ma.origin); + } + + private LdLoader.MemoryArea getMemoryArea(String name) { + LdLoader.MemoryArea m = null; + for (LdLoader.MemoryArea ma : memoryAreas) { + if (ma.name.equals(name)) { + m = ma; + } + } + if (m == null) { + throw new RuntimeException("No such memory area: " + name); + } + return m; + } + + @Override + public void enterMustbe_exp(GnuLdParser.Mustbe_expContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterMustbe_exp"); + } + + @Override + public void exitMustbe_exp(GnuLdParser.Mustbe_expContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitMustbe_exp"); + + expr.put(ctx, expr.get(ctx.exp())); + } + + + @Override + public void enterOrigin_spec(GnuLdParser.Origin_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterOrigin_spec"); + } + + @Override + public void exitOrigin_spec(GnuLdParser.Origin_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitOrigin_spec"); + } + + @Override + public void enterLength_spec(GnuLdParser.Length_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterLength_spec"); + } + + @Override + public void exitLength_spec(GnuLdParser.Length_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitLength_spec"); + } + + @Override + public void enterMemory_spec(GnuLdParser.Memory_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterMemory_spec"); + } + + @Override + public void exitMemory_spec(GnuLdParser.Memory_specContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitMemory_spec"); + LdLoader.MemoryArea ma = new LdLoader.MemoryArea(); + ma.name = ctx.NAME().getText(); + ma.attributes = attributes; +// System.out.println("ctx.origin_spec() = " + ctx.origin_spec()); + ma.origin = expr.get(ctx.origin_spec().mustbe_exp()); + ma.length = expr.get(ctx.length_spec().mustbe_exp()); + System.out.println(ma); + memoryAreas.add(ma); + } + + LdLoader.MemoryAttribute attribute; + boolean attributesInverted; + Set attributes; + + @Override + public void exitAttributes_opt(GnuLdParser.Attributes_optContext ctx) { +// System.out.println("ElfinfoGnuLdListener.exitAttributes_opt"); + attributes = new HashSet<>(); + } + + @Override + public void enterAttributeInverted(GnuLdParser.AttributeInvertedContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterAttributeInverted"); + + if (!attributes.isEmpty()) { + throw new RuntimeException("Attributes for memory areas can only be attributesInverted (with '!') as the first character in a specification; foo(!rw), not foo(x!rw)."); + } +// String name = ctx.name().getText(); + String name = ctx.NAME().getText(); +// System.out.println("ctx.ATTRIBUTE().getText() = " + name); + + attributesInverted = true; + } + + @Override + public void enterAttributeNormal(GnuLdParser.AttributeNormalContext ctx) { +// System.out.println("ElfinfoGnuLdListener.enterAttributeNormal"); + + String name = ctx.NAME().getText(); +// System.out.println("ctx.ATTRIBUTE().getText() = " + name); + for (int i = 0; i < name.length(); i++) { + attribute = LdLoader.MemoryAttribute.valueOf(String.valueOf(Character.toUpperCase(name.charAt(i)))); + attributes.add(attribute); + } + attributesInverted = false; + } +} diff --git a/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdVisitor.java b/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdVisitor.java new file mode 100644 index 0000000..3062aad --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/ElfinfoGnuLdVisitor.java @@ -0,0 +1,75 @@ +package io.trygvis.ld; + +import io.trygvis.ld.antlr.GnuLdParser; +import io.trygvis.ld.antlr.GnuLdParserBaseVisitor; +import org.antlr.v4.runtime.tree.ParseTreeProperty; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class ElfinfoGnuLdVisitor extends GnuLdParserBaseVisitor { + public List memoryAreas = new ArrayList<>(); + + ParseTreeProperty es = new ParseTreeProperty<>(); + + @Override + public ElfinfoGnuLdVisitor visitMemory_spec(GnuLdParser.Memory_specContext ctx) { + System.out.println("ElfinfoGnuLdBaseVisitor.visitMemory_spec"); + visitChildren(ctx); + + if (attributesInverted) { + // not quite sure how this is supposed to work yet + throw new RuntimeException("Inverted memory region attributes is not implemented yet."); + } + + LdLoader.MemoryArea ma = new LdLoader.MemoryArea(); + ma.name = ctx.NAME().getText(); + ma.attributes = attributes; + ma.origin = ElfinfoExprVisitor.evaluate(ctx.origin_spec().mustbe_exp()); + ma.length = ElfinfoExprVisitor.evaluate(ctx.length_spec().mustbe_exp()); + System.out.println(ma); + memoryAreas.add(ma); + return this; + } + + LdLoader.MemoryAttribute attribute; + boolean attributesInverted; + Set attributes; + + @Override + public ElfinfoGnuLdVisitor visitAttributes_opt(GnuLdParser.Attributes_optContext ctx) { + System.out.println("ElfinfoGnuLdBaseVisitor.visitAttributes_opt"); + attributes = new HashSet<>(); + return visitChildren(ctx); + } + + @Override + public ElfinfoGnuLdVisitor visitAttributeNormal(GnuLdParser.AttributeNormalContext ctx) { + System.out.println("ElfinfoGnuLdBaseVisitor.visitAttributeNormal"); + String name = ctx.NAME().getText(); + System.out.println("ctx.ATTRIBUTE().getText() = " + name); + for (int i = 0; i < name.length(); i++) { + attribute = LdLoader.MemoryAttribute.valueOf(String.valueOf(Character.toUpperCase(name.charAt(i)))); + attributes.add(attribute); + } + attributesInverted = false; + return visitChildren(ctx); + } + + @Override + public ElfinfoGnuLdVisitor visitAttributeInverted(GnuLdParser.AttributeInvertedContext ctx) { + System.out.println("ElfinfoGnuLdBaseVisitor.visitAttributeInverted"); + if (!attributes.isEmpty()) { + throw new RuntimeException("Attributes for memory areas can only be attributesInverted (with '!') as the first character in a specification; foo(!rw), not foo(x!rw)."); + } +// String name = ctx.name().getText(); + String name = ctx.NAME().getText(); + System.out.println("ctx.ATTRIBUTE().getText() = " + name); + + attributesInverted = true; + return visitChildren(ctx); + } +} diff --git a/java/src/main/java/io/trygvis/ld/LdLoader.java b/java/src/main/java/io/trygvis/ld/LdLoader.java new file mode 100644 index 0000000..0b71720 --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/LdLoader.java @@ -0,0 +1,121 @@ +package io.trygvis.ld; + +import io.trygvis.ld.antlr.GnuLdLexer; +import io.trygvis.ld.antlr.GnuLdParser; +import org.antlr.v4.runtime.ANTLRFileStream; +import org.antlr.v4.runtime.BufferedTokenStream; +import org.antlr.v4.runtime.ConsoleErrorListener; + +import java.io.File; +import java.math.BigInteger; +import java.util.List; +import java.util.Set; + +public class LdLoader { + + public final List memoryAreas; + + public LdLoader(List memoryAreas) { + this.memoryAreas = memoryAreas; + } + + public enum MemoryAttribute { + R, W, X, A, I, + } + + public static class MemoryArea { + private final BigInteger MEGA = BigInteger.valueOf(1024 * 1024); + private final BigInteger KILO = BigInteger.valueOf(1024); + + String name; + BigInteger origin; + BigInteger length; + Set attributes; + + @Override + public String toString() { + return "MemoryArea{" + + "name='" + name + '\'' + + ", origin=" + origin + + ", length=" + length + + ", attributes='" + attributes + '\'' + + '}'; + } + + public String prettyOrigin() { + if (origin == null) { + return ""; + } + String hex = origin.toString(16); + + return "0x" + ("00000000").substring(0, 8 - hex.length()) + hex; + } + + public String prettyLength() { + if (length == null) { + return ""; + } + + if (length.compareTo(MEGA) >= 0 && length.mod(MEGA).equals(BigInteger.ZERO)) { + return length.divide(MEGA) + "M"; + } + + if (length.compareTo(KILO) >= 0 && length.mod(KILO).equals(BigInteger.ZERO)) { + return length.divide(KILO) + "k"; + } + + return String.valueOf(length); + } + + public String prettyAttributes() { + String s = ""; + for (MemoryAttribute attribute : attributes) { + s += attribute.name().toLowerCase(); + } + return s; + } + } + + public static LdLoader load(File path) throws Exception { + GnuLdLexer lexer = new GnuLdLexer(new ANTLRFileStream(path.getAbsolutePath())); + BufferedTokenStream tokens = new BufferedTokenStream(lexer); + GnuLdParser parser = new GnuLdParser(tokens); + parser.setBuildParseTree(true); + parser.removeErrorListeners(); + ConsoleErrorListener errorListener = new ConsoleErrorListener(); + parser.addErrorListener(errorListener); + CollectingErrorListener collectingErrorListener = new CollectingErrorListener(); + parser.addErrorListener(collectingErrorListener); + + ElfinfoGnuLdListener listener = new ElfinfoGnuLdListener(); + parser.addParseListener(listener); + + GnuLdParser.FileContext file = parser.file(); + + if (parser.getNumberOfSyntaxErrors() > 0) { + throw new ParseErrorException(lexer, tokens, parser, collectingErrorListener.errors + ); + } + +// ElfinfoGnuLdVisitor visitor = new ElfinfoGnuLdVisitor(); +// visitor.visit(file); + +// return new LdLoader(visitor.memoryAreas); + return new LdLoader(listener.memoryAreas); + } + + public static class ParseErrorException extends Exception { + public final GnuLdLexer lexer; + public final BufferedTokenStream tokens; + public final GnuLdParser parser; + public final List errors; + + public ParseErrorException(GnuLdLexer lexer, BufferedTokenStream tokens, GnuLdParser parser, List errors) { + this.lexer = lexer; + this.tokens = tokens; + this.parser = parser; + this.errors = errors; + } + } + +} diff --git a/java/src/main/java/io/trygvis/ld/StringGnuLdVisitor.java b/java/src/main/java/io/trygvis/ld/StringGnuLdVisitor.java new file mode 100644 index 0000000..a975497 --- /dev/null +++ b/java/src/main/java/io/trygvis/ld/StringGnuLdVisitor.java @@ -0,0 +1,59 @@ +package io.trygvis.ld; + +import io.trygvis.ld.antlr.GnuLdParserBaseVisitor; +import io.trygvis.ld.antlr.GnuLdParser; +import org.antlr.v4.runtime.tree.ParseTree; + +import java.util.List; + +class StringGnuLdVisitor extends GnuLdParserBaseVisitor { + +// public static String parseName(GnuLdParser.NameContext ctx) { +// return ""; +// } + + /* + public static String parseName(GnuLdParser.NameContext ctx) { + StringGnuLdVisitor v = new StringGnuLdVisitor(); + return v.visit(ctx); + } + + private StringBuilder string = new StringBuilder(); + + @Override + public String visitNamePlain(GnuLdParser.NamePlainContext ctx) { + System.out.println("NameTest.visitNamePlain"); + String s = ctx.NAME().getText(); + string.append(s); + return s; + } + +// @Override +// public String visitName_or_space(GnuLdParser.Name_or_spaceContext ctx) { +// System.out.println("StringGnuLdBaseVisitor.visitName_or_space"); +// +// TerminalNode name = ctx.NAME(); +// String s = name != null ? name.getText() : " "; +// string.append(s); +// return s; +// } + + @Override + public String visitNameQuoted(GnuLdParser.NameQuotedContext ctx) { + System.out.println("StringGnuLdBaseVisitor.visitNameQuoted"); + List children = ctx.children; + System.out.println("children.size()) = " + children.size()); + + String s = ""; + for (int i = 1; i < children.size() - 1; i++) { + ParseTree part = children.get(i); + System.out.println("part.getText() = " + part.getText()); + s += part.getText(); + } + + return s; +// +// return visitChildren(ctx); + } + */ +} -- cgit v1.2.3