import copy
import re

class Success(object):

    def __init__(self, val, rest):
        self.val  = val
        self.rest = rest

    def __str__(self):
        return 'Success(' + repr(self.val) + ', ' + repr(self.rest) + ')'

class Failure(object):

    def __init__(self, rest):
        self.rest = rest

    def __str__(self):
        return 'Failure(' + repr(self.rest) + ')'

class Trampoline(object):

    def __init__(self):
        self.stack = []
        self.table = {}

    def hasNext(self):
        return self.stack != []

    def step(self):
        if self.hasNext():
            (fn, argList) = self.stack.pop()
            fn(*argList)

    def pushCall(self, fn, *argList):
        self.stack.append((fn, argList))

    def push(self, fn, string, cont):

        def tableRef(fn, string):
            if fn in self.table:
                fnMemo = self.table[fn]

                if string not in fnMemo:
                    fnMemo[string] = ([], {})

                return fnMemo[string]
            else:
                entry = ([], {})
                fnMemo = {string : entry}

                self.table[fn] = fnMemo

                return entry

        entry = tableRef(fn, string)

        if not entry[0] and not entry[1]:
            entry[0].append(cont)

            def myCont(result):
                if str(result) not in entry[1]:
                    entry[1][str(result)] = result

                    tempList = copy.deepcopy(entry[0])

                    for c in tempList:
                        c(result)

            self.pushCall(fn, string, self, myCont)
        else:
            entry[0].append(cont)

            tempDict = copy.deepcopy(entry[1])

            for sr, r in tempDict.iteritems():
                cont(r)

    def run(self):
        while self.hasNext():
            self.step()

allCaches = []

def memo(fn):
    cache = {}
    allCaches.append(cache)

    def memo_wrapper(*args):
        sargs = str(args)

        if sargs not in cache:
            cache[sargs] = fn(*args)
        return cache[sargs]

    return memo_wrapper

@memo
def succeed(val):

    def f(string, tramp, cont):
        cont(Success(val, string))

    return f

@memo
def lit(match):

    def f(string, tramp, cont):
        length = min(len(string), len(match))

        head = string[0:length]
        tail = string[length:]

        if head == match:
            cont(Success(head, tail))
        else:
            cont(Failure(string))

    return f

@memo
def reg(pattern):

    def f(string, tramp, cont):
        result = re.findall('^' + pattern, string)

        if not result:
            cont(Failure(string))
        else:
            result = result[0]
            length = len(result)

            head = string[0:length]
            tail = string[length:]

            cont(Success(head, tail))

    return f

def bind(p, fn):

    def f(string, tramp, cont):

        def myCont(result):
            if isinstance(result, Success):
                fn(result.val)(result.rest, tramp, cont)
            else:
                cont(result)

        tramp.push(p, string, myCont)

    return f

@memo
def seq(plist):

    def seq_(a, b):
        def f1(x):
            def f2(y):
                return succeed(x + [y])
            return bind(b, f2)
        return bind(a, f1)

    return reduce(seq_, plist, succeed([]))

@memo
def alt(plist):

    def f(string, tramp, cont):
        for p in plist:
            tramp.push(p, string, cont)

    return f

@memo
def rep1(p):

    def f(string, tramp, cont):
        tramp.push(seq([p, rep1(p)]), string, cont)
        tramp.push(p, string, cont)

    return f

@memo
def rep0(p):

    def f(string, tramp, cont):
        tramp.push(rep1(p), string, cont)
        tramp.push(succeed([]), string, cont)

    return f

@memo
def opt(p):

    def f(string, tramp, cont):
        tramp.push(p, string, cont)
        tramp.puch(succeed([]), string, cont)

    return f

@memo
def ws(p):

    def f(string, tramp, cont):
        tramp.push(seq([reg(r'[\s]*'), p, reg(r'[\s]*')]), string, cont)

    return f

@memo
def red(p, fn):

    def f(val):
        if type(val) == type([]):
            return succeed(fn(*val))
        else:
            return succeed(fn(val))

    return bind(p, f)

def runParser(parser, string):
    results = []
    tramp = Trampoline()

    for cache in allCaches:
        cache.clear()

    def myCont(result):
        if isinstance(result, Success) and result.rest == '':
            results.append(result)

    tramp.push(parser, string, myCont)
    tramp.run()

    return results

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #

expr = (lambda *_:
    alt([ red( seq([expr, lit('+'), term]),
               lambda x, _, y: x + y),
          red( seq([expr, lit('-'), term]),
               lambda x, _, y: x - y),
          term]) (*_))

term = (lambda *_:
    alt([ red( seq([term, lit('*'), factor]),
               lambda x, _, y: x * y),
          red( seq([term, lit('/'), factor]),
               lambda x, _, y: x / y),
          factor]) (*_))

factor = (lambda *_:
    alt ([ red( seq([ws(lit('(')), expr, ws(lit(')'))]),
                lambda _, e, __: e),
           red( seq([ws(lit('-')), factor]),
                lambda _, f: -f),
           number]) (*_))

number = red( ws(reg(r'[-+]?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?')),
              lambda _, n, __: float(n))

results = runParser(expr, '0.1*( \r1 + 2  *  5 \t+ -(15\n- 10) - - - 2*-1/0.5)')
print '\n'.join([str(r) for r in results]), '\n', len(results), 'result(s)'