Using ANTLR 4 with Quarkus: A Practical Guide
Why combine ANTLR + Quarkus?
-
Quarkus gives you a fast, cloud/native Java framework with REST, live reload, native image, etc.
-
ANTLR is a powerful parser generator to define grammars and generate parsers/lexers.
-
Together, you can embed a DSL, query language, rule engine, or expression evaluator into a Quarkus microservice.
Challenges / caveats to be aware of:
-
You must integrate ANTLR’s code generation into your build so that generated sources are compiled by Quarkus.
-
In Quarkus dev mode, some Maven plugins (like antlr4-maven-plugin) may not run automatically; you might need to explicitly run
generate-sourcesfirst. Lightrun -
Be mindful of version mismatches between ANTLR tool/grammar version and runtime. Quarkus has historically shipped with a specific ANTLR runtime version. GitHub+1
Example: Expression Parsing via REST
Let’s build a simple Quarkus app that:
-
Accepts a mathematical expression via REST (e.g.
"2 + 3 * 4") -
Uses ANTLR-generated parser to parse and evaluate the expression
-
Returns the result
Project Structure
Grammar: Expr.g4
Place under src/main/antlr4:
This defines a simple arithmetic grammar with precedence (multiplication/division higher than addition/subtraction).
pom.xml
Here’s a minimal pom.xml configured to run ANTLR code generation and build a Quarkus app:
Important note: In Quarkus dev mode, sometimes the ANTLR plugin doesn't run automatically unless you explicitly run mvn generate-sources before quarkus:dev. Lightrun
ExpressionEvaluator.java
ExpressionResource.java
With this endpoint, you can call:
and get back 14.
Testing & Running
-
Run in dev mode:
-
In production:
-
Test via HTTP call, e.g.:
Additional Tips & Caveats
-
ANTLR version mismatches can lead to runtime errors (ATN deserialization issues) when mixing versions. Make sure the version used to generate the parser matches the runtime version. GitHub+1
-
For native image builds, dynamic reflection used by ANTLR may need explicit registration or substitutions. Quarkus extensions sometimes provide built-in support.
-
If your grammar grows complex, consider organizing it modularly (lexer grammar, parser grammar, etc.).
-
Use custom error listeners to provide better syntax error messages.
-
For large grammars, incremental parsing or partial parsing might be needed, depending on performance.