ANTLR

ANTLR (ANother Tool for Language Recognition) is a parser generator: you describe a language's syntax in a grammar file, and ANTLR generates a lexer and parser that turn source text into a parse tree. It is used to build query languages, configuration formats, domain-specific languages, code analysis tools, and translators — Hive and Spark SQL, Presto, and many IDE plugins have parsers generated by ANTLR. One grammar can generate parsers for Java, Python, JavaScript and TypeScript, C#, Go, C++, Swift, Dart, and PHP.

ANTLR 4's adaptive parsing strategy accepts grammars written naturally — including directly left-recursive expression rules — so you spend time on the language, not on contorting rules to satisfy the parsing algorithm. Its generated listeners and visitors separate parsing from what you do with the tree.

TL;DR

Quick Example

An expression language with assignments, written as a grammar:

Generate a Python parser and evaluate input with a visitor:

Because MulDiv appears before AddSub, multiplication binds tighter — precedence comes from the order of alternatives.

Core Concepts

Lexer and Parser Rules

The lexer picks the longest match, breaking ties by rule order — so keywords must be defined before a general identifier rule. Literals in parser rules ('=') create implicit tokens.

Adaptive Parsing and Left Recursion

ANTLR 4's ALL(\*) strategy looks ahead as far as needed at runtime to choose between alternatives, caching decisions for speed. It rewrites directly left-recursive rules such as expr : expr '*' expr | ... automatically; alternatives listed first get higher precedence, and <assoc=right> marks right-associative operators such as exponentiation. Indirect left recursion across several rules is not supported.

Parse Trees, Listeners, and Visitors

Most language tools convert the parse tree into their own abstract syntax tree early, so later stages do not depend on grammar details. See Abstract Syntax Trees.

Lexer Modes and Channels

Lexer modes switch token rules in context — inside a string template, a tag, or an embedded language — using pushMode and popMode. Channels keep tokens out of the parser's way without discarding them: sending comments and whitespace to a hidden channel lets formatters and documentation tools still find them.

Error Handling

By default, ANTLR reports syntax errors to the console and recovers by inserting or deleting tokens. Language tools should replace the default error listener with one that collects errors with line and column information, and choose a strategy: keep recovering to report many errors (editors), or stop at the first error with BailErrorStrategy (configuration loaders).

Testing and Performance

ANTLR or a Hand-Written Parser

Many production compilers use hand-written recursive descent parsers; many data and tooling projects use ANTLR. See Lexers and Parsers and Tree-sitter.

Best Practices

Keep Grammars Free of Application Logic

Avoid embedded actions and semantic predicates where possible; do the work in listeners or visitors so the grammar stays reusable across targets.

Label Alternatives

Labels produce specific callback methods (visitAddSub) and context classes, making tree-walking code far clearer than inspecting children by position.

Order Lexer Rules Carefully

Put keywords before identifiers and longer operators before their prefixes, and test tokenization separately from parsing.

Build Your Own AST

Translate the parse tree into a stable AST so grammar refactoring does not ripple through every later stage.

Common Mistakes

Identifier Rule Before Keywords

Swallowing Errors

Logic Inside the Grammar

FAQ

What is ANTLR used for?

Generating lexers and parsers from grammar files to build domain-specific languages, query languages, configuration formats, code analyzers, translators, and IDE support.

Which languages can ANTLR generate parsers for?

ANTLR 4 targets include Java, C#, Python, JavaScript, TypeScript, Go, C++, Swift, Dart, and PHP, all from the same grammar.

What is the difference between a listener and a visitor in ANTLR?

A listener is called automatically as a tree walker enters and exits nodes, which suits collecting data. A visitor lets your code decide which children to visit and return values, which suits evaluation and AST construction.

Does ANTLR support left recursion?

ANTLR 4 supports direct left recursion within a rule, rewriting it automatically, with precedence determined by the order of alternatives. Indirect left recursion across multiple rules is not supported.

Is ANTLR fast enough for production?

For most uses, yes, especially with two-stage SLL/LL parsing and well-structured grammars. Highly performance-sensitive or editor-incremental use cases may prefer hand-written parsers or Tree-sitter.

Related Topics

References