Short description of the JavaCC grammar file

options { optional, see documentation of JavaCC
name = value ; ...
}
PARSER_BEGIN(name) identifies parser-class and filename
package path; optional, defines package
import path; ... optional, will be copied
public class name ... { must define class of parser
...
}
PARSER_END(name)
rule ...

Names, constants, comments and embedded Java code follow the rules of Java.

Syntactic rules

type name ( ... ) throws ... : defines methods and nonterminals/symbols
{ locals } defines local variables
{ formula } specifies nonterminal/symbol

formula is a sequence of patterns:

re regular expression, recognizes token
lval = re and assignes token
name ( ... ) recognizes nonterminal/symbol
lval = name ( ... ) and assignes result
... | ... alternative
( ... ) grouping
( ... )* n-times, where n >=0
( ... )?  or   [ ... ] optional
( ... )+ n-times, where n >=1
{ ... } java programcode, e.g. with return
LOOKAHEAD( ... ) controls lookahead, see documentation


Lexical rules

< state , ... > optional, defines name of state
TOKEN Scanner returns token to parser
[ IGNORE_CASE ] optional: with this option, the scanner is not sensitive to lower/upper case
:
{ re detects input
{ ... } optional, scanner executes this while scanning
: state optional, defines next state
| ...
}

You can ignore input with SKIP, you can collect input for the next TOKEN with MORE and you can combine input with the next TOKEN  with SPECIAL_TOKEN, see documentation.

re is a regular expression:

"..." Java string, represents itself:
< name : pattern > defines pattern
< #name : pattern > defines local pattern
< name > references pattern
< EOF > represents End Of File (EOF)

pattern is one of the following patterns:

"..." Java string, represents itself
< name > references pattern
... | ... alternative
( ... ) grouping
( ... )* n-times, where n >= 0
( ... )? optional
( ... )+ n-times, where n >= 1
[ ... , ... ] list of characters
~ [ ... , ... ] complement of a list of characters
"x" one character of a list
"x" - "y" an area of characters in the list

Short Reference of jjtree instructions

jjtree pushes nodes for nonterminals/symbols on an internal stack and combines them typically pro nonterminal/symbol:

type name ( ... ) throws ... : creates ASTname-node.
type name ( ... ) throws ... #class : creates ASTclass-node.
type name ( ... ) throws ... #void : creates no node, the same (local) effect as (the global option) NODE_DEFAULT_VOID = true.

The scope of a nonterminal/symbol starts, whenever the nonterminal/symbol is called. Detected nonterminals/symbols store the created nodes in their scope. Postfix-operatars inline and at groups can influence, how many nodes are combined and stored:

#class(number) creates ASTclass-nodes with number children.
#class(condition) if condition is true, the ASTclass-node with all the nodes in its scope will be created.
#class(>1) Special case: creates ASTclass-node, whenever more than 1 child exists.
#class Special case: creates ASTclass-node with all the children in its scope.

You can acces the nodes by using the variable jjtThis, which represents the node, which is currently created.

You can use methods like jjtGetChild(...), which returns a child node of jjtThis, and nodeCreated(), which returns if nodes were created (useful e.g. in the case that the node is conditionally created).