PROGRAM -> DECL { DECL } DECL -> VAR_DECL | FUNC_DECL | STRUCT_DECL VAR_DECL -> "var" TYPE NAME ";" FUNC_DECL -> "func" [ "ret" TYPE ] NAME "(" [ PARAM_DECL { "," PARAM_DECL } ] ")" "{" { DECL } { STMT } "}" STRUCT_DECL -> "struct" NAME "{" { VAR_DECL } "}" PARAM_DECL -> [ "ref" ] TYPE NAME EXP -> EXP LOG_OP EXP | "!" EXP | EXP REL_OP EXP | EXP ARIT_OP EXP | "(" EXP ")" | LITERAL | CALL | "new" NAME "(" ")" | VAR VAR -> NAME | EXP "." NAME LOG_OP -> "&&" | "||" REL_OP -> "<" | "<=" | ">" | ">=" | "=" | "!=" ARIT_OP -> "+" | "-" | "*" | "/" | "**" LITERAL -> FLOAT_LITERAL | INT_LITERAL | STRING_LITERAL | "true" | "false" | "null" STMT -> ASSIGN_STMT | IF_STMT | WHILE_STMT | RETURN_STMT | CALL_STMT ASSIGN_STMT -> VAR ":=" EXP ";" IF_STMT -> "if" EXP "then" { STMT } [ "else" { STMT } ] "endif" WHILE_STMT -> "while" EXP "do" "{" { STMT } "}" RETURN_STMT -> "return" [ EXP ] ";" CALL_STMT -> CALL ";" CALL -> NAME "(" [ ACTUAL_PARAM { "," ACTUAL_PARAM } ] ")" ACTUAL_PARAM -> "ref" VAR | EXP TYPE -> "float" | "int" | "string" | "bool" | NAME