Skip to content

Instantly share code, notes, and snippets.

@sma
Created February 21, 2009 19:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sma/68143 to your computer and use it in GitHub Desktop.
Save sma/68143 to your computer and use it in GitHub Desktop.
# node = '(' NAME {attribute} {node} ')'
# attribute = NAME '=' VALUE
import re
class Node(object):
def __init__(self, name, attributes=None, children=None):
self.name, self.attributes, self.children = name, attributes or {}, children or []
def __repr__(self):
return "(%s%s%s%s%s)" % (
self.name,
" " if self.attributes else "",
" ".join("%s=%r" % i for i in self.attributes.items()),
" " if self.children else "",
" ".join(repr(c) for c in self.children)
)
def Scanner(s):
for m in re.finditer(r'''(\w+)|"([^"]*)"|'([^']*)'|([()=])|#.*?\n|\s+''', s):
if m.lastindex:
t = m.group(m.lastindex)
if m.lastindex == 1: yield "name", t
elif m.lastindex in (2, 3): yield "value", t
elif m.lastindex == 4: yield t, t
yield None, None
class Parser(object):
def __init__(self, scanner):
self.scanner = scanner; self.advance()
def advance(self):
self.t, self.v = self.scanner.next()
def expect(self, t):
if self.t != t: raise SyntaxError, t + " expected"
v = self.v; self.advance(); return v
def node(self):
self.expect('(')
node = Node(self.expect("name"))
while self.t == "name": self.attribute(node)
while self.t == '(': node.children.append(self.node())
self.expect(')')
return node
def attribute(self, node):
name = self.expect("name"); self.expect("=")
node.attributes[name] = self.expect("value")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment