LARA

options {
    STATIC = false;
//    LOOKAHEAD = 2;
}
PARSER_BEGIN(WhileParser)
    class WhileParser {
        public static void main(String[] args) throws ParseException, TokenMgrError {
            WhileParser parser = new WhileParser(System.in);
            parser.Start();
        }
    }
PARSER_END(WhileParser)

SKIP : { " " | "\t" | "\n" | "\r" | < "//"(~["\n", "\r"])* ("\n" | "\r" | "\r\n")> }
TOKEN : { < INTLIT: "0" | ["1"-"9"](["0"-"9"])* > }
TOKEN : { < STRLIT: "\"" (~["\"", "\n", "\r"])* "\"" > }
TOKEN : { < NUMBER: (["0"-"9"])+ > }
TOKEN : { < IF: "if" > }
TOKEN : { < ELSE: "else" > }
TOKEN : { < WHILE: "while" > }
TOKEN : { < PRINTLN: "println" > }
TOKEN : { < ID: <LETTER> (<LETTER> | ["0"-"9"])* > | < #LETTER: ["A"-"Z","a"-"z","_"] > }

void Start() :
{}
{
    (Statement())* <EOF>
}

void Statement() :
{}
{
    Print() | Assign() | If() | While() | Block()
}

void Print() :
{}
{
    <PRINTLN> "(" <STRLIT> "," <ID> ")" ";"
}

void Assign() :
{}
{
    <ID> "=" Expr() ";"
}

void If() :
{}
{
    <IF> "(" Expr() ")" Statement() <ELSE> Statement()
}

void While() :
{}
{
    <WHILE> "(" Expr() ")" Statement()
}

void Block() :
{}
{
    "{" (Statement())* "}"
}

void Expr() :
{}
{
    EqExpr() (("&&" | "||") EqExpr())*
}

void EqExpr() :
{}
{
    CompExpr() ("==" CompExpr())*
}

void CompExpr() :
{}
{
    AddExpr() (("<" | ">") AddExpr())*
}

void AddExpr() :
{}
{
    FactExpr() (("+" | "-") FactExpr())*
}

void FactExpr() :
{}
{
    PrimaryExpr() (("*" | "/" | "%") PrimaryExpr())*
}

void PrimaryExpr() :
{}
{
    "(" Expr() ")"
    | <ID>
    | <INTLIT>
    | ("-" | "!") PrimaryExpr()
}