Skip to content

Instantly share code, notes, and snippets.

@startling
Created May 4, 2012 19:40
Show Gist options
  • Save startling/2597240 to your computer and use it in GitHub Desktop.
Save startling/2597240 to your computer and use it in GitHub Desktop.

Embedded in a string, a la Pymeta

parser = Parser("""
integer ::= \d+
atom ::= integer | s_expression
atoms ::= (atom,?\s*)*
s_expression ::= "(" atoms ")"
""")

embedded in a file, which amounts to the same thing

parser = Parser.from_file("grammar.txt")

## as methods

class MyParser(Parser):
    def integer(self):
        return pattern("\d+")

    def atom(self):
        return choice(self.integer(), self.s_expression)

    def atoms(self):
        return many(sequence(self.atom(), pattern(",?\s*")))

    def s_expression(self):
        return sequence(string('('), self.atoms(), string(")"))

as attributes

class MyParser(Parser):
    integer = pattern("\d+")
    atom = choice(integer, s_expression) # -> wouldn't work, since s_expression
                                         #    is undefined at the moment.
    atoms = many(sequence(atom, pattern(",?\s*")))
    s_expression = sequence(string("("), atoms, string(")"))

Or some property magic to mix the two.

class MyParser(Parser):
    integer = pattern("\d+")

    @property
    def atom(self):
        return choice(self.integer, self.s_expression)
    # would other things in the class body be able to refer to this? I have no idea

    atoms = many(sequence(atom, pattern(",?\s*")))
    s_expression = sequence(string("("), atoms, string(")"))

or regex-like patterns

class MyParser(Parser):
    integer = pattern("\d+")
    atom = pattern("{integer}|{s_expression}")
    atoms = pattern("({atom},?\s*)+")
    s_expression = pattern("\({atoms}\)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment