Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import json
- import weakref
- from uc.io.proto.parser import *
- __all__ = ["dogparser"]
- class dogparser (parser):
- other = [
- (r"\[", "other::block::start,;string::literal,list"),
- (r"\]", "other::block::end,"),
- (r"\|", "other::whitespace,")
- ]
- def __init__ (self):
- super(dogparser, self).__init__(
- (r'^#.*', "comment"),
- (r'(?<=\s)#.*', "comment"),
- (r"\{", "block::start"),
- (r"\}", "block::end"),
- (r"\;", "block::split"),
- (r"\d{1,}#[\da-f]*", "number::withbase"),
- (r"\d{1,}", "number::decimal"),
- (r"'(.*?[^\\]|)'" , "string::raw"),
- (r'"(.*?[^\\]|)"', "string::json"),
- (r'[^\s\'"\{:]{1,}:(?!:)', "string::keyword"),
- (r'[^\s\'"\{\}\;\d]{1,}', "string::literal"),
- (r'\s{1,}', "whitespace")
- )
- self.insert(2, *self.other)
- self.ignore |= {'comment', 'whitespace'}
- def apply (self, text):
- for token in super(dogparser, self).apply(text):
- if token.name.startswith("other::"):
- tokens = token.name.split("::", 1)[1].split(";")
- for subtoken in tokens:
- token.name, token.value = subtoken.split(",", 1)
- yield token
- else: yield token
- def parse (self, text):
- return self.tostruct(self.apply(text))
- @classmethod
- def tostruct (cls, tokens, parent=None):
- block = cls.block(parent)
- entry = cls.item()
- kw = None
- for token in tokens:
- arg = None
- if token == "block::start": arg = cls.tostruct(tokens, block)
- elif token.name.startswith("block::"):
- if entry.args: block.append(entry)
- entry, kw = cls.item(), None
- if token == "block::end": break
- elif token == "number::withbase":
- base, num = token.value.split("#")
- arg = int(num, int(base))
- elif token == "number::decimal": arg = int(token.value)
- elif token == "string::raw": arg = token.value[1:-1]
- elif token == "string::json": arg = json.loads(token.value)
- elif token == "string::literal": arg = entry.link(token.value)
- elif token == "string::keyword": kw = token.value[:-1]
- if arg:
- if kw: entry.kwargs[kw] = arg
- else: entry.args.append(arg)
- kw = None
- return block
- class block (list):
- def __init__ (self, parent, *entries):
- super(dogparser.block, self).__init__(entries)
- self.parent = lambda: None if parent is None else weakref.ref(parent)
- def __repr__ (self):
- hp = bool(self.parent())
- res = "{" if hp else ""
- for cmd in self:
- res += str(cmd) + "; "
- if hp: res = res.rstrip("; ") + "}"
- return res
- class item (object):
- def __init__ (self, *args, **kwargs):
- super(dogparser.item, self).__init__()
- self.args = list(args)
- self.kwargs = kwargs
- def __repr__ (self):
- res = "dogparser.item("
- res += ", ".join(repr(s) for s in self.args)
- if self.kwargs:
- res += ", "
- res += ", ".join("{!s}={!r}".format(*i) for i in self.kwargs.items())
- return res + ")"
- def __repr__ (self):
- res = " ".join(repr(a) for a in self.args)
- if self.kwargs:
- res += " "
- res += " ".join("{!s}: {!r}".format(*i) for i in self.kwargs.items())
- return res
- class link (object):
- def __init__ (self, to):
- super(dogparser.item.link, self).__init__()
- self.to = to
- def __repr__ (self):
- return str(self.to)
- return "@" + repr(self.to)
- if __name__ == "__main__":
- from sys import stdin
- p = dogparser()
- while True:
- data = stdin.read() or exit(0)
- print(p.parse(data))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement