Well, here's a sre-based scanner and recursive-descent parser based on
my understanding of the grammar you gave.
Using a real scanner and parser may or may not be a better choice, but
it's not hard in Python to create a scanner and write a
recursive-descent parser for a simple grammar.
Jeff
------------------------------------------------------------------------
# This code is in the public domain
class PeekableIterato r:
def __init__(self, s):
self.s = iter(s)
self._peek = []
def atend(self):
try:
self.peek()
except StopIteration:
return True
return False
def peek(self):
if not self._peek: self._peek = [self.s.next()]
return self._peek[0]
def next(self):
if self._peek:
return self._peek.pop( )
return self.s.next()
def __iter__(self): return self
def tok(scanner, s):
return s
def num(scanner, s):
try:
return int(s)
except ValueError:
return float(s)
import sre
scanner = sre.Scanner([
(r"/\*(?:[^*]|[*]+[^/])*\*/", None),
(r"\*?[A-Za-z_][A-Za-z0-9_]*", tok),
(r"//.*$", None),
(r"[0-9]*\.[0-9]+|[0-9]+\.?", num),
(r"[{}]", tok),
(r'"(?:[^\\"]|\\.)*"', tok),
(r"[ \t\r\n]*", None),
], sre.MULTILINE)
class Node:
def __init__(self, name):
self.name = name
self.contents = []
def add(self, v): self.contents.a ppend(v)
def __str__(self):
sc = " ".join(map(repr , self.contents))
return "<%s: %s>" % (self.name, sc)
__repr__ = __str__
def parse_nodes(t):
n = []
while 1:
if t.peek() == "}":
t.next()
break
n.append(parse_ node(t))
return n
def parse_contents( n, t):
if t.atend(): return
if t.peek() == "{":
t.next()
for n1 in parse_nodes(t):
n.add(n1)
while 1:
if t.atend(): break
if t.peek() == "}": break
if isinstance(p, basestring) and t.peek().starts with("*"): break
n.add(t.next())
def parse_node(t):
n = Node(t.next())
parse_contents( n, t)
return n
def parse_top(t):
nodes = []
while not t.atend():
yield parse_node(t)
import sys
def main(source = sys.stdin):
tokens, rest = scanner.scan(so urce.read())
if rest:
print "Garbage at end of file:", `rest`
for n in parse_top(Peeka bleIterator(tok ens)):
print n
if __name__ == '__main__': main()
------------------------------------------------------------------------
$ python michael.py < michael.txt # and reindented for show
<*Version: 200>
<*SCENE: <AMBIENT_COLOUR : 0.0 0.0 0.0>>
<*MATERIAL_LIST : <*MATERIAL_COUN T: 0>>
<*GEOMOBJECT:
<*NODE_NAME: '"obj1"'>
<*MESH:
<*MESH_VERTEX_L IST:
<*MESH_VERTEX : 0 0 0 0>
<*MESH_VERTEX : 1 0 1 2>
<*MESH_FACE_LIS T: <*MESH_FACE: 1 2 3>>
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.6 (GNU/Linux)
iD8DBQFBbIQVJd0 1MZaTXX0RAlmXAJ 9CjRfV1w4NQo2wS Ba4doZSWuNvDQCe Kzyd
Z0SHDzDLxFnacVG Nf6PQmtE=
=s51L
-----END PGP SIGNATURE-----