ANTLR Runtime Testsuite
August 3, 2026 ยท View on GitHub
ANTLR maintains a shared runtime conformance suite in antlr/antlr4/runtime-testsuite.
This repo includes antlr4-runtime-testsuite, a Rust-side harness that consumes those
upstream descriptor files without vendoring them.
Why a Rust Harness Exists
The upstream Java/JUnit harness assumes each target can be generated directly with
-Dlanguage=<target> and that target-specific grammar action templates are available.
The Rust harness keeps the upstream descriptor/template contract but uses the
direct source compiler:
- the ANTLR jar's StringTemplate engine renders each descriptor through
Rust.test.stg, antlr4-rust-gencompiles the rendered.g4root and import graph directly,- the generated modules run against
antlr4_runtime.
The jar is used only as the upstream StringTemplate implementation. It does not generate Rust metadata or recognizers.
Run Full Sweep
Keep the ANTLR jar and upstream runtime-testsuite under
target/antlr-cleanroom. The repository ignores this directory, and unlike an operating-system
temporary directory it is not periodically purged. cargo clean removes it.
Run the full Rust sweep with:
cargo run --quiet -p antlr-rust-runtime-testsuite --bin antlr4-runtime-testsuite
In other environments, pass explicit paths or set ANTLR4_JAR and
ANTLR4_RUNTIME_TESTSUITE.
Run One Descriptor
cargo run -p antlr-rust-runtime-testsuite --bin antlr4-runtime-testsuite -- \
--antlr-jar target/antlr-cleanroom/tools/antlr-4.13.2-complete.jar \
--descriptors target/antlr-cleanroom/antlr4-upstream/runtime-testsuite \
--case LexerExec/KeywordID
--descriptors may point either at the upstream runtime-testsuite directory or
directly at its resources/org/antlr/v4/test/runtime/descriptors directory.
Run a Group Sample
cargo run -p antlr-rust-runtime-testsuite --bin antlr4-runtime-testsuite -- \
--antlr-jar target/antlr-cleanroom/tools/antlr-4.13.2-complete.jar \
--descriptors target/antlr-cleanroom/antlr4-upstream/runtime-testsuite \
--group LexerExec \
--limit 20
The harness creates temporary Cargo crates under target/antlr-runtime-testsuite.
Pass --keep to retain those directories for debugging.
Current Scope
Supported now:
- lexer descriptors,
- parser descriptors with empty stdout/stderr expectations,
- single and imported/composite grammar source graphs,
- descriptor stdout/stderr comparison,
- grouped lexer recovery diagnostics,
- farthest-token parser mismatch diagnostics for supported non-recovery failures,
- parser single-token insertion/deletion recovery diagnostics for supported descriptors,
- parser mismatched-token recovery diagnostics and error-node parse trees for supported descriptors,
- parser extraneous-input diagnostics and error-node parse trees for supported single-token deletion descriptors,
- parser precedence predicates in ATN recognition,
- lexer and parser target-template actions for the currently supported stdout helpers,
- parser token-label text actions such as
$TOKEN.textand$label.text, - parser
AppendStr(..., "$TOKEN.text")stdout actions for supported semantic-predicate descriptors, - parser token-display actions such as
Append(..., "$label")andAppend(..., "$rule.stop")for recovered-token descriptors, - parser rule-level
@afteractions for the currently supported stdout helpers, - parser
$textaction intervals that stop at the previous visible token, including the greedy and non-greedy if/else binding descriptors, - parser decision-order tie breaking for clean action-bearing ambiguities such
as optional
elsebinding and assignment-vs-wildcard alternatives, - parser rule-level
@init {<GetExpectedTokenNames():writeln()>}actions, - nested parser tree construction for action-bearing rules and direct
ToStringTree("$ctx")stdout actions, - lexer semantic predicates for the currently supported
True(),False(),TextEquals(...), token-start-column, and current-column templates, - lexer DFA dump output for the predicate-sensitive
SemPredEvalLexershowDFAfixtures, - lexer accept-position adjustment for the upstream
PositionAdjustingLexerthrough the same generic post-accept lifecycle hook available to callers, - parser
@init {<BuildParseTrees()>}andnotBuildParseTreedescriptors, - parser
predictionMode=LLandpredictionMode=SLLdescriptors modeled by the metadata recognizer, - parser
showDiagnosticErrorsambiguity diagnostics for the currently modeled exact-ambiguity semantic-predicate descriptors, - parser
DumpDFA()output for the currently modeled full-context diagnostics descriptors, - parser rule-level
@after {<ToStringTree("$label.ctx")>}actions for simple rule labels, - parser semantic predicates for
LANotEquals(...)andLTEquals(...)lookahead target templates, - parser rule-argument predicates for supported
ValEquals("$i", "...")target templates, including literal integer calls andVarRef("i")forwarding, - parser boolean-member predicates for the runtime-testsuite
GetMember(...):Not()fixture, - parser integer-member target templates for semantic-predicate fixtures,
including
AddMember,GetMember,ModMemberEquals, andModMemberNotEquals, - multi-template parser action blocks and empty regular actions bound to their finalized ATN action states,
- parser supported-predicate decision ordering for action-bearing alternatives,
- listener-suite target templates for
BasicListener, token/rule getter listeners, and the left-recursive listener fixtures, - simple left-recursive return-value stdout helpers such as
$e.vand$e.result, - common-label left-recursion compile-check templates such as
Production(...)andResult(...), - integer/member predicate scaffolding used by selected semantic-predicate
descriptors, including
InitIntMember,SetMember, andInvoke_pred, - alt-numbered parse-tree contexts for grammars using
TreeNodeWithAltNumField/contextSuperClass, RuleInvocationStack()stdout helper actions,BailErrorStrategy()descriptors as no-ops while the default Rust error handling still matches the covered outputs,- compile-time-only target templates such as
IntArg,AssignLocal,AssertIsList,Pass, parser property helpers, and supported member scaffolding as no-ops, - nested
StringTemplateaction parsing for supported no-op wrappers, StringTemplatecomments in descriptor grammars,- ANTLR recursive-context tree rewrites for left-recursive parse-tree output,
- ANTLR whitespace escaping for terminal text in
ToStringTree(...)output, StringTemplatebackslash rendering for descriptor grammars,- direct Rust module generation from rendered grammar source and execution through Cargo.
Not wired yet:
- composite grammar override/member/mixed-action shapes beyond the currently covered descriptor cases,
- target-template semantic actions beyond the currently supported stdout helpers and no-op compile checks,
- parser error recovery diagnostics beyond the currently supported mismatch, no-viable, extraneous-input, semantic-predicate fail options, EOF unwind, and token recovery cases,
- runtime diagnostic/profile/DFA flags beyond the currently modeled ambiguity diagnostics and non-default prediction modes.
The harness reports unsupported descriptors as skipped, and the sweep fails if any descriptor fails or is skipped.
Current validated groups:
- full descriptor sweep:
357 passed, 0 failed, 0 skipped, 357 run CompositeLexers:2 passed, 0 failed, 0 skipped, 2 runCompositeParsers:15 passed, 0 failed, 0 skipped, 15 runFullContextParsing:15 passed, 0 failed, 0 skipped, 15 runLexerExec:42 passed, 0 failed, 0 skipped, 42 runLexerErrors:12 passed, 0 failed, 0 skipped, 12 runLeftRecursion:98 passed, 0 failed, 0 skipped, 98 runListeners:7 passed, 0 failed, 0 skipped, 7 runParseTrees:10 passed, 0 failed, 0 skipped, 10 runParserExec:50 passed, 0 failed, 0 skipped, 50 runParserErrors:34 passed, 0 failed, 0 skipped, 34 runPerformance:7 passed, 0 failed, 0 skipped, 7 runSemPredEvalLexer:8 passed, 0 failed, 0 skipped, 8 runSemPredEvalParser:26 passed, 0 failed, 0 skipped, 26 runSets:31 passed, 0 failed, 0 skipped, 31 run