// ------------------------------------------------------------- // 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: ~[]> } |
// (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> )+ |