Grammar Documentation
Grammar Reference
Generated May 5, 2026 · 67 rules · ANTLR3 · Generated by DevDiagrams

grammarDef

entry point
The top-level rule. A grammar file begins with an optional doc comment,
an optional grammar type keyword ('lexer', 'parser', or 'tree'), the
'grammar' keyword, a name, a semicolon, optional options, tokens, and
attribute scope sections, followed by one or more rules.
grammarDef
: DOC_COMMENT?
( 'lexer' {gtype=LEXER_GRAMMAR;} // pure lexer
| 'parser' {gtype=PARSER_GRAMMAR;} // pure parser
| 'tree' {gtype=TREE_GRAMMAR;} // a tree parser
| {gtype=COMBINED_GRAMMAR;} // merged parser/lexer
)
g='grammar' id ';' optionsSpec? tokensSpec? attrScope* action*
rule+
EOF
-> ^( {adaptor.create(gtype,$g)}
id DOC_COMMENT? optionsSpec? tokensSpec? attrScope* action* rule+
)
;
DOC_COMMENT 'lexer' 'parser' 'tree' g = 'grammar' id ';' optionsSpec tokensSpec attrScope action rule EOF

tokensSpec

The tokens section. Declares imaginary token types used in AST
construction that do not correspond to real input tokens.
Delimited by the 'tokens' keyword and a closing '}'.
tokensSpec
: TOKENS tokenSpec+ '}' -> ^(TOKENS tokenSpec+)
;
TOKENS tokenSpec '}'

tokenSpec

A single token declaration within a tokens section. A token may
optionally be assigned a string literal or character literal value
using '='. Terminated by ';'.
tokenSpec
: TOKEN_REF
( '=' (lit=STRING_LITERAL|lit=CHAR_LITERAL) -> ^('=' TOKEN_REF $lit)
| -> TOKEN_REF
)
';'
;
TOKEN_REF '=' lit = STRING_LITERAL lit = CHAR_LITERAL ';'

attrScope

An attribute scope declaration at grammar level. Defines a named
set of shared variables accessible within a dynamic scope using
'scope id ACTION'.
attrScope
: 'scope' id ACTION -> ^('scope' id ACTION)
;
'scope' id ACTION

action

A grammar-level named action such as @members or @header.
Optionally scoped to a specific component (e.g. @parser::members).
action
: '@' (actionScopeName '::')? id ACTION -> ^('@' actionScopeName? id ACTION)
;
'@' actionScopeName '::' id ACTION

actionScopeName

The scope name in a grammar-level action. Normally an identifier,
but 'lexer' and 'parser' are also permitted as scope names even
though they are keywords.
actionScopeName
: id
| l='lexer' -> ID[$l]
| p='parser' -> ID[$p]
;
id l = 'lexer' p = 'parser'

optionsSpec

The options section. Contains one or more key=value option pairs
delimited by the 'options' keyword and a closing '}'.
optionsSpec
: OPTIONS (option ';')+ '}' -> ^(OPTIONS option+)
;
OPTIONS option ';' '}'

option

A single key=value option pair within an options section.
option
: id '=' optionValue -> ^('=' id optionValue)
;
id '=' optionValue

optionValue

The value of an option. May be an identifier, string literal,
character literal, integer, or '*' (used for k=*).
optionValue
: id
| STRING_LITERAL
| CHAR_LITERAL
| INT
| s='*' -> STRING_LITERAL[$s] // used for k=*
;
id STRING_LITERAL CHAR_LITERAL INT s = '*'

rule

A single grammar rule. May be a parser rule (lowercase name) or a
lexer rule (uppercase name). Optionally preceded by a doc comment
and an access modifier ('protected', 'public', 'private', or
'fragment'). May include arguments, return values, a throws clause,
options, scope declarations, and named actions. The rule body is a
colon-separated list of alternatives terminated by ';'.
rule
scope {
String name;
}
: DOC_COMMENT?
( modifier=('protected'|'public'|'private'|'fragment') )?
id {$rule::name = $id.text;}
'!'?
( arg=ARG_ACTION )?
( 'returns' rt=ARG_ACTION )?
throwsSpec? optionsSpec? ruleScopeSpec? ruleAction*
':' altList ';'
exceptionGroup?
-> ^( RULE id {modifier!=null?adaptor.create(modifier):null} ^(ARG $arg)? ^(RET $rt)?
optionsSpec? ruleScopeSpec? ruleAction*
altList
exceptionGroup?
EOR["EOR"]
)
;
DOC_COMMENT modifier = 'protected' 'public' 'private' 'fragment' id '!' arg = ARG_ACTION 'returns' rt = ARG_ACTION throwsSpec optionsSpec ruleScopeSpec ruleAction ':' altList ';' exceptionGroup

ruleAction

A named action attached to a rule, such as @init or @after.
Executed at the start or end of the rule respectively.
ruleAction
: '@' id ACTION -> ^('@' id ACTION)
;
'@' id ACTION

throwsSpec

A throws clause listing the exception types a rule may throw.
Introduced by 'throws' followed by a comma-separated list of
identifiers.
throwsSpec
: 'throws' id ( ',' id )* -> ^('throws' id+)
;
'throws' id ',' id

ruleScopeSpec

The scope specification for a rule. Defines a dynamic scope local
to the rule (ACTION form), references a previously declared named
scope (id list form), or both.
ruleScopeSpec
: 'scope' ACTION -> ^('scope' ACTION)
| 'scope' id (',' id)* ';' -> ^('scope' id+)
| 'scope' ACTION
'scope' id (',' id)* ';'
-> ^('scope' ACTION id+ )
;
'scope' ACTION 'scope' id ',' id ';' 'scope' ACTION 'scope' id ',' id ';'

block

A parenthesized block of alternatives. May have an optional options
section and colon separator before the first alternative. Used for
subrules and token sets.
block
: lp='('
( (opts=optionsSpec)? ':' )?
a1=alternative rewrite ( '|' a2=alternative rewrite )*
rp=')'
-> ^( BLOCK[$lp,"BLOCK"] optionsSpec? (alternative rewrite?)+ EOB[$rp,"EOB"] )
;
lp = '(' opts = optionsSpec ':' a1 = alternative rewrite '|' a2 = alternative rewrite rp = ')'

altList

A list of alternatives at rule level, separated by '|'. Forms the
body of a rule between ':' and ';'.
altList
@init {
// must create root manually as it's used by invoked rules in real antlr tool.
// leave here to demonstrate use of {...} in rewrite rule
// it's really BLOCK[firstToken,"BLOCK"]; set line/col to previous ( or : token.
CommonTree blkRoot = (CommonTree)adaptor.create(BLOCK,input.LT(-1),"BLOCK");
}
: a1=alternative rewrite ( '|' a2=alternative rewrite )*
-> ^( {blkRoot} (alternative rewrite?)+ EOB["EOB"] )
;
a1 = alternative rewrite '|' a2 = alternative rewrite

alternative

A single alternative — a sequence of one or more elements. An empty
alternative (epsilon) is also permitted and produces an EPSILON node
in the AST.
alternative
@init {
Token firstToken = input.LT(1);
Token prevToken = input.LT(-1); // either : or | I think
}
: element+ -> ^(ALT[firstToken,"ALT"] element+ EOA["EOA"])
| -> ^(ALT[prevToken,"ALT"] EPSILON[prevToken,"EPSILON"] EOA["EOA"])
;
element

exceptionGroup

A group of exception handlers and an optional finally clause
following a rule body. At least one exceptionHandler or a
finallyClause must be present.
exceptionGroup
: ( exceptionHandler )+ ( finallyClause )?
| finallyClause
;
exceptionHandler finallyClause finallyClause

exceptionHandler

A single catch clause. Consists of 'catch', an argument action
specifying the exception type and variable, and an action body.
exceptionHandler
: 'catch' ARG_ACTION ACTION -> ^('catch' ARG_ACTION ACTION)
;
'catch' ARG_ACTION ACTION

finallyClause

A finally clause. Consists of 'finally' and an action body that
is always executed after the rule completes.
finallyClause
: 'finally' ACTION -> ^('finally' ACTION)
;
'finally' ACTION

element

A single element within an alternative. Delegates to
elementNoOptionSpec.
element
: elementNoOptionSpec
;
elementNoOptionSpec

elementNoOptionSpec

An element within an alternative, without options. May be a labeled
atom or block (using '=' or '+=' assignment), an atom or block with
an optional EBNF suffix, a standalone EBNF expression, an action,
a semantic predicate, or a tree specification.
elementNoOptionSpec
: id (labelOp='='|labelOp='+=') atom
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] ^($labelOp id atom) EOA["EOA"]) EOB["EOB"]))
| -> ^($labelOp id atom)
)
| id (labelOp='='|labelOp='+=') block
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] ^($labelOp id block) EOA["EOA"]) EOB["EOB"]))
| -> ^($labelOp id block)
)
| atom
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] atom EOA["EOA"]) EOB["EOB"]) )
| -> atom
)
| ebnf
| ACTION
| SEMPRED ( '=>' -> GATED_SEMPRED | -> SEMPRED )
| treeSpec
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] treeSpec EOA["EOA"]) EOB["EOB"]) )
| -> treeSpec
)
;
id labelOp = '=' labelOp = '+=' atom ebnfSuffix id labelOp = '=' labelOp = '+=' block ebnfSuffix atom ebnfSuffix ebnf ACTION SEMPRED '=>' treeSpec ebnfSuffix

atom

An atomic grammar element. May be a character range, a terminal
symbol, a negated set, or a rule reference. Rule references and
terminals may optionally be suffixed with '^' (AST root) or '!'
(exclude from AST). Rule references may also carry an argument
action.
atom:   range ( (op='^'|op='!') -> ^($op range) | -> range )
| terminal
| notSet ( (op='^'|op='!') -> ^($op notSet) | -> notSet )
| RULE_REF ( arg=ARG_ACTION )? ( (op='^'|op='!') )?
-> {$arg!=null&&op!=null}? ^($op RULE_REF $arg)
-> {$arg!=null}? ^(RULE_REF $arg)
-> {$op!=null}? ^($op RULE_REF)
-> RULE_REF
;
range op = '^' op = '!' terminal notSet op = '^' op = '!' RULE_REF arg = ARG_ACTION op = '^' op = '!'

notSet

A negated element using '~'. Matches any token or character not in
the specified terminal or block. Used in both parser and lexer rules.
notSet
: '~'
( notTerminal -> ^('~' notTerminal)
| block -> ^('~' block)
)
;
'~' notTerminal block

treeSpec

A tree construction pattern used in tree grammar rules.
Introduced by '^(' and closed by ')'. Must contain at least two
elements — a root node and one or more child elements.
treeSpec
: '^(' element ( element )+ ')' -> ^(TREE_BEGIN element+)
;
'^(' element element ')'

ebnf

An EBNF expression: a block optionally followed by '?' (optional),
'*' (closure), or '+' (positive closure). '=>' introduces a
syntactic predicate. A block with no suffix is treated as a plain
grouped alternative.
ebnf
@init {
Token firstToken = input.LT(1);
}
@after {
$ebnf.tree.getToken().setLine(firstToken.getLine());
$ebnf.tree.getToken().setCharPositionInLine(firstToken.getCharPositionInLine());
}
: block
( op='?' -> ^(OPTIONAL[op] block)
| op='*' -> ^(CLOSURE[op] block)
| op='+' -> ^(POSITIVE_CLOSURE[op] block)
| '=>' // syntactic predicate
-> {gtype==COMBINED_GRAMMAR &&
Character.isUpperCase($rule::name.charAt(0))}?
// if lexer rule in combined, leave as pred for lexer
^(SYNPRED["=>"] block)
// in real antlr tool, text for SYN_SEMPRED is predname
-> SYN_SEMPRED
| -> block
)
;
block op = '?' op = '*' op = '+' '=>'

range

A character range used in lexer rules. Matches a single character
between two character literals, inclusive, using the '..' operator.
range!
: c1=CHAR_LITERAL RANGE c2=CHAR_LITERAL -> ^(CHAR_RANGE[$c1,".."] $c1 $c2)
;
c1 = CHAR_LITERAL RANGE c2 = CHAR_LITERAL

terminal

A terminal element. May be a character literal, a token reference
(optionally with arguments), a string literal, or '.' (wildcard
matching any token or character). May be suffixed with '^' (AST
root) or '!' (exclude from AST).
terminal
: ( CHAR_LITERAL -> CHAR_LITERAL
// Args are only valid for lexer rules
| TOKEN_REF
( ARG_ACTION -> ^(TOKEN_REF ARG_ACTION)
| -> TOKEN_REF
)
| STRING_LITERAL -> STRING_LITERAL
| '.' -> '.'
)
( '^' -> ^('^' $terminal)
| '!' -> ^('!' $terminal)
)?
;
CHAR_LITERAL TOKEN_REF ARG_ACTION STRING_LITERAL '.' '^' '!'

notTerminal

A terminal element used within a negated set ('~'). May be a
character literal, token reference, or string literal. Does not
permit AST operators or arguments.
notTerminal
: CHAR_LITERAL
| TOKEN_REF
| STRING_LITERAL
;
CHAR_LITERAL TOKEN_REF STRING_LITERAL

ebnfSuffix

An EBNF suffix operator applied to an atom or block. '?' makes the
preceding element optional, '*' allows zero or more repetitions,
and '+' requires one or more repetitions.
ebnfSuffix
@init {
Token op = input.LT(1);
}
: '?' -> OPTIONAL[op]
| '*' -> CLOSURE[op]
| '+' -> POSITIVE_CLOSURE[op]
;
'?' '*' '+'

rewrite

A rewrite rule following an alternative, introduced by '->'.
Multiple predicated rewrites may precede the final unconditional
rewrite. If no '->' is present the alternative produces no rewrite.
rewrite
@init {
Token firstToken = input.LT(1);
}
: (rew+='->' preds+=SEMPRED predicated+=rewrite_alternative)*
rew2='->' last=rewrite_alternative
-> ^($rew $preds $predicated)* ^($rew2 $last)
|
;
rew += '->' preds += SEMPRED predicated += rewrite_alternative rew2 = '->' last = rewrite_alternative

rewrite_alternative

A single rewrite alternative. May be a StringTemplate template
reference, a tree construction alternative, or empty (epsilon).
rewrite_alternative
options {backtrack=true;}
: rewrite_template
| rewrite_tree_alternative
| /* empty rewrite */ -> ^(ALT["ALT"] EPSILON["EPSILON"] EOA["EOA"])
;
rewrite_template rewrite_tree_alternative

rewrite_tree_block

A parenthesized block within a tree rewrite expression.
rewrite_tree_block
: lp='(' rewrite_tree_alternative ')'
-> ^(BLOCK[$lp,"BLOCK"] rewrite_tree_alternative EOB[$lp,"EOB"])
;
lp = '(' rewrite_tree_alternative ')'

rewrite_tree_alternative

A sequence of one or more tree rewrite elements forming a single
rewrite alternative.
rewrite_tree_alternative
: rewrite_tree_element+ -> ^(ALT["ALT"] rewrite_tree_element+ EOA["EOA"])
;
rewrite_tree_element

rewrite_tree_element

A single element within a tree rewrite alternative. May be an atom,
an atom with an EBNF suffix, a tree node with an optional suffix,
or an EBNF block.
rewrite_tree_element
: rewrite_tree_atom
| rewrite_tree_atom ebnfSuffix
-> ^( ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] rewrite_tree_atom EOA["EOA"]) EOB["EOB"]))
| rewrite_tree
( ebnfSuffix
-> ^(ebnfSuffix ^(BLOCK["BLOCK"] ^(ALT["ALT"] rewrite_tree EOA["EOA"]) EOB["EOB"]))
| -> rewrite_tree
)
| rewrite_tree_ebnf
;
rewrite_tree_atom rewrite_tree_atom ebnfSuffix rewrite_tree ebnfSuffix rewrite_tree_ebnf

rewrite_tree_atom

An atomic element within a tree rewrite expression. May be a
character literal, token reference (with optional arguments),
rule reference, string literal, label reference (via '$'), or
an action.
rewrite_tree_atom
: CHAR_LITERAL
| TOKEN_REF ARG_ACTION? -> ^(TOKEN_REF ARG_ACTION?) // for imaginary nodes
| RULE_REF
| STRING_LITERAL
| d='$' id -> LABEL[$d,$id.text] // reference to a label in a rewrite rule
| ACTION
;
CHAR_LITERAL TOKEN_REF ARG_ACTION RULE_REF STRING_LITERAL d = '$' id ACTION

rewrite_tree_ebnf

An EBNF expression within a tree rewrite: a parenthesized block
followed by an EBNF suffix operator ('?', '*', or '+').
rewrite_tree_ebnf
@init {
Token firstToken = input.LT(1);
}
@after {
$rewrite_tree_ebnf.tree.getToken().setLine(firstToken.getLine());
$rewrite_tree_ebnf.tree.getToken().setCharPositionInLine(firstToken.getCharPositionInLine());
}
: rewrite_tree_block ebnfSuffix -> ^(ebnfSuffix rewrite_tree_block)
;
rewrite_tree_block ebnfSuffix

rewrite_tree

A tree node construction in a rewrite rule. Introduced by '^('
with a root atom followed by zero or more child elements, closed
by ')'.
rewrite_tree
: '^(' rewrite_tree_atom rewrite_tree_element* ')'
-> ^(TREE_BEGIN rewrite_tree_atom rewrite_tree_element* )
;
'^(' rewrite_tree_atom rewrite_tree_element ')'

rewrite_template

A StringTemplate template rewrite. May be an inline template
definition, a named template reference, an indirect template
reference (expression in parentheses), or a raw action that
evaluates to a StringTemplate instance.
rewrite_template
: // -> template(a={...},...) "..." inline template
id lp='(' rewrite_template_args ')'
( str=DOUBLE_QUOTE_STRING_LITERAL | str=DOUBLE_ANGLE_STRING_LITERAL )
-> ^(TEMPLATE[$lp,"TEMPLATE"] id rewrite_template_args $str)

| // -> foo(a={...}, ...)
rewrite_template_ref

| // -> ({expr})(a={...}, ...)
rewrite_indirect_template_head

| // -> {...}
ACTION
;
id lp = '(' rewrite_template_args ')' str = DOUBLE_QUOTE_STRING_LITERAL str = DOUBLE_ANGLE_STRING_LITERAL rewrite_template_ref rewrite_indirect_template_head ACTION

rewrite_template_ref

A named StringTemplate template reference with arguments.
e.g. -> foo(a={...}, ...)
rewrite_template_ref
: id lp='(' rewrite_template_args ')'
-> ^(TEMPLATE[$lp,"TEMPLATE"] id rewrite_template_args)
;
id lp = '(' rewrite_template_args ')'

rewrite_indirect_template_head

An indirect StringTemplate template reference where the template
name is computed by an expression in parentheses.
e.g. -> ({expr})(a={...}, ...)
rewrite_indirect_template_head
: lp='(' ACTION ')' '(' rewrite_template_args ')'
-> ^(TEMPLATE[$lp,"TEMPLATE"] ACTION rewrite_template_args)
;
lp = '(' ACTION ')' '(' rewrite_template_args ')'

rewrite_template_args

The argument list for a StringTemplate template rewrite. A
comma-separated list of named arguments, or empty.
rewrite_template_args
: rewrite_template_arg (',' rewrite_template_arg)*
-> ^(ARGLIST rewrite_template_arg+)
| -> ARGLIST
;
rewrite_template_arg ',' rewrite_template_arg

rewrite_template_arg

A single named argument in a template argument list.
e.g. a={...}
rewrite_template_arg
: id '=' ACTION -> ^(ARG[$id.start] id ACTION)
;
id '=' ACTION

id

An identifier. TOKEN_REF and RULE_REF are both mapped to the
imaginary ID token type, normalizing the distinction between
uppercase and lowercase names where a plain identifier is needed.
id  :   TOKEN_REF -> ID[$TOKEN_REF]
| RULE_REF -> ID[$RULE_REF]
;
TOKEN_REF RULE_REF

SL_COMMENT

A single-line comment beginning with '//'. Routed to the hidden
channel. Also handles the special '$ANTLR src' directive which
resets the reported file and line number.
SL_COMMENT
: '//'
( ' $ANTLR ' SRC // src directive
| ~('\r'|'\n')*
)
'\r'? '\n'
{$channel=HIDDEN;}
;
'//' ' $ANTLR ' SRC ~ '\r' '\n' '\r' '\n'

ML_COMMENT

A multi-line comment delimited by '/*' and '* /'. Routed to the
hidden channel unless the next character after '/*' is '*', in
which case it is classified as a DOC_COMMENT.
ML_COMMENT
: '/*' {if (input.LA(1)=='*') $type=DOC_COMMENT; else $channel=HIDDEN;} .* '*/'
;
'/*' . '*/'

CHAR_LITERAL

A single-quoted character literal. Contains exactly one
LITERAL_CHAR (which may be an escape sequence).
CHAR_LITERAL
: '\'' LITERAL_CHAR '\''
;
'\'' LITERAL_CHAR '\''

STRING_LITERAL

A single-quoted string literal. Contains two or more LITERAL_CHAR
characters. (A single character is matched as CHAR_LITERAL instead.)
STRING_LITERAL
: '\'' LITERAL_CHAR LITERAL_CHAR* '\''
;
'\'' LITERAL_CHAR LITERAL_CHAR '\''

LITERAL_CHAR

A single character within a quoted literal. May be an escape
sequence or any character except single quote and backslash.
fragment
LITERAL_CHAR
: ESC
| ~('\''|'\\')
;
ESC ~ '\'' '\\'

DOUBLE_QUOTE_STRING_LITERAL

A double-quoted string literal. Used in StringTemplate template
inline definitions in rewrite rules.
DOUBLE_QUOTE_STRING_LITERAL
: '"' (ESC | ~('\\'|'"'))* '"'
;
'"' ESC ~ '\\' '"' '"'

DOUBLE_ANGLE_STRING_LITERAL

A double-angle-bracket string literal using '<<' and '>>'.
Used as an alternative form of inline StringTemplate definition.
DOUBLE_ANGLE_STRING_LITERAL
: '<<' .* '>>'
;
'<<' . '>>'

ESC

An escape sequence within a string or character literal. Supports
standard escapes (n, r, t, b, f, quote, backslash), '>' (used in
StringTemplate), and Unicode escapes (\uXXXX). Unknown escapes are
passed through as-is.
fragment
ESC : '\\'
( 'n'
| 'r'
| 't'
| 'b'
| 'f'
| '"'
| '\''
| '\\'
| '>'
| 'u' XDIGIT XDIGIT XDIGIT XDIGIT
| . // unknown, leave as it is
)
;
'\\' 'n' 'r' 't' 'b' 'f' '"' '\'' '\\' '>' 'u' XDIGIT XDIGIT XDIGIT XDIGIT .

XDIGIT

A single hexadecimal digit. Used within Unicode escape sequences.
fragment
XDIGIT :
'0' .. '9'
| 'a' .. 'f'
| 'A' .. 'F'
;
'0'..'9' 'a'..'f' 'A'..'F'

INT

One or more decimal digits forming a non-negative integer literal.
Used in options (e.g. k=2) and character ranges.
INT :   '0'..'9'+
;
'0'..'9'

ARG_ACTION

An argument action enclosed in square brackets '[' and ']'.
Used to pass arguments to rules and token references. The
surrounding brackets are stripped from the token text.
ARG_ACTION
: NESTED_ARG_ACTION
;
NESTED_ARG_ACTION

NESTED_ARG_ACTION

The inner matching logic for ARG_ACTION. Handles nested argument
actions, string literals, character literals, and arbitrary content
between '[' and ']'.
fragment
NESTED_ARG_ACTION :
'['
( options {greedy=false; k=1;}
: NESTED_ARG_ACTION
| ACTION_STRING_LITERAL
| ACTION_CHAR_LITERAL
| .
)*
']'
{setText(getText().substring(1, getText().length()-1));}
;
'[' NESTED_ARG_ACTION ACTION_STRING_LITERAL ACTION_CHAR_LITERAL . ']'

ACTION

A target-language action enclosed in curly braces '{' and '}'.
If immediately followed by '?' it is reclassified as a SEMPRED
(semantic predicate).
ACTION
: NESTED_ACTION ( '?' {$type = SEMPRED;} )?
;
NESTED_ACTION '?'

NESTED_ACTION

The inner matching logic for ACTION. Handles nested actions,
single-line comments, multi-line comments, string literals,
character literals, and arbitrary content between '{' and '}'.
fragment
NESTED_ACTION :
'{'
( options {greedy=false; k=2;}
: NESTED_ACTION
| SL_COMMENT
| ML_COMMENT
| ACTION_STRING_LITERAL
| ACTION_CHAR_LITERAL
| .
)*
'}'
;
'{' NESTED_ACTION SL_COMMENT ML_COMMENT ACTION_STRING_LITERAL ACTION_CHAR_LITERAL . '}'

ACTION_CHAR_LITERAL

A character literal appearing inside an action. Handles escaped
characters within single quotes.
fragment
ACTION_CHAR_LITERAL
: '\'' (ACTION_ESC|~('\\'|'\'')) '\''
;
'\'' ACTION_ESC ~ '\\' '\'' '\''

ACTION_STRING_LITERAL

A string literal appearing inside an action. Handles escaped
characters within double quotes.
fragment
ACTION_STRING_LITERAL
: '"' (ACTION_ESC|~('\\'|'"'))* '"'
;
'"' ACTION_ESC ~ '\\' '"' '"'

ACTION_ESC

An escape sequence within an action string or character literal.
Handles escaped single quote, escaped double quote, and any other
backslash-escaped character.
fragment
ACTION_ESC
: '\\\''
| '\\' '"' // ANTLR doesn't like: '\\"'
| '\\' ~('\''|'"')
;
'\\\'' '\\' '"' '\\' ~ '\'' '"'

TOKEN_REF

A token reference. Begins with an uppercase letter followed by
zero or more letters, digits, or underscores. Used to name lexer
rules and imaginary token types.
TOKEN_REF
: 'A'..'Z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
'A'..'Z' 'a'..'z' 'A'..'Z' '_' '0'..'9'

RULE_REF

A rule reference. Begins with a lowercase letter followed by
zero or more letters, digits, or underscores. Used to name parser
and tree grammar rules.
RULE_REF
: 'a'..'z' ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*
;
'a'..'z' 'a'..'z' 'A'..'Z' '_' '0'..'9'

OPTIONS

The 'options' keyword followed by optional whitespace and '{'.
Matched as a single token to prevent the '{' from being treated
as the start of an action.
OPTIONS
: 'options' WS_LOOP '{'
;
'options' WS_LOOP '{'

TOKENS

The 'tokens' keyword followed by optional whitespace and '{'.
Matched as a single token to prevent the '{' from being treated
as the start of an action.
TOKENS
: 'tokens' WS_LOOP '{'
;
'tokens' WS_LOOP '{'

SRC

The '$ANTLR src' directive embedded in a single-line comment.
Resets the reported source file name and line number, useful when
the grammar file has been generated from another source.
fragment
SRC : 'src' ' ' file=ACTION_STRING_LITERAL ' ' line=INT
;
'src' ' ' file = ACTION_STRING_LITERAL ' ' line = INT

WS

Whitespace: spaces, tabs, carriage returns, and newlines.
Routed to the hidden channel so the parser does not see it.
WS  :   (   ' '
| '\t'
| '\r'? '\n'
)+
{$channel=HIDDEN;}
;
' ' '\t' '\r' '\n'

WS_LOOP

Whitespace and comment loop used within OPTIONS and TOKENS token
rules to skip over any whitespace or comments between the keyword
and the opening '{'.
fragment
WS_LOOP
: ( WS
| SL_COMMENT
| ML_COMMENT
)*
;
WS SL_COMMENT ML_COMMENT