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}\)")