# ANTLR4 Runtime for Dart Notice: Dart target may generate code incompatible with Dart 2.9 sound null safety. Please set the minimum SDK constraint to 2.8.4 or lower if such violation is found. Contributions are welcomed. ### First steps #### 1. Install ANTLR4 [The getting started guide](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md) should get you started. #### 2. Install the Dart ANTLR runtime Each target language for ANTLR has a runtime package for running parser generated by ANTLR4. The runtime provides a common set of tools for using your parser. Install the runtime with the same version as the main ANTLR tool: Add this to your package's pubspec.yaml file: ```yaml ... dependencies: antlr4: ... ``` #### 3. Generate your parser You use the ANTLR4 "tool" to generate a parser. These will reference the ANTLR runtime, installed above. Suppose you're using a UNIX system and have set up an alias for the ANTLR4 tool as described in [the getting started guide](https://github.com/antlr/antlr4/blob/master/doc/getting-started.md). To generate your Dart parser, run the following command: ```shell script antlr4 -Dlanguage=Dart MyGrammar.g4 ``` For a full list of antlr4 tool options, please visit the [tool documentation page](https://github.com/antlr/antlr4/blob/master/doc/tool-options.md). ### Complete example Suppose you're using the JSON grammar from https://github.com/antlr/grammars-v4/tree/master/json. Then, invoke `antlr4 -Dlanguage=Dart JSON.g4`. The result of this is a collection of `.dart` including: * JsonLexer.dart * JsonParser.dart * JsonBaseListener.dart * JsonListener.dart (if you have not activated the -no-listener option) * JsonVisitor.dart (if you have activated the -visitor option) We'll write a small main func to call the generated parser/lexer (assuming they are separate). This one writes out the encountered `ParseTreeContext`'s: ```dart import 'package:antlr4/antlr4.dart'; import 'package:my_project/JSONParser.dart'; import 'package:my_project/JSONLexer.dart'; class TreeShapeListener implements ParseTreeListener { @override void enterEveryRule(ParserRuleContext ctx) { print(ctx.text); } @override void exitEveryRule(ParserRuleContext node) { } @override void visitErrorNode(ErrorNode node) { } @override void visitTerminal(TerminalNode node) { } } void main(List args) async { JSONLexer.checkVersion(); JSONParser.checkVersion(); final input = await InputStream.fromPath(args[0]); final lexer = JSONLexer(input); final tokens = CommonTokenStream(lexer); final parser = JSONParser(tokens); parser.addErrorListener(DiagnosticErrorListener()); parser.buildParseTree = true; final tree = parser.json(); ParseTreeWalker.DEFAULT.walk(TreeShapeListener(), tree); } ``` Create a `example.json` file: ```json {"a":1} ``` Parse the input file: ```shell script dart bin/main.dart example.json ``` The expected output is: ``` {"a":1} {"a":1} {"a":1} "a":1 1 ```