(* new version *) program = {expression | comment}; comment = ";", [ascii]; expression = rvalue | assign; rvalue = arith | compare | call | coll; compare = rvalue, compare_op, rvalue; arith = term, [term_op, term]; builtin = "write"; (* TODO: add more *) call = "do", "(", builtin, {["," rvalue]}, ")"; compare_op = "eq" | "neq" | "gt" | "gte" | "lt" | "lte"; term_op = "+" | "-"; term = factor, [factor_op, factor]; factor_op = "*" | "/"; factor = real | "(", rvalue, ")" | ident; real = {"-"}, double; double = [digit], {".", [digit]}; assign = ident, "=", expression; ident = alpha, [alpha]; (* old version *) identifier = alpha, [{alpha, digit, "_"}]; coll = "[", rvalue, [{",", rvalue}], "]"; seq = "|", rvalue, [{",", rvalue}], "|"; real = {"-"}, digit, [".", {digit}]; collection = coll | seq; builtin = "map" | "fold" | "filter" | "zip" | "read" | "write" | "length"; fn = "func", "(", [ident, {",", ident}], ")", "{", {state}, "}"; rvalue = (identifier | real | '(', expr, ')') | collection | fn; arith = rvalue, ("+" | "-" | "*" | "/"), rvalue; logic = rvalue, ("or" | "and", "xor"); condition = rvalue, ("<" | ">" | "==" | "<=" | ">="), rvalue; binop = arith | logic | condition; unop = "not"; expr = assign | ([unop] rvalue, [ binop, expr ] ('\n' | ';')); if = "if", expr, {state}, ["elif", expr, {state}], ["else", {state}], "done"; while = "while", expr, {state}, "done"; state = expr | if | while; call = "do", "(", builtin, {",", rvalue}, ")"; assign = identifier, "=", (call | rvalue | expr); program = {state} (* missing return *) (* no support for ';' yet *) (* no support for 'elif' yet *)