program = importDeclaration* , (typeDefinition | functionDeclaration)* , mainFunction;
importDeclaration = "import" , identifier , ";";
typeDefinition = "type" , identifier , gomType , ";";
functionDeclaration = "fn" , identifier , "(" , argumentItem* , ")" , functionReturnType? ,
"{" , statement+ , "}";
mainFunction = "fn" , "main" , "(" , argumentItem* , ")" , functionReturnType? ,
"{" , statement+ , "}";
statement = ifStatement
| forStatement
| returnStatement
| letStatement
| expressionStatement;
forStatement = "for" , "(" , expr , ";" , expr , ";" , ")" , "{" , statement* , "}";
returnStatement = "return" , expr , ";";
letStatement = "let" , identifier , "=" , expr , ";";
expressionStatement = expr , ";";
gomType = primitiveType | compositeType , primitiveType?;
argumentItem = identifier , ":" , gomType , ","?;
functionReturnType = ":" , gomType;
expr = access
| call
| "(" , expr , ")"
| comparison;
access = identifier , ("." , (identifier | call))+;
call = identifier , "(" , term* , ")";
comparison = sum , "<" , sum
| sum , ">" , sum
| sum , "<=" , sum
| sum , ">=" , sum
| sum , "==" , sum
| sum;
sum = quot , "+" , quot
| quot , "-" , quot
| quot;
quot = expo , "/" , expo
| expo , "*" , expo
| term;
term = identifier | numLiteral | stringLiteral;
identifier = letter , (letter | digit)*;
numLiteral = digit+;
stringLiteral = '"' , (letter | digit)* , '"';
primitiveType = "i8" | "i16" | "f16" | "str";
compositeType = identifier;
letter = "A" | "B" | "C" | "D" | "E" | "F" | "G"
| "H" | "I" | "J" | "K" | "L" | "M" | "N"
| "O" | "P" | "Q" | "R" | "S" | "T" | "U"
| "V" | "W" | "X" | "Y" | "Z" | "a" | "b"
| "c" | "d" | "e" | "f" | "g" | "h" | "i"
| "j" | "k" | "l" | "m" | "n" | "o" | "p"
| "q" | "r" | "s" | "t" | "u" | "v" | "w"
| "x" | "y" | "z" ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
S = (#x20 | #x9 | #xD | #xA)+