except ZeroDivisionError: return None return ret res = reduce(F, args, z) return res eval = unarg(eval_expr) number = sometok('number') >> make_number name = sometok('name') >> make_name string = sometok('string') >> make_string func = sometok('func') >> make_func value = number | name | string makeop = lambda s, f: op(s) >> const(f) add = makeop('+', (ets.add, operator.add)) sub = makeop('-', (ets.sub, operator.sub)) mul = makeop('*', (ets.mul, operator.mul)) div = makeop('/', (ets.div, operator.div)) mul_op = mul | div add_op = add | sub args = fwd() factor = fwd() primary = value call = func + op_('(') + args + op_(')') >> exec_func term = factor + many(mul_op + factor ) >> eval expr = term + many(add_op + term ) >> eval
Spec('number', r'-?(\.[0-9]+)|([0-9]+(\.[0-9]*)?)'), Spec('string', r'"[^"]*"'), # '\"' escapes are ignored ] useless = ['comment', 'newline', 'space'] t = make_tokenizer(specs) return [x for x in t(str) if x.type not in useless] id = sometoks(['name', 'number', 'string']) make_graph_attr = lambda args: DefAttrs(u'graph', [Attr(*args)]) make_edge = lambda x, xs, attrs: Edge([x] + xs, attrs) node_id = memoize(id) # + maybe(port) a_list = ( id + maybe(op_('=') + id) + skip(maybe(op(','))) >> unarg(Attr)) attr_list = ( many(op_('[') + many(a_list) + op_(']')) >> flatten) attr_stmt = ( (n('graph') | n('node') | n('edge')) + attr_list >> unarg(DefAttrs)) graph_attr = id + op_('=') + id >> make_graph_attr node_stmt = node_id + attr_list >> unarg(Node) # We use a fwd() because of circular definitions like (stmt_list -> stmt -> # subgraph -> stmt_list) subgraph = fwd() edge_rhs = skip(op('->') | op('--')) + (subgraph | node_id) edge_stmt = (