117 lines
3.0 KiB
Markdown
117 lines
3.0 KiB
Markdown
# 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: <ANTLR version>
|
|
...
|
|
```
|
|
|
|
#### 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<String> 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
|
|
``` |