diff options
| author | Jack Koenig | 2021-08-31 14:10:29 -0700 |
|---|---|---|
| committer | Jack Koenig | 2021-12-01 11:40:52 -0800 |
| commit | 17250fba841ae3129dc798c0bc48d10200be18ae (patch) | |
| tree | 37b93b1c487f78e39acd17f94faf5f5c3b24b9d8 /src/main/scala/firrtl/Parser.scala | |
| parent | 64a0ca2512199c55e51ec90dbd3ec7d563472255 (diff) | |
Use ANTLR Listener to save memory during parsing
The ANTLR-generated concrete syntax tree (CST) takes up much more memory
than the parsed .fir file. By using a Listener, we can construct the
FIRRTL AST live with CST construction and null out the CST as we consume
pieces of it. Not only does this improve performance, it drastically
reduces max memory use for the parser.
Diffstat (limited to 'src/main/scala/firrtl/Parser.scala')
| -rw-r--r-- | src/main/scala/firrtl/Parser.scala | 18 |
1 files changed, 7 insertions, 11 deletions
diff --git a/src/main/scala/firrtl/Parser.scala b/src/main/scala/firrtl/Parser.scala index 2d2bd350..bb93511c 100644 --- a/src/main/scala/firrtl/Parser.scala +++ b/src/main/scala/firrtl/Parser.scala @@ -6,6 +6,7 @@ import org.antlr.v4.runtime._ import org.antlr.v4.runtime.atn._ import logger.LazyLogging import firrtl.ir._ +import firrtl.parser.Listener import firrtl.Utils.time import firrtl.antlr.{FIRRTLParser, _} @@ -29,29 +30,24 @@ object Parser extends LazyLogging { /** Parses a org.antlr.v4.runtime.CharStream and returns a parsed [[firrtl.ir.Circuit Circuit]] */ def parseCharStream(charStream: CharStream, infoMode: InfoMode): Circuit = { - val (parseTimeMillis, cst) = time { + val (parseTimeMillis, ast) = time { val parser = { val lexer = new FIRRTLLexer(charStream) new FIRRTLParser(new CommonTokenStream(lexer)) } + val listener = new Listener(infoMode) + parser.getInterpreter.setPredictionMode(PredictionMode.SLL) + parser.addParseListener(listener) // Concrete Syntax Tree - val cst = parser.circuit + parser.circuit val numSyntaxErrors = parser.getNumberOfSyntaxErrors if (numSyntaxErrors > 0) throw new SyntaxErrorsException(s"$numSyntaxErrors syntax error(s) detected") - cst - } - val visitor = new Visitor(infoMode) - val (visitTimeMillis, visit) = time { - visitor.visit(cst) - } - val ast = visit match { - case c: Circuit => c - case x => throw new ClassCastException("Error! AST not rooted with Circuit node!") + listener.getCircuit } ast |
