Welcome, guest | Sign In | My Account | Store | Cart
import re


scan = re.compile(flags=re.VERBOSE, pattern=r"""
    (?P<number> \d+\.?\d* ) |
    (?P<operator> \+ | - | \* | / ) |
    (?P<eof> $ ) |
    (?P<error> \S )  # catch all (except whitespace)
""").finditer


def parse(source):
    parser = RPNParser()
    for each in scan(source):
        dispatch = getattr(parser, each.lastgroup)
        dispatch(each.group())
    return parser.stack[0]


class RPNParser(object):

    def __init__(self):
        self.stack = []

    def number(self, token):
        self.stack.append(token)

    def operator(self, token):
        right = self.stack.pop()
        left = self.stack.pop()
        self.stack.append(Expression(left, token, right))

    def eof(self, token):
        if len(self.stack) != 1:
            raise Exception("source kaputt!")

    def error(self, token):
        raise Exception("unknown token %s!" % token)


class Expression(object):

    def __init__(self, *args):
        self.args = args

    def __str__(self):
        return "(%s %s %s)" % self.args


if __name__ == "__main__":

    print parse("1.5 2 + 3.33 1.11 - *")

History

  • revision 2 (14 years ago)
  • previous revisions are not available