PROGRAM ← STATEMENTS STATEMENTS ← ((COMMAND COMMENT? / COMMENT) EOX)+ ~COMMENT ← ("#" / "comment" / "remark" / "rem") (!([\r\n]+).)* COMMAND ← WORD (ARGUMENTS)? EKEYWORD ← "calculate" / "calc" / "expression" / "expr" PKEYWORD ← "evaluate" / "eval" / "perform" XKEYWORD ← "do" / "end" BLOCK ← "do" EOX? STATEMENTS? "end" / "{" EOX? STATEMENTS? "}" PBLOCK ← PKEYWORD EOX? STATEMENTS? "end" / "[" EOX? STATEMENTS? "]" ARGUMENTS ← (ARGSEP? (BLOCK / PBLOCK / ARGUMENT))* # ARGUMENTS ← PREPOSITION* ARTICLE* ARGUMENT ((ARGSEP? BLOCK) / # (ARGSEP? PBLOCK) / (ARGSEP? ARGUMENT))* ARGSEP ← ',' / ((PREPOSITION / ARTICLE)+) PREPOSITION ← < ( "else" / "otherwise" / "aboard" / "about" / "above" / "across" / "after" / "against" / "alongside"/ "along" / "amidst" / "amidst" / "among" / "around" / "as" / "at" / "atop" / "before" / "behind"/ "below" / "beneath" / "besides" / "beside" / "between" / "beyond"/ "but" / "by" / "circa" / "despite" / "down" / "during"/ "except" / "for" / "from" / "inside" / "into" / "in" / "less" / "like" / "near" / "nothwithstanding" / "off" / "onto" / "on" / "opposite" / "outside" / "out" / "over" / "since" / "than" / "through" / "thru" / "towards" / "throughout" / "to" / "underneath"/ "under" / "unlike" / "until" / "upon" / "upside" / "up" / "versus" / "via" / "within" / "without" / "with" ) > WHITESPACE ~ARTICLE ← <("a" / "an" / "the")> WHITESPACE ARGUMENT ← EXPR # / NUMBER EXPR ← BINEXPR / UNEXPR BINEXPR ← (ATOM (BINOP ATOM)*) UNEXPR ← (UNOP ATOM) ATOM ← STRING / NAME / NUMBER / '(' EXPR ')' / EKEYWORD EXPR "end" KWUNOP ← "not" / "negate" KWBINOP ← "plus" / "minus" / "times" / "divide" / "of" / "'s" / "'" / "and" / "or" / "equals" / "equal" / "is" BINOP ← < [-+/*] / "<-" / "->" "&&"/ "||" / "==" / KWBINOP > UNOP ← < [-!] / KWUNOP > # / "of" / "'s" STRING ← ESCSTR / RAWSTR # Raw string macro RAWSM(O,C) ← O < (!(C).)* > C NAME ← ARTICLE? WORD+ # Escaped string macro. ESCSM(O,C) ← O < (!(C)STRCHAR)* > C ESCSTR ← ESCSM("`", "`") / ESCSM('"', '"') RAWSTR ← RAWSM('<<', '>>') / RAWSM('«', '»') / RAWSM('‹', '›') / RAWSM('“', '”') STRESC1 ← "\\" [nrtfv\'\\"\[\]\\] STRESC2 ← "\\" [0-3] [0-7] [0-7] STRESC3 ← "\\" [0-7] [0-7]* STRESC4 ← "\\x" [0-9a-fA-F] [0-9a-fA-F]? STRESC5 ← "\\u" [0-9a-fA-F]+ STRNOESC ← (!('\\\\').) STRCHAR ← STRESC1 / STRESC2 / STRESC3 / STRESC4 / STRESC5 / STRNOESC NUMBER ← DECIMAL / INTEGER DECIMAL ← < [-]?[0-9]+[.][0-9]+ > INTEGER ← < [-]?[0-9]+ > ~EOX ← ([ \t]*[\r\n.]+[ \t]*)+ KEYWORD ← PREPOSITION / ARTICLE / XKEYWORD / EKEYWORD / KWBINOP / KWUNOP WORD ← !KEYWORD ANYWORD ANYWORD ← < [a-zA-Z][a-zA-Z0-9]* > WHITESPACE ← < [ \t]* > %whitespace ← [ \t]* %word ← [a-zA-Z][-+/*a-zA-Z0-9]* --- # Expression parsing option %expr = BINEXPR # Rule to apply 'precedence climbing method' to %binop = L && || and or %binop = L == equals equal is %binop = L + - plus minus %binop = L * / times divide %binop = L of 's <- -> ' # foo bar baz quux