/*
 * [The "BSD license"]
 *  Copyright (c) 2012-2016 Terence Parr
 *  Copyright (c) 2012-2016 Sam Harwell
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

javaTypeInitMap ::= [
	"int":"0",
	"long":"0",
	"float":"0.0f",
	"double":"0.0",
	"boolean":"false",
	"byte":"0",
	"short":"0",
	"char":"0",
	default:"null" // anything other than a primitive type is an object
]

// args must be <object-model-object>, <fields-resulting-in-STs>

ParserFile(file, parser, namedActions, contextSuperClass) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)>
package <file.genPackage>;
<endif>
<namedActions.header>

import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.*;
import org.antlr.v4.runtime.tree.*;
import org.jspecify.annotations.NullUnmarked;
import java.util.List;
import java.util.Iterator;
import java.util.ArrayList;
import jakarta.annotation.Generated;


<parser>
>>

ListenerFile(file, header, namedActions) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)>
package <file.genPackage>;
<endif>
<header>
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.jspecify.annotations.NullUnmarked;
import jakarta.annotation.Generated;

/**
 * This interface defines a complete listener for a parse tree produced by
 * {@link <file.parserName>}.
 */
@NullUnmarked
@Generated("<file.grammarName>Listener")
interface <file.grammarName>Listener extends ParseTreeListener {
	<file.listenerNames:{lname |
/**
<if(file.listenerLabelRuleNames.(lname))>
 * Enter a parse tree produced by the {@code <lname>\}
 * labeled alternative in {@link <file.parserName>#<file.listenerLabelRuleNames.(lname)>\}.
<else>
 * Enter a parse tree produced by {@link <file.parserName>#<lname>\}.
<endif>
 * @param ctx the parse tree
 */
void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);
/**
<if(file.listenerLabelRuleNames.(lname))>
 * Exit a parse tree produced by the {@code <lname>\}
 * labeled alternative in {@link <file.parserName>#<file.listenerLabelRuleNames.(lname)>\}.
<else>
 * Exit a parse tree produced by {@link <file.parserName>#<lname>\}.
<endif>
 * @param ctx the parse tree
 */
void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n">
}
>>

BaseListenerFile(file, header, namedActions) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)>
package <file.genPackage>;
<endif>
<header>
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.tree.ErrorNode;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.jspecify.annotations.NullUnmarked;
import jakarta.annotation.Generated;

/**
 * This class provides an empty implementation of {@link <file.grammarName>Listener},
 * which can be extended to create a listener which only needs to handle a subset
 * of the available methods.
 */
@NullUnmarked
@Generated("<file.grammarName>BaseListener")
@SuppressWarnings({ "CheckReturnValue", "NullAway" })
class <file.grammarName>BaseListener implements <file.grammarName>Listener {
	<file.listenerNames:{lname |
/**
 * {@inheritDoc\}
 *
 * \<p>The default implementation does nothing.\</p>
 */
@Override public void enter<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \}
/**
 * {@inheritDoc\}
 *
 * \<p>The default implementation does nothing.\</p>
 */
@Override public void exit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { \}}; separator="\n">

	/**
	 * {@inheritDoc\}
	 *
	 * \<p>The default implementation does nothing.\</p>
	 */
	@Override public void enterEveryRule(ParserRuleContext ctx) { }
	/**
	 * {@inheritDoc\}
	 *
	 * \<p>The default implementation does nothing.\</p>
	 */
	@Override public void exitEveryRule(ParserRuleContext ctx) { }
	/**
	 * {@inheritDoc\}
	 *
	 * \<p>The default implementation does nothing.\</p>
	 */
	@Override public void visitTerminal(TerminalNode node) { }
	/**
	 * {@inheritDoc\}
	 *
	 * \<p>The default implementation does nothing.\</p>
	 */
	@Override public void visitErrorNode(ErrorNode node) { }
}
>>

VisitorFile(file, header, namedActions) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)>
package <file.genPackage>;
<endif>
<header>
import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.jspecify.annotations.NullUnmarked;
import jakarta.annotation.Generated;

/**
 * This interface defines a complete generic visitor for a parse tree produced
 * by {@link <file.parserName>}.
 *
 * @param \<T> The return type of the visit operation. Use {@link Void} for
 * operations with no return type.
 */
@NullUnmarked
@Generated("<file.grammarName>Visitor")
interface <file.grammarName>Visitor\<T> extends ParseTreeVisitor\<T> {
	<file.visitorNames:{lname |
/**
<if(file.visitorLabelRuleNames.(lname))>
 * Visit a parse tree produced by the {@code <lname>\}
 * labeled alternative in {@link <file.parserName>#<file.visitorLabelRuleNames.(lname)>\}.
<else>
 * Visit a parse tree produced by {@link <file.parserName>#<lname>\}.
<endif>
 * @param ctx the parse tree
 * @return the visitor result
 */
T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx);}; separator="\n">
}
>>

BaseVisitorFile(file, header, namedActions) ::= <<
<fileHeader(file.grammarFileName, file.ANTLRVersion)>
<if(file.genPackage)>
package <file.genPackage>;
<endif>
<header>
import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
import org.jspecify.annotations.NullUnmarked;
import jakarta.annotation.Generated;

/**
 * This class provides an empty implementation of {@link <file.grammarName>Visitor},
 * which can be extended to create a visitor which only needs to handle a subset
 * of the available methods.
 *
 * @param \<T> The return type of the visit operation. Use {@link Void} for
 * operations with no return type.
 */
@NullUnmarked
@Generated("<file.grammarName>BaseVisitor")
@SuppressWarnings({ "CheckReturnValue", "NullAway" })
class <file.grammarName>BaseVisitor\<T> extends AbstractParseTreeVisitor\<T> implements <file.grammarName>Visitor\<T> {
	<file.visitorNames:{lname |
/**
 * {@inheritDoc\}
 *
 * \<p>The default implementation returns the result of calling
 * {@link #visitChildren\} on {@code ctx\}.\</p>
 */
@Override public T visit<lname; format="cap">(<file.parserName>.<lname; format="cap">Context ctx) { return visitChildren(ctx); \}}; separator="\n">
}
>>

fileHeader(grammarFileName, ANTLRVersion) ::= <<
// Generated from <grammarFileName> by ANTLR <ANTLRVersion>
>>

Parser(parser, funcs, atn, sempredFuncs, superClass) ::= <<
<Parser_(ctor="parser_ctor", ...)>
>>

Parser_(parser, funcs, atn, sempredFuncs, ctor, superClass) ::= <<
@NullUnmarked
@Generated("<parser.name>")
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "NullAway"})
class <parser.name> extends <superClass; null="Parser"> {
	// Customization: Suppress version check
	// static { RuntimeMetaData.checkVersion("<file.ANTLRVersion>", RuntimeMetaData.VERSION); }

	protected static final DFA[] _decisionToDFA;
	protected static final PredictionContextCache _sharedContextCache =
		new PredictionContextCache();
	<if(parser.tokens)>
	public static final int
		<parser.tokens:{k | <k>=<parser.tokens.(k)>}; separator=", ", wrap, anchor>;
	<endif>
	<if(parser.rules)>
	public static final int
		<parser.rules:{r | RULE_<r.name> = <r.index>}; separator=", ", wrap, anchor>;
	<endif>
	private static String[] makeRuleNames() {
		return new String[] {
			<parser.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
		};
	}
	public static final String[] ruleNames = makeRuleNames();

	<vocabulary(parser.literalNames, parser.symbolicNames)>

	@Override
	public String getGrammarFileName() { return "<parser.grammarFileName>"; }

	@Override
	public String[] getRuleNames() { return ruleNames; }

	@Override
	public String getSerializedATN() { return _serializedATN; }

	@Override
	public ATN getATN() { return _ATN; }

	<namedActions.members>
	<parser:(ctor)()>
	<funcs; separator="\n">

<if(sempredFuncs)>
	public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
		switch (ruleIndex) {
		<parser.sempredFuncs.values:{f|
case <f.ruleIndex>:
	return <f.name>_sempred((<f.ctxType>)_localctx, predIndex);}; separator="\n">
		}
		return true;
	}
	<sempredFuncs.values; separator="\n">
<endif>

	<atn>
}
>>

vocabulary(literalNames, symbolicNames) ::= <<
private static String[] makeLiteralNames() {
	return new String[] {
		<literalNames:{t | <t>}; null="null", separator=", ", wrap, anchor>
	};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
	return new String[] {
		<symbolicNames:{t | <t>}; null="null", separator=", ", wrap, anchor>
	};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);

/**
 * @deprecated Use {@link #VOCABULARY} instead.
 */
@Deprecated
public static final String[] tokenNames;
static {
	tokenNames = new String[_SYMBOLIC_NAMES.length];
	for (int i = 0; i \< tokenNames.length; i++) {
		tokenNames[i] = VOCABULARY.getLiteralName(i);
		if (tokenNames[i] == null) {
			tokenNames[i] = VOCABULARY.getSymbolicName(i);
		}

		if (tokenNames[i] == null) {
			tokenNames[i] = "\<INVALID>";
		}
	}
}

@Override
@Deprecated
public String[] getTokenNames() {
	return tokenNames;
}

@Override

public Vocabulary getVocabulary() {
	return VOCABULARY;
}
>>

dumpActions(recog, argFuncs, actionFuncs, sempredFuncs) ::= <<
<if(actionFuncs)>
@Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
	switch (ruleIndex) {
	<recog.actionFuncs.values:{f|
case <f.ruleIndex>:
	<f.name>_action((<f.ctxType>)_localctx, actionIndex);
	break;}; separator="\n">
	}
}
<actionFuncs.values; separator="\n">
<endif>
<if(sempredFuncs)>
@Override
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
	switch (ruleIndex) {
	<recog.sempredFuncs.values:{f|
case <f.ruleIndex>:
	return <f.name>_sempred((<f.ctxType>)_localctx, predIndex);}; separator="\n">
	}
	return true;
}
<sempredFuncs.values; separator="\n">
<endif>
>>

parser_ctor(p) ::= <<
public <p.name>(TokenStream input) {
	super(input);
	_interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
>>

/* This generates a private method since the actionIndex is generated, making an
 * overriding implementation impossible to maintain.
 */
RuleActionFunction(r, actions) ::= <<
private void <r.name>_action(<r.ctxType> _localctx, int actionIndex) {
	switch (actionIndex) {
	<actions:{index|
case <index>:
	<actions.(index)>
	break;}; separator="\n">
	}
}
>>

/* This generates a private method since the predIndex is generated, making an
 * overriding implementation impossible to maintain.
 */
RuleSempredFunction(r, actions) ::= <<
private boolean <r.name>_sempred(<r.ctxType> _localctx, int predIndex) {
	switch (predIndex) {
	<actions:{index|
case <index>:
	return <actions.(index)>;}; separator="\n">
	}
	return true;
}
>>

RuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,namedActions,finallyAction,postamble,exceptions) ::= <<

<ruleCtx>
<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n">

<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.escapedName>(<args; separator=",">) throws RecognitionException {
	<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, getState()<currentRule.args:{a | , <a.escapedName>}>);
	enterRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>);
	<namedActions.init>
	<locals; separator="\n">
	try {
<if(currentRule.hasLookaheadBlock)>
		int _alt;
<endif>
		<code>
		<postamble; separator="\n">
		<namedActions.after>
	}
	<if(exceptions)>
	<exceptions; separator="\n">
	<else>
	catch (RecognitionException re) {
		_localctx.exception = re;
		_errHandler.reportError(this, re);
		_errHandler.recover(this, re);
	}
	<endif>
	finally {
		<finallyAction>
		exitRule();
	}
	return _localctx;
}
>>

LeftRecursiveRuleFunction(currentRule,args,code,locals,ruleCtx,altLabelCtxs,
	namedActions,finallyAction,postamble) ::=
<<

<ruleCtx>
<altLabelCtxs:{l | <altLabelCtxs.(l)>}; separator="\n">

<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.escapedName>(<args; separator=", ">) throws RecognitionException {
	return <currentRule.escapedName>(0<currentRule.args:{a | , <a.escapedName>}>);
}

private <currentRule.ctxType> <currentRule.escapedName>(int _p<args:{a | , <a>}>) throws RecognitionException {
	ParserRuleContext _parentctx = _ctx;
	int _parentState = getState();
	<currentRule.ctxType> _localctx = new <currentRule.ctxType>(_ctx, _parentState<currentRule.args:{a | , <a.escapedName>}>);
	<currentRule.ctxType> _prevctx = _localctx;
	int _startState = <currentRule.startState>;
	enterRecursionRule(_localctx, <currentRule.startState>, RULE_<currentRule.name>, _p);
	<namedActions.init>
	<locals; separator="\n">
	try {
<if(currentRule.hasLookaheadBlock)>
		int _alt;
<endif>
		<code>
		<postamble; separator="\n">
		<namedActions.after>
	}
	catch (RecognitionException re) {
		_localctx.exception = re;
		_errHandler.reportError(this, re);
		_errHandler.recover(this, re);
	}
	finally {
		<finallyAction>
		unrollRecursionContexts(_parentctx);
	}
	return _localctx;
}
>>

CodeBlockForOuterMostAlt(currentOuterMostAltCodeBlock, locals, preamble, ops) ::= <<
<if(currentOuterMostAltCodeBlock.altLabel)>_localctx = new <currentOuterMostAltCodeBlock.altLabel; format="cap">Context(_localctx);<endif>
enterOuterAlt(_localctx, <currentOuterMostAltCodeBlock.alt.altNum>);
<CodeBlockForAlt(currentAltCodeBlock=currentOuterMostAltCodeBlock, ...)>
>>

CodeBlockForAlt(currentAltCodeBlock, locals, preamble, ops) ::= <<
{
<locals; separator="\n">
<preamble; separator="\n">
<ops; separator="\n">
}
>>

LL1AltBlock(choice, preamble, alts, error) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif>
<preamble; separator="\n">
switch (_input.LA(1)) {
<choice.altLook,alts:{look,alt| <cases(tokens=look)>
	<alt>
	break;}; separator="\n">
default:
	<error>
}
>>

LL1OptionalBlock(choice, alts, error) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
switch (_input.LA(1)) {
<choice.altLook,alts:{look,alt| <cases(tokens=look)>
	<alt>
	break;}; separator="\n">
default:
	break;
}
>>

LL1OptionalBlockSingleAlt(choice, expr, alts, preamble, error, followExpr) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
<preamble; separator="\n">
if (<expr>) {
	<alts; separator="\n">
}
<!else if ( !(<followExpr>) ) <error>!>
>>

LL1StarBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
<preamble; separator="\n">
while (<loopExpr>) {
	<alts; separator="\n">
	setState(<choice.loopBackStateNumber>);
	_errHandler.sync(this);
	<iteration>
}
>>

LL1PlusBlockSingleAlt(choice, loopExpr, alts, preamble, iteration) ::= <<
setState(<choice.blockStartStateNumber>); <! alt block decision !>
_errHandler.sync(this);
<preamble; separator="\n">
do {
	<alts; separator="\n">
	setState(<choice.stateNumber>); <! loopback/exit decision !>
	_errHandler.sync(this);
	<iteration>
} while ( <loopExpr> );
>>

// LL(*) stuff

AltBlock(choice, preamble, alts, error) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
<if(choice.label)><labelref(choice.label)> = _input.LT(1);<endif>
<preamble; separator="\n">
switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) {
<alts:{alt |
case <i>:
	<alt>
	break;}; separator="\n">
}
>>

OptionalBlock(choice, alts, error) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
switch ( getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx) ) {
<alts:{alt |
case <i><if(!choice.ast.greedy)>+1<endif>:
	<alt>
	break;}; separator="\n">
}
>>

StarBlock(choice, alts, sync, iteration) ::= <<
setState(<choice.stateNumber>);
_errHandler.sync(this);
_alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx);
while ( _alt!=<choice.exitAlt> && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
	if ( _alt==1<if(!choice.ast.greedy)>+1<endif> ) {
		<iteration>
		<alts> <! should only be one !>
	}
	setState(<choice.loopBackStateNumber>);
	_errHandler.sync(this);
	_alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx);
}
>>

PlusBlock(choice, alts, error) ::= <<
setState(<choice.blockStartStateNumber>); <! alt block decision !>
_errHandler.sync(this);
_alt = 1<if(!choice.ast.greedy)>+1<endif>;
do {
	switch (_alt) {
	<alts:{alt|
case <i><if(!choice.ast.greedy)>+1<endif>:
	<alt>
	break;}; separator="\n">
	default:
		<error>
	}
	setState(<choice.loopBackStateNumber>); <! loopback/exit decision !>
	_errHandler.sync(this);
	_alt = getInterpreter().adaptivePredict(_input,<choice.decision>,_ctx);
} while ( _alt!=<choice.exitAlt> && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
>>

Sync(s) ::= "sync(<s.expecting.name>);"

ThrowNoViableAlt(t) ::= "throw new NoViableAltException(this);"

TestSetInline(s) ::= <<
<s.bitsets:{bits | <if(rest(rest(bits.tokens)))><bitsetBitfieldComparison(s, bits)><else><bitsetInlineComparison(s, bits)><endif>}; separator=" || ">
>>

// Java language spec 15.19 - shift operators mask operands rather than overflow to 0... need range test
testShiftInRange(shiftAmount) ::= <<
((<shiftAmount>) & ~0x3f) == 0
>>

bitsetBitfieldComparison(s, bits) ::= <%
(<testShiftInRange({<offsetShift(s.varName, bits.shift)>})> && ((1L \<\< <offsetShift(s.varName, bits.shift)>) & <bits.calculated>L) != 0)
%>

isZero ::= [
"0":true,
default:false
]

offsetShift(shiftAmount, offset) ::= <%
<if(!isZero.(offset))>(<shiftAmount> - <offset>)<else><shiftAmount><endif>
%>

bitsetInlineComparison(s, bits) ::= <%
<bits.tokens:{t | <s.varName>==<t.name>}; separator=" || ">
%>

cases(tokens) ::= <<
<tokens:{t | case <t.name>:}; separator="\n">
>>

InvokeRule(r, argExprsChunks) ::= <<
setState(<r.stateNumber>);
<if(r.labels)><r.labels:{l | <labelref(l)> = }><endif><r.escapedName>(<if(r.ast.options.p)><r.ast.options.p><if(argExprsChunks)>,<endif><endif><argExprsChunks>);
>>

MatchToken(m) ::= <<
setState(<m.stateNumber>);
<if(m.labels)><m.labels:{l | <labelref(l)> = }><endif>match(<m.escapedName>);
>>

MatchSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, false)>"

MatchNotSet(m, expr, capture) ::= "<CommonSetStuff(m, expr, capture, true)>"

CommonSetStuff(m, expr, capture, invert) ::= <<
setState(<m.stateNumber>);
<if(m.labels)><m.labels:{l | <labelref(l)> = }>_input.LT(1);<endif>
<capture>
if ( <if(invert)><m.varName> \<= 0 || <else>!<endif>(<expr>) ) {
	<if(m.labels)><m.labels:{l | <labelref(l)> = (Token)}><endif>_errHandler.recoverInline(this);
}
else {
	if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
	_errHandler.reportMatch(this);
	consume();
}
>>

Wildcard(w) ::= <<
setState(<w.stateNumber>);
<if(w.labels)><w.labels:{l | <labelref(l)> = }><endif>matchWildcard();
>>

// ACTION STUFF

Action(a, foo, chunks) ::= "<chunks>"

ArgAction(a, chunks) ::= "<chunks>"

SemPred(p, chunks, failChunks) ::= <<
setState(<p.stateNumber>);
if (!(<chunks>)) throw new FailedPredicateException(this, <p.predicate><if(failChunks)>, <failChunks><elseif(p.msg)>, <p.msg><endif>);
>>

ExceptionClause(e, catchArg, catchAction) ::= <<
catch (<catchArg>) {
	<catchAction>
}
>>

// lexer actions are not associated with model objects

LexerSkipCommand()  ::= "skip();"
LexerMoreCommand()  ::= "more();"
LexerPopModeCommand() ::= "popMode();"

LexerTypeCommand(arg, grammar)      ::= "_type = <arg>;"
LexerChannelCommand(arg, grammar)   ::= "_channel = <arg>;"
LexerModeCommand(arg, grammar)      ::= "_mode = <arg>;"
LexerPushModeCommand(arg, grammar)  ::= "pushMode(<arg>);"

ActionText(t) ::= "<t.text>"
ActionTemplate(t) ::= "<t.st>"
ArgRef(a) ::= "_localctx.<a.escapedName>"
LocalRef(a) ::= "_localctx.<a.escapedName>"
RetValueRef(a) ::= "_localctx.<a.escapedName>"
QRetValueRef(a) ::= "<ctx(a)>.<a.dict>.<a.escapedName>"
/** How to translate $tokenLabel */
TokenRef(t) ::= "<ctx(t)>.<t.escapedName>"
LabelRef(t) ::= "<ctx(t)>.<t.escapedName>"
ListLabelRef(t) ::= "<ctx(t)>.<ListLabelName(t.escapedName)>"
SetAttr(s,rhsChunks) ::= "<ctx(s)>.<s.escapedName> = <rhsChunks>;"

TokenLabelType() ::= "<file.TokenLabelType; null={Token}>"
InputSymbolType() ::= "<file.InputSymbolType; null={Token}>"

TokenPropertyRef_text(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getText():null)"
TokenPropertyRef_type(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getType():0)"
TokenPropertyRef_line(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getLine():0)"
TokenPropertyRef_pos(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getCharPositionInLine():0)"
TokenPropertyRef_channel(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getChannel():0)"
TokenPropertyRef_index(t) ::= "(<ctx(t)>.<t.label>!=null?<ctx(t)>.<t.label>.getTokenIndex():0)"
TokenPropertyRef_int(t) ::= "(<ctx(t)>.<t.label>!=null?Integer.valueOf(<ctx(t)>.<t.label>.getText()):0)"

RulePropertyRef_start(r) ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.start):null)"
RulePropertyRef_stop(r)	 ::= "(<ctx(r)>.<r.label>!=null?(<ctx(r)>.<r.label>.stop):null)"
RulePropertyRef_text(r)	 ::= "(<ctx(r)>.<r.label>!=null?_input.getText(<ctx(r)>.<r.label>.start,<ctx(r)>.<r.label>.stop):null)"
RulePropertyRef_ctx(r)	 ::= "<ctx(r)>.<r.label>"
RulePropertyRef_parser(r)	 ::= "this"

ThisRulePropertyRef_start(r) ::= "_localctx.start"
ThisRulePropertyRef_stop(r)	 ::= "_localctx.stop"
ThisRulePropertyRef_text(r)	 ::= "_input.getText(_localctx.start, _input.LT(-1))"
ThisRulePropertyRef_ctx(r)	 ::= "_localctx"
ThisRulePropertyRef_parser(r)	 ::= "this"

NonLocalAttrRef(s)		 ::= "((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.escapedName>"
SetNonLocalAttr(s, rhsChunks)	  ::=
	"((<s.ruleName; format=\"cap\">Context)getInvokingContext(<s.ruleIndex>)).<s.escapedName> = <rhsChunks>;"

AddToLabelList(a) ::= "<ctx(a.label)>.<a.listName>.add(<labelref(a.label)>);"

TokenDecl(t) ::= "<TokenLabelType()> <t.escapedName>"
TokenTypeDecl(t) ::= "int <t.escapedName>;"
TokenListDecl(t) ::= "List\<Token> <t.escapedName> = new ArrayList\<Token>()"
RuleContextDecl(r) ::= "<r.ctxName> <r.escapedName>"
RuleContextListDecl(rdecl) ::= "List\<<rdecl.ctxName>> <rdecl.escapedName> = new ArrayList\<<rdecl.ctxName>>()"

ContextTokenGetterDecl(t)      ::=
    "public TerminalNode <t.name>() { return getToken(<parser.name>.<t.name>, 0); }"
ContextTokenListGetterDecl(t)  ::=
    "public List\<TerminalNode> <t.name>() { return getTokens(<parser.name>.<t.name>); }"
ContextTokenListIndexedGetterDecl(t)  ::= <<
public TerminalNode <t.name>(int i) {
	return getToken(<parser.name>.<t.name>, i);
}
>>
ContextRuleGetterDecl(r)       ::= <<
public <r.ctxName> <r.escapedName>() {
	return getRuleContext(<r.ctxName>.class,0);
}
>>
ContextRuleListGetterDecl(r)   ::= <<
public List\<<r.ctxName>\> <r.escapedName>() {
	return getRuleContexts(<r.ctxName>.class);
}
>>
ContextRuleListIndexedGetterDecl(r)   ::= <<
public <r.ctxName> <r.escapedName>(int i) {
	return getRuleContext(<r.ctxName>.class,i);
}
>>

LexerRuleContext() ::= "RuleContext"

/** The rule context name is the rule followed by a suffix; e.g.,
 *	r becomes rContext.
 */
RuleContextNameSuffix() ::= "Context"

ImplicitTokenLabel(tokenName) ::= "<tokenName>"
ImplicitRuleLabel(ruleName)	  ::= "<ruleName>"
ImplicitSetLabel(id)		  ::= "_tset<id>"
ListLabelName(label)		  ::= "<label>"

CaptureNextToken(d) ::= "<d.varName> = _input.LT(1);"
CaptureNextTokenType(d) ::= "<d.varName> = _input.LA(1);"

StructDecl(struct,ctorAttrs,attrs,getters,dispatchMethods,interfaces,extensionMembers,signatures)
	::= <<
@SuppressWarnings("CheckReturnValue")
public static class <struct.escapedName> extends <if(contextSuperClass)><contextSuperClass><else>ParserRuleContext<endif><if(interfaces)> implements <interfaces; separator=", "><endif> {
	<attrs:{a | public <a>;}; separator="\n">
	<getters:{g | <g>}; separator="\n">
	<if(ctorAttrs)>public <struct.escapedName>(ParserRuleContext parent, int invokingState) { super(parent, invokingState); }<endif>
	public <struct.escapedName>(ParserRuleContext parent, int invokingState<ctorAttrs:{a | , <a>}>) {
		super(parent, invokingState);
		<struct.ctorAttrs:{a | this.<a.escapedName> = <a.escapedName>;}; separator="\n">
	}
	@Override public int getRuleIndex() { return RULE_<struct.derivedFromName>; }
<if(struct.provideCopyFrom)> <! don't need copy unless we have subclasses !>
	public <struct.escapedName>() { }
	public void copyFrom(<struct.escapedName> ctx) {
		super.copyFrom(ctx);
		<struct.attrs:{a | this.<a.escapedName> = ctx.<a.escapedName>;}; separator="\n">
	}
<endif>
	<dispatchMethods; separator="\n">
	<extensionMembers; separator="\n">
}
>>

AltLabelStructDecl(struct,attrs,getters,dispatchMethods) ::= <<
@SuppressWarnings("CheckReturnValue")
public static class <struct.escapedName> extends <currentRule.name; format="cap">Context {
	<attrs:{a | public <a>;}; separator="\n">
	<getters:{g | <g>}; separator="\n">
	public <struct.escapedName>(<currentRule.name; format="cap">Context ctx) { copyFrom(ctx); }
	<dispatchMethods; separator="\n">
}
>>

ListenerDispatchMethod(method) ::= <<
@Override
public void <if(method.isEnter)>enter<else>exit<endif>Rule(ParseTreeListener listener) {
	if ( listener instanceof <parser.grammarName>Listener ) ((<parser.grammarName>Listener)listener).<if(method.isEnter)>enter<else>exit<endif><struct.derivedFromName; format="cap">(this);
}
>>

VisitorDispatchMethod(method) ::= <<
@Override
public \<T> T accept(ParseTreeVisitor\<? extends T> visitor) {
	if ( visitor instanceof <parser.grammarName>Visitor ) return ((<parser.grammarName>Visitor\<? extends T>)visitor).visit<struct.derivedFromName; format="cap">(this);
	else return visitor.visitChildren(this);
}
>>

AttributeDecl(d) ::= "<d.type> <d.escapedName><if(d.initValue)> = <d.initValue><endif>"

/** If we don't know location of label def x, use this template */
labelref(x) ::= "<if(!x.isLocal)>((<x.ctx.name>)_localctx).<endif><x.escapedName>"

/** For any action chunk, what is correctly-typed context struct ptr? */
ctx(actionChunk) ::= "((<actionChunk.ctx.name>)_localctx)"

// used for left-recursive rules
recRuleAltPredicate(ruleName,opPrec)  ::= "precpred(_ctx, <opPrec>)"
recRuleSetReturnAction(src,name)	  ::= "$<name>=$<src>.<name>;"
recRuleSetStopToken()                 ::= "_ctx.stop = _input.LT(-1);"

recRuleAltStartAction(ruleName, ctxName, label, isListLabel) ::= <<
_localctx = new <ctxName>Context(_parentctx, _parentState);
<if(label)>
<if(isListLabel)>
_localctx.<label>.add(_prevctx);
<else>
_localctx.<label> = _prevctx;
<endif>
<endif>
pushNewRecursionContext(_localctx, _startState, RULE_<ruleName>);
>>

recRuleLabeledAltStartAction(ruleName, currentAltLabel, label, isListLabel) ::= <<
_localctx = new <currentAltLabel; format="cap">Context(new <ruleName; format="cap">Context(_parentctx, _parentState));
<if(label)>
<if(isListLabel)>
((<currentAltLabel; format="cap">Context)_localctx).<label>.add(_prevctx);
<else>
((<currentAltLabel; format="cap">Context)_localctx).<label> = _prevctx;
<endif>
<endif>
pushNewRecursionContext(_localctx, _startState, RULE_<ruleName>);
>>

recRuleReplaceContext(ctxName) ::= <<
_localctx = new <ctxName>Context(_localctx);
_ctx = _localctx;
_prevctx = _localctx;
>>

recRuleSetPrevCtx() ::= <<
if ( _parseListeners!=null ) triggerExitRuleEvent();
_prevctx = _localctx;
>>


LexerFile(lexerFile, lexer, namedActions) ::= <<
<fileHeader(lexerFile.grammarFileName, lexerFile.ANTLRVersion)>
<if(lexerFile.genPackage)>
package <lexerFile.genPackage>;
<endif>
<namedActions.header>
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
import org.jspecify.annotations.NullUnmarked;
import jakarta.annotation.Generated;

<lexer>
>>

Lexer(lexer, atn, actionFuncs, sempredFuncs, superClass) ::= <<
@NullUnmarked
@Generated("<lexer.name>")
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "NullAway"})
class <lexer.name> extends <superClass; null="Lexer"> {
	// Customization: Suppress version check
	// static { RuntimeMetaData.checkVersion("<lexerFile.ANTLRVersion>", RuntimeMetaData.VERSION); }

	protected static final DFA[] _decisionToDFA;
	protected static final PredictionContextCache _sharedContextCache =
		new PredictionContextCache();
	<if(lexer.tokens)>
	public static final int
		<lexer.tokens:{k | <k>=<lexer.tokens.(k)>}; separator=", ", wrap, anchor>;
	<endif>
	<if(lexer.escapedChannels)>
	public static final int
		<lexer.escapedChannels:{c | <c>=<lexer.escapedChannels.(c)>}; separator=", ", wrap, anchor>;
	<endif>
	<if(rest(lexer.escapedModeNames))>
	public static final int
		<rest(lexer.escapedModeNames):{m | <m>=<i>}; separator=", ", wrap, anchor>;
	<endif>
	public static String[] channelNames = {
		"DEFAULT_TOKEN_CHANNEL", "HIDDEN"<if (lexer.channelNames)>, <lexer.channelNames:{c| "<c>"}; separator=", ", wrap, anchor><endif>
	};

	public static String[] modeNames = {
		<lexer.modes:{m| "<m>"}; separator=", ", wrap, anchor>
	};

	private static String[] makeRuleNames() {
		return new String[] {
			<lexer.ruleNames:{r | "<r>"}; separator=", ", wrap, anchor>
		};
	}
	public static final String[] ruleNames = makeRuleNames();

	<vocabulary(lexer.literalNames, lexer.symbolicNames)>

	<namedActions.members>

	public <lexer.name>(CharStream input) {
		super(input);
		_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
	}

	@Override
	public String getGrammarFileName() { return "<lexer.grammarFileName>"; }

	@Override
	public String[] getRuleNames() { return ruleNames; }

	@Override
	public String getSerializedATN() { return _serializedATN; }

	@Override
	public String[] getChannelNames() { return channelNames; }

	@Override
	public String[] getModeNames() { return modeNames; }

	@Override
	public ATN getATN() { return _ATN; }

	<dumpActions(lexer, "", actionFuncs, sempredFuncs)>
	<atn>
}
>>

SerializedJavaATN(model) ::= <<
<if(rest(model.segments))>
<! requires segmented representation !>
<model.segments:{segment|private static final String _serializedATNSegment<i0> =
	"<segment; wrap={"+<\n><\t>"}>";}; separator="\n">
public static final String _serializedATN = Utils.join(
	new String[] {
		<model.segments:{segment | _serializedATNSegment<i0>}; separator=",\n">
	},
	""
);
<else>
<! only one segment, can be inlined !>
public static final String _serializedATN =
	"<model.serialized; wrap={"+<\n><\t>"}>";
<endif>
public static final ATN _ATN =
	new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
	_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
	for (int i = 0; i \< _ATN.getNumberOfDecisions(); i++) {
		_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
	}
<!	org.antlr.v4.tool.DOTGenerator dot = new org.antlr.v4.tool.DOTGenerator(null);!>
<!	System.out.println(dot.getDOT(_ATN.decisionToState.get(0), ruleNames, false));!>
<!	System.out.println(dot.getDOT(_ATN.ruleToStartState[2], ruleNames, false));!>
}
>>

/** Using a type to init value map, try to init a type; if not in table
 *	must be an object, default value is "null".
 */
initValue(typeName) ::= <<
<javaTypeInitMap.(typeName)>
>>

codeFileExtension() ::= ".java"
