using Antlr4.Runtime; using Antlr4.Runtime.Atn; using Antlr4.Runtime.Tree; using InkBlot.ParseHierarchy; using InkBlot.Visitor; using Microsoft.Extensions.Logging; namespace InkBlot; public class InkBlotParser { public static (Story, IEnumerable) Parse(IFileReader fileReader, ILoggerFactory loggerFactory, string mainFileName) { var tokens = GetTokenStream(fileReader, mainFileName, out var lexerErrorListener); var parser = new InkBlotAntlrGrammarParser(tokens); var parserErrorListener = new ParserErrorListener(); parser.RemoveErrorListeners(); parser.AddErrorListener(parserErrorListener); #if DEBUG parser.AddErrorListener(new DiagnosticErrorListener()); parser.Interpreter.PredictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION; #endif var tree = parser.story(); var listener = new Listener(loggerFactory.CreateLogger()); var walker = new ParseTreeWalker(); walker.Walk(listener, tree); return (listener.Story, lexerErrorListener.Diagnostics.Concat(parserErrorListener.Diagnostics)); } private static CommonTokenStream GetTokenStream(IFileReader fileReader, string mainFileName, out LexerErrorListener lexerErrorListener) { var stream = fileReader.GetContents(mainFileName); var inputStream = new AntlrInputStream(stream); var lexer = new InkBlotAntlrGrammarLexer(inputStream); lexerErrorListener = new LexerErrorListener(); lexer.RemoveErrorListeners(); lexer.AddErrorListener(lexerErrorListener); var tokens = new CommonTokenStream(lexer); return tokens; } public static CommonTokenStream GetTokenStream(IFileReader fileReader, string mainFileName) { return GetTokenStream(fileReader, mainFileName, out _); } }