start		::=	statement ";" | expression ";"

statement	::=	var_decl | fn_decl | fn_call 
			| return_stat | print_stat | println_stat
			| assign_stat | if_stat | for_stat | while_stat

body		::=	(statement ";")*

clause		::=	(statement ";")+

var_decl	::=	VAR ident_list

fn_decl		::=	FUNCTION identifier "(" (ident_list)? ")" body END

ident_list	::=	identifier ("," identifier)*

fn_call		::=	identifier "(" (exp_list)? ")"

exp_list	::=	expression ("," expression)*

return_stat	::=	RETURN (expression | condition)

print_stat  	::= 	PRINT print_list

println_stat  	::= 	PRINTLN (print_list)?

print_list	::=	(expression | STRING) ("," (expression | STRING))*

assign_stat      ::=    (IDNUM | IDSET) "=" expression
			| IDBOOL "=" condition

if_stat		::=	IF condition THEN clause elifs (ELSE clause)? FI

elifs		::=	(ELIF condition THEN clause)*

for_stat	::=	FOR IDNUM IN exp_list DO body END

while_stat	::=	WHILE condition DO body END

condition	::=	and_clause ("|" condition)*

and_clause	::=	not_clause ("&" and_clause)*

not_clause	::=	"!" not_clause | "(" condition ")" | comparison | fn_call | boolean

comparison	::=	expression comparator expression

comparator	::=	"<" | "<=" | ">" | ">=" |"==" | "!=" | "=in" | "!in"

expression	::=	("+" | "-")? product (("+" | "-") expression)*

product		::=	term (("*" | "/" | "%") product)*

term		::=	"(" expression ")" | "|" expression "|" | fn_call | simple_term

simple_term	::=	IDNUM | IDSET | NUMBER | interval | set_const | set_former

interval	::=	"[" expression "," expression "]"

set_const	::=	"{"  (exp_list)? "}"

set_former	::=	"{" IDNUM (IN expression)? "|" condition "}"

identifier	::=	IDNUM | IDSET | IDBOOL

boolean		::=	IDBOOL| TRUE | FALSE