erikrose / parsimonious

The fastest pure-Python PEG parser I can muster
MIT License
1.82k stars 128 forks source link

Issue with NodeVisitor #136

Closed botzill closed 6 years ago

botzill commented 6 years ago

I have a simple example like this:

from parsimonious.grammar import Grammar, NodeVisitor

class MyNodeVisitor(NodeVisitor):
    grammar = Grammar("""
text = "My name is "(name)"!"
name = ~"[a-zA-Z]+"
""")

    def visit_text(self, node, visited_children):
        print("Text", node.text)
        return node

    def visit_name(self, node, visited_children):
        print("Name", node.text)
        return node

    # def generic_visit(self, node, visited_children):
    #     pass

mv = MyNodeVisitor()
node = mv.parse("My name is Geo!")

While I implement all visit_ methods I still get the error:

 node.expr.as_rule())
parsimonious.exceptions.VisitationError: NotImplementedError: No visitor method was defined for this expression: "My name is "

Parse tree:
<Node matching "My name is ">  <-- *** We were here. ***

Any ideas why I'm doing wrong?

Seb35 commented 6 years ago

First, thanks for this example, I didn’t find such example to use the visitor nodes.

I made it work just by de-commenting your generic visit. By default, the generic_visit raises the exception NotImplementedError (see nodes.py).

If I understand correctly, only the rules have a name (this line), and your node "My name is " is anonyous and hence cannot have a visit function. The generic_visit is almost mandatory, as soon as there are anonymous nodes.

Seb35 commented 6 years ago

This issue is similar to #110.

erikrose commented 6 years ago

I think you've pegged it, @Seb35. Thanks!