ANTLR Regeneration Guide
March 14, 2026 · View on GitHub
This project vendors the ANTLR toolchain to keep parser builds reproducible. The
resources/antlr/antlr4-4.13.2-complete.jar artifact is the canonical source
for generating JavaScript parser and lexer code from the
GameMakerLanguageLexer.g4 and GameMakerLanguageParser.g4 grammars.
Prerequisites
- Java 21 (or any modern JVM capable of running the ANTLR tool JAR).
- Node.js dependencies installed via
pnpm installat the repository root.
The ANTLR runtime for JavaScript remains an npm registry dependency (antlr4@4.13.2);
it is distinct from the tool JAR that produces the generated sources.
Regenerating Parser Artifacts
-
Ensure the working tree is clean and dependencies are installed.
-
From the repository root run:
pnpm run build:antlrThe root script changes into
src/parserand invokes the workspaceantlrscript, which executes the vendored ANTLR JAR twice—once per grammar—writing fresh artifacts intosrc/parser/generated/. -
Verify the working tree is still clean. Any manual edits to
src/parser/generated/**indicate a divergence that must be resolved by adjusting grammar files or the non-generated extension points.
Extension Points
Custom parser behavior now lives outside the generated directory:
src/parser/src/runtime/game-maker-language-parser-visitor.jsexposes the delegate-driven visitor wrapper. It subclasses the generated visitor to keep the public API intact (VISIT_METHOD_NAMES, delegate hook, etc.).src/parser/src/runtime/game-maker-language-parser-listener.jsmirrors the listener delegation model. It composes optional per-rule handlers while preserving the generated listener contract via inheritance.src/parser/src/runtime/recognition-exception-patch.jsinstalls a structuralinstanceofguard so that recognition errors created by bundled runtimes still satisfyre instanceof antlr4.error.RecognitionException.src/parser/src/gml-parser.jsinstalls the guard during module initialization.
Consumers can import the visitor and listener helpers via
src/parser/gml-parser.js, which now re-exports the extension classes and their
method name enumerations.
Error Handling
installRecognitionExceptionLikeGuard() augments the ANTLR runtime at startup
so that any object matching isRecognitionExceptionLike() is treated as a
RecognitionException. This ensures the generated parser’s catch blocks follow
ANTLR’s normal recovery flow even when the runtime is bundled or proxied. The
helper lives in src/parser/src/runtime/recognition-exception-patch.js and is
invoked by src/parser/src/gml-parser.js before parsing begins.
Grammar Adjustments
The following grammar fixes accompany the extracted extensions:
- Unary plus expressions now map to a dedicated
UnaryPlusExpressionalternative, enabling constructs such asvar point = [+x, -y];to parse without custom runtime patches. - Constructor parent clauses (
function Foo() : Bar(...) constructor) now reuse theargumentsrule so that each parent argument is parsed as a full expression rather than a bare identifier token. This aligns the grammar with GameMaker’s syntax, where calls such as: AbstractInputButton(button, eInputType.keyboard)are valid. - Statement parsing now uses lightweight lookahead predicates to distinguish
assignment/inc-dec statements from chained call statements. This prevents
multiline chains such as
fsm\n .add(...)\n .add(...);from being misclassified as assignment or inc-dec statements while still preservingfor (...)update-clause parsing.
When additional grammar updates are required, modify the .g4 sources first
and rerun pnpm run build:antlr to refresh the generated JavaScript output.