Mercurial > lcfOS
diff python/parserlib.py @ 212:62386bcee1ba
Added parser combinator lib
author | Windel Bouwman |
---|---|
date | Sun, 30 Jun 2013 19:00:41 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/parserlib.py Sun Jun 30 19:00:41 2013 +0200 @@ -0,0 +1,83 @@ + + + +class Token: + pass + +# Base functions: +class Pbase: + def __init__(self): + self.pa = None + def parse(self, txt): + r = self.do(txt) + if r: + match, rest = r + # Apply action: + if self.ParseAction: + match = self.ParseAction(match) + return match, rest + else: + # TODO: fail in some way + pass + def getParseAction(self): + return self.pa + def setParseAction(self, pa): + self.pa = pa + + ParseAction = property(getParseAction, setParseAction) + +# basic elements: + +class Literal(Pbase): + def __init__(self, s): + super().__init__() + self.pat = s + def do(self, txt): + if txt.startswith(self.pat): + return self.pat, txt[len(self.pat):] + +class Or(Pbase): + def __init__(self, options): + super().__init__() + self.options = options + def do(self, txt): + for option in self.options: + r = option.parse(txt) + if r: + return r + +class And: + def __init__(self, options): + self.options = options + +class Sequence(Pbase): + def __init__(self, seq): + super().__init__() + self.seq = seq + def do(self, txt): + results = [] + for thung in self.seq: + r = thung.parse(txt) + if r: + res, txt = r + results.append(res) + else: + return + return results, txt + +class Optional(Pbase): + def __init__(self, thung): + super().__init__() + self.thung = thung + def do(self, txt): + r = self.thung.do(txt) + if r: + return r + return (0, txt) + +# Contraptions of basic blocks: + +def OneOrMore(): + def __init__(self, thingy): + pass +