program <- _ block '.' _ block <- const var procedure statement const <- ('CONST' __ ident '=' _ number (',' _ ident '=' _ number)* ';' _)? var <- ('VAR' __ ident (',' _ ident)* ';' _)? procedure <- ('PROCEDURE' __ ident ';' _ block ';' _)* statement <- (assignment / call / statements / if / while / out / in)? assignment <- ident ':=' _ expression call <- 'CALL' __ ident statements <- 'BEGIN' __ statement (';' _ statement )* 'END' __ if <- 'IF' __ condition 'THEN' __ statement while <- 'WHILE' __ condition 'DO' __ statement out <- ('out' __ / 'write' __ / '!' _) expression in <- ('in' __ / 'read' __ / '?' _) ident condition <- odd / compare odd <- 'ODD' __ expression compare <- expression compare_op expression compare_op <- < '=' / '#' / '<=' / '<' / '>=' / '>' > _ expression <- sign term (term_op term)* sign <- < [-+]? > _ term_op <- < [-+] > _ term <- factor (factor_op factor)* factor_op <- < [*/] > _ factor <- ident / number / '(' _ expression ')' _ ident <- < [a-z] [a-z0-9]* > _ number <- < [0-9]+ > _ ~_ <- [ \t\r\n]* ~__ <- ![a-z0-9_] _