def program(self, text): """program = {directive} , {statement} , return_statement , "\eof" ;""" self._attempting(text) return concatenation([ zero_or_more( self.directive, ignore_whitespace=True ), zero_or_more( self.statement, ignore_whitespace=True ), self.return_statement, "\\eof", ], ignore_whitespace=True)(text).retyped(TokenType.program)
def test_optional_repetition(self): # Makes sure nested repetitions will terminate. c0 = P.zero_or_more(P.option(P.alternation(["a", "b"]))) t0 = "ababaabbaaab" n0 = c0(t0) self.assertEqual(n0.consumed, len(t0))
def number(self, text): """number = ["-"] . ("0" | digit - "0" . {digit}) . ["." . digit +] ;""" self._attempting(text) return concatenation([ option( "-" ), alternation([ "0", concatenation([ exclusion( self.digit, "0" ), zero_or_more( self.digit, ignore_whitespace=False ), ], ignore_whitespace=False), ]), option( concatenation([ ".", one_or_more( self.digit, ignore_whitespace=False ), ], ignore_whitespace=False) ), ], ignore_whitespace=False)(text).compressed(TokenType.number)
def grammar(self, text): """grammar = {comment} , rule , {comment | rule} ;""" self._attempting(text) return concatenation([ zero_or_more( self.comment, ignore_whitespace=True ), self.rule, zero_or_more( alternation([ self.comment, self.rule, ]), ignore_whitespace=True ), ], ignore_whitespace=True)(text).retyped(TokenType.grammar)
def expression(self, text): """expression = {operator} , expression_terminal , {operator + , expression} ;""" self._attempting(text) return concatenation([ zero_or_more( self.operator, ignore_whitespace=True ), self.expression_terminal, zero_or_more( concatenation([ one_or_more( self.operator, ignore_whitespace=True ), self.expression, ], ignore_whitespace=True), ignore_whitespace=True ), ], ignore_whitespace=True)(text).retyped(TokenType.expression)
def branch(self, text): """branch = branch_if , {branch_elif} , branch_else ; b""" self._attempting(text) return concatenation([ self.branch_if, zero_or_more( self.branch_elif, ignore_whitespace=True ), self.branch_else, ], ignore_whitespace=True)(text).retyped(TokenType.branch)
def test_zero_or_more(self): c0 = P.zero_or_more("a") n0 = c0("ab") self.assertEqual(n0.node_type, P.ParseNodeType.repetition) self.assertEqual(len(n0.children), 1) n1 = c0("aaaaa") self.assertEqual(len(n1.children), 5) n2 = c0("ba") self.assertTrue(n2.is_empty)
def eol(self, text): """eol = { whitespace - "\n" } . "\n" ;""" self._attempting(text) return concatenation([ zero_or_more( exclusion( self.whitespace, "\n" ), ignore_whitespace=False ), "\n", ], ignore_whitespace=False)(text)
def function_args(self, text): """function_args = expression , {"," , function_args} ;""" self._attempting(text) return concatenation([ self.expression, zero_or_more( concatenation([ ",", self.function_args, ], ignore_whitespace=True), ignore_whitespace=True ), ], ignore_whitespace=True)(text)
def string(self, text): """string = '"' . {double_string_char} . '"' | "'" . {single_string_char} . "'" ;""" self._attempting(text) return alternation([ concatenation([ '"', zero_or_more( self.double_string_char, ignore_whitespace=False ), '"', ], ignore_whitespace=False), concatenation([ "'", zero_or_more( self.single_string_char, ignore_whitespace=False ), "'", ], ignore_whitespace=False), ])(text).compressed(TokenType.string)
def number(self, text): """number = digit - "0" . {digit} ;""" self._attempting(text) return concatenation([ exclusion( self.digit, "0" ), zero_or_more( self.digit, ignore_whitespace=False ), ], ignore_whitespace=False)(text).compressed(TokenType.number)
def directive(self, text): """directive = "#" . { all_characters - "\n" } . eol ;""" self._attempting(text) return concatenation([ "#", zero_or_more( exclusion( self.all_characters, "\n" ), ignore_whitespace=False ), self.eol, ], ignore_whitespace=False)(text).compressed(TokenType.directive)
def identifier(self, text): """identifier = (alpha_character | "_") . {alpha_character | "_" | digit} ;""" self._attempting(text) return concatenation([ alternation([ self.alpha_character, "_", ]), zero_or_more( alternation([ self.alpha_character, "_", self.digit, ]), ignore_whitespace=False ), ], ignore_whitespace=False)(text).compressed(TokenType.identifier)
def simple_identifier(self, text): """simple_identifier = (alpha_character | "_") . {alpha_character | digit | "_" | "."} ;""" self._attempting(text) return concatenation([ alternation([ self.alpha_character, "_", ]), zero_or_more( alternation([ self.alpha_character, self.digit, "_", ".", ]), ignore_whitespace=False ), ], ignore_whitespace=False)(text).retyped(TokenType.simple_identifier)
def comment(self, text): """comment = "/*" . {all_characters - "*" | "*" . all_characters - "/"} . "*/" ;""" self._attempting(text) return concatenation([ "/*", zero_or_more( alternation([ exclusion( self.all_characters, "*" ), concatenation([ "*", exclusion( self.all_characters, "/" ), ], ignore_whitespace=False), ]), ignore_whitespace=False ), "*/", ], ignore_whitespace=False)(text).compressed(TokenType.comment)
def comment(self, text): """comment = "(*" . {printable - "*" | "*" . printable - ")"} . "*)" ;""" self._attempting(text) return concatenation([ "(*", zero_or_more( alternation([ exclusion( self.printable, "*" ), concatenation([ "*", exclusion( self.printable, ")" ), ], ignore_whitespace=False), ]), ignore_whitespace=False ), "*)", ], ignore_whitespace=False)(text).compressed(TokenType.comment)