ANTLR4 and the goal of Python

I am having problems with the Python target in ANTLR4. It seems that very few examples are available, and the transition to the corresponding Java code does not seem relevant.

I use the standard Hello.g4 grammar:

// Define a grammar called Hello grammar Hello; r : 'hello' ID ; // match keyword hello followed by an identifier ID : [az]+ ; // match lower-case identifiers WS : [ \t\r\n]+ -> skip ; // skip spaces, tabs, newlines 

Example (built from the standard Hello.g4 example):

 input_ = antlr4.FileStream(_FILENAME) lexer = HelloLexer.HelloLexer(input_) stream = antlr4.CommonTokenStream(lexer) parser = HelloParser.HelloParser(stream) rule_name = 'r' tree = getattr(parser, rule_name)() 

I also wrote a listener. To confirm / verify that this is correct, I will repeat here:

 class HelloListener(antlr4.ParseTreeListener): def enterR(self, ctx): print("enterR") def exitR(self, ctx): print("exitR") def enterId(self, ctx): print("enterId") def exitId(self, ctx): print("exitId") 

So, firstly, I cannot guarantee that the line I am giving is valid because I am not getting any output to the screen. How can I define a tree object if something was matched? How to extract the relevant rules / tokens?

A Python example would be great if possible.

+7
python antlr antlr4
source share
3 answers

I hear you having the same problems right now. The Python documentation for v4 is useless, and v3 is different in what it can be used. I am thinking of switching to Java to implement my stuff.

As for your code: I think your own custom listener should inherit from the generated HelloListener. You can do the print there.

Also try parsing invalid input to see if the parser is running at all. I'm not sure about the line with getattr (parser, rule_name) (), though. I followed the steps in the (unfortunately very short) documentation for the Python Antlr4 target: https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Python+Target

You can also find listener documentation. Hope this helps.

+3
source share

I created an example for Python 2 using Hello grammar.

Here is the relevant code:

 from antlr4 import * from HelloLexer import HelloLexer from HelloListener import HelloListener from HelloParser import HelloParser import sys class HelloPrintListener(HelloListener): def enterHi(self, ctx): print("Hello: %s" % ctx.ID()) def main(): lexer = HelloLexer(StdinStream()) stream = CommonTokenStream(lexer) parser = HelloParser(stream) tree = parser.hi() printer = HelloPrintListener() walker = ParseTreeWalker() walker.walk(printer, tree) if __name__ == '__main__': main() 

As fabs said, the key should inherit from the generated HelloListener. There seems to be some sort of attraction in this question, as you can see if you change your HelloPrintListener inheritance directly from the ANTLR ParseTreeListener . I assumed this would work, since the generated HelloListener only has empty methods, but I saw the same behavior that you saw (listener methods are never called).

Despite the lack of documentation for Python listeners, the methods available are similar to Java.

0
source share

The antlr documentation has been updated to document support for the purposes of python 3 and python 4. Examples from the antlr book converted to python3 can be found here , they are enough for anyone to get started.

0
source share

All Articles