Ok, I'm quite new to Python

Jeff Epler jepler at unpythonic.net
Wed Oct 13 03:25:42 CEST 2004


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 PeekableIterator:
    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.append(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().startswith("*"): 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(source.read())
    if rest:
        print "Garbage at end of file:", `rest`
    for n in parse_top(PeekableIterator(tokens)):
        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_COUNT: 0>>
<*GEOMOBJECT:
    <*NODE_NAME: '"obj1"'>
    <*MESH:
        <*MESH_VERTEX_LIST:
            <*MESH_VERTEX: 0 0 0 0>
            <*MESH_VERTEX: 1 0 1 2>
        >
        <*MESH_FACE_LIST: <*MESH_FACE: 1 2 3>>
    >
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/python-list/attachments/20041012/ee4fe5aa/attachment.sig>


More information about the Python-list mailing list