def test_parse_success(self): """Make sure ``parse()`` returns the tree on success. There's not much more than that to test that we haven't already vetted above. """ expr = OneOrMore(Literal("a", name="lit"), name="more") text = "aa" eq_(expr.parse(text), Node("more", text, 0, 2, children=[Node("lit", text, 0, 1), Node("lit", text, 1, 2)]))
def test_parse_success(self): """Make sure ``parse()`` returns the tree on success. There's not much more than that to test that we haven't already vetted above. """ expr = OneOrMore(Literal('a', name='lit'), name='more') text = 'aa' self.assertEqual(expr.parse(text), Node(expr, text, 0, 2, children=[ Node(expr.members[0], text, 0, 1), Node(expr.members[0], text, 1, 2)]))
def test_parse_success(self): """Make sure ``parse()`` returns the tree on success. There's not much more than that to test that we haven't already vetted above. """ expr = OneOrMore(Literal('a', name='lit'), name='more') text = 'aa' eq_(expr.parse(text), Node('more', text, 0, 2, children=[ Node('lit', text, 0, 1), Node('lit', text, 1, 2)]))
def _expressions_from_rules(self, rule_syntax): """Return the rules for parsing the grammar definition syntax. Return a 2-tuple: a dict of rule names pointing to their expressions, and then the top-level expression for the first rule. """ # Hard-code enough of the rules to parse the grammar that describes the # grammar description language, to bootstrap: ws = Regex(r'\s+', name='ws') comment = Regex(r'#[^\r\n]*', name='comment') _ = Regex(r'[ \t]+', name='_') label = Regex(r'[a-zA-Z_][a-zA-Z_0-9]*', name='label') quantifier = Regex(r'[*+?]', name='quantifier') # This pattern supports empty literals. TODO: A problem? literal = Regex(r'u?r?"[^"\\]*(?:\\.[^"\\]*)*"', ignore_case=True, dot_all=True, name='literal') regex = Sequence(Literal('~'), literal, Regex('[ilmsux]*', ignore_case=True), name='regex') atom = OneOf(label, literal, regex, name='atom') quantified = Sequence(atom, quantifier, name='quantified') term = OneOf(quantified, atom, name='term') another_term = Sequence(_, term, name='another_term') sequence = Sequence(term, OneOrMore(another_term), name='sequence') or_term = Sequence(_, Literal('/'), another_term, name='or_term') ored = Sequence(term, OneOrMore(or_term), name='ored') expression = OneOf(ored, sequence, term, name='expression') eol = Regex(r'[\r\n$]', name='eol') # TODO: Support $. rule = Sequence(label, Optional(_), Literal('='), Optional(_), expression, Optional(_), Optional(comment), eol, name='rule') rule_or_rubbish = OneOf(rule, ws, comment, name='rule_or_rubbish') rules = OneOrMore(rule_or_rubbish, name='rules') # Use those hard-coded rules to parse the (more extensive) rule syntax. # (For example, unless I start using parentheses in the rule language # definition itself, I should never have to hard-code expressions for # those above.) rule_tree = rules.parse(rule_syntax) # Turn the parse tree into a map of expressions: return RuleVisitor().visit(rule_tree)
def test_parse_failure(self): """Make sure ``parse()`` fails when it doesn't recognize all the way to the end.""" expr = OneOrMore(Literal("a", name="lit"), name="more") text = "aab" eq_(expr.parse(text), None)
def test_parse_failure(self): """Make sure ``parse()`` fails when it doesn't recognize all the way to the end.""" expr = OneOrMore(Literal('a', name='lit'), name='more') text = 'aab' eq_(expr.parse(text), None)
def test_parse_failure(self): """Make sure ``parse()`` fails when it doesn't recognize all the way to the end.""" expr = OneOrMore(Literal('a', name='lit'), name='more') text = 'aab' eq_(expr.parse(text), None)