BNF for VaporParser.jj

TOKENS

// -------------------------------------------------------------
// Tokens

// Whitespace and Comments
<DEFAULT> SKIP : {
" "
| "\t"
| <LineComment: "//" (~["\n","\r"])*>
| <BlockComment: "/*" (~["*"])* "*" ("*" | ~["*","/"] (~["*"])* "*")* "/">
}

   
<DEFAULT> TOKEN : {
<#Digit: ["0"-"9"]>
| <Digits: (<Digit>)+>
| <NegDigits: "-" <Digits>> : {
| <#IdentHead: ["a"-"z","A"-"Z","_"]>
| <#IdentRest: <IdentHead> | <Digit> | ".">
| <Eol: (("\r")* "\n" ([" ","\t"])*)+>
}

   
<DEFAULT> MORE : {
<LitStrStart: "\""> : WITHIN_STRING
}

   
<WITHIN_STRING> TOKEN : {
<LitStr: "\""> : DEFAULT
}

   
<WITHIN_STRING> MORE : {
<EscapeQuote: "\\\""> : {
| <EscapeBackslash: "\\\\"> : {
| <NormalStringContent: [" "-"~"]>
}

   
// -------------------------------------------------------------
<DEFAULT> TOKEN : {
<#Ident: <IdentHead> (<IdentRest>)*>
| <RegIdent: "$" <Ident>> : {
| <CodeLabelIdent: <Ident> ":"> : {
| <LabelRefIdent: ":" <Ident>> : {
| <PlainIdent: <Ident>>
}

   
// Catch-all token.
<*> TOKEN : {
<Anything: ~[]>
}

   

NON-TERMINALS

// (The rest of the tokens are defined as we use them in the grammar.)

// -------------------------------------------------------------
// Parser
// -------------------------------------------------------------
Program ::= ( Eol )? ( Function | DataSegment )* <EOF>
DataSegment ::= ( "const" | "var" ) Ident Eol ( ( DataValue )+ Eol )*
Function ::= "func" Ident ( "(" ( VarRefNoReg )* ")" )? ( "[" "in" <Digits> "," "out" <Digits> "," "local" <Digits> "]" )? Eol ( ( CodeLabel ( Eol | Instr ) | Instr ) )*
Instr ::= ( Return | MemRead | MemWrite | Assign | Branch | Goto | Call | BuiltIn )
MemRead ::= VarRef "=" MemRef Eol
MemWrite ::= MemRef "=" Operand Eol
MemRef ::= ( StackMemRef | GlobalMemRef )
StackMemRef ::= ( "in" | "out" | "local" ) "[" <Digits> "]"
GlobalMemRef ::= "[" DataAddr ( ( "+" | "-" ) <Digits> )? "]"
Assign ::= VarRef "=" Operand Eol
Branch ::= ( "if" | "if0" ) Operand "goto" CodeLabelRef Eol
Goto ::= "goto" CodeAddr Eol
Call ::= ( VarRefNoReg "=" )? "call" FuncAddr ( "(" ( OperandNoReg )* ")" )? Eol
BuiltIn ::= ( VarRef "=" )? Ident "(" ( Operand )* ")" Eol
Return ::= "ret" ( OperandNoReg )? Eol
DataValue ::= ( LabelRef | LitInt )
Operand ::= ( LabelRef | LitInt | LitStr | VarRef )
LabelRef ::= <LabelRefIdent>
CodeAddr ::= ( CodeLabelRef | VarRef )
DataAddr ::= ( DataSegmentRef | VarRef )
FuncAddr ::= ( FuncRef | VarRef )
CodeLabelRef ::= <LabelRefIdent>
DataSegmentRef ::= <LabelRefIdent>
FuncRef ::= <LabelRefIdent>
VarRef ::= ( Ident | <RegIdent> )
VarRefNoReg ::= VarRef
OperandNoReg ::= Operand
LitInt ::= ( <Digits> | <NegDigits> )
LitStr ::= <LitStr>
Ident ::= ( <PlainIdent> | "func" | "const" | "var" | "in" | "out" | "local" | "if" | "if0" | "goto" | "ret" | "call" )
CodeLabel ::= <CodeLabelIdent>
Eol ::= ( <Eol> )+