def BNF():
global bnf<EOL>if not bnf:<EOL><INDENT>point = Literal( "<STR_LIT:.>" )<EOL>e     = CaselessKeyword( "<STR_LIT:E>" )<EOL>pi    = CaselessKeyword( "<STR_LIT>" )<EOL>fnumber = Regex(r"<STR_LIT>")<EOL>ident = Word(alphas, alphanums+"<STR_LIT>")<EOL>plus, minus, mult, div = map(Literal, "<STR_LIT>")<EOL>lpar, rpar = map(Suppress, "<STR_LIT>")<EOL>addop  = plus | minus<EOL>multop = mult | div<EOL>expop = Literal( "<STR_LIT>" )<EOL>expr = Forward()<EOL>atom = ((<NUM_LIT:0>,None)*minus + ( pi | e | fnumber | ident + lpar + expr + rpar | ident ).setParseAction( pushFirst ) |<EOL>Group( lpar + expr + rpar )).setParseAction(pushUMinus)<EOL>factor = Forward()<EOL>factor << atom + ZeroOrMore( ( expop + factor ).setParseAction( pushFirst ) )<EOL>term = factor + ZeroOrMore( ( multop + factor ).setParseAction( pushFirst ) )<EOL>expr << term + ZeroOrMore( ( addop + term ).setParseAction( pushFirst ) )<EOL>bnf = expr<EOL><DEDENT>return bnf<EOL>
expop   :: '^'
multop  :: '*' | '/'
addop   :: '+' | '-'
integer :: ['+' | '-'] '0'..'9'+
atom    :: PI | E | real | fn '(' expr ')' | '(' expr ')'
factor  :: atom [ expop factor ]*
term    :: factor [ multop factor ]*
expr    :: term [ addop term ]*