// ------------------------------------------------------------- // 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> )+ |