我在ANTLR4中使用Python目标时遇到了问题。似乎很少有可用的示例,并且查找相应的Java代码似乎无关紧要。
我用的是标准的Hello。g4语法:
// Define a grammar called Hello
grammar Hello;
r : 'hello' ID ; // match keyword hello followed by an identifier
ID : [a-z]+ ; // match lower-case identifiers
WS : [ trn]+ -> skip ; // skip spaces, tabs, newlines
示例(从标准的Hello。g4):
input_ = antlr4.FileStream(_FILENAME)
lexer = HelloLexer.HelloLexer(input_)
stream = antlr4.CommonTokenStream(lexer)
parser = HelloParser.HelloParser(stream)
rule_name = 'r'
tree = getattr(parser, rule_name)()
我还写了一个监听器。为了断言/验证这是正确的,我将在这里重复:
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")
首先,我不能保证我给它的字符串是有效的因为我没有得到任何屏幕输出。如何从树对象中判断是否匹配了任何内容?如何提取匹配规则/令牌?
如果可能的话,一个Python的例子会很棒。
我知道你现在也有同样的问题。v4的Python文档是无用的,v3的差异太大而无法使用。我正在考虑切换回Java来实现我的东西。
关于你的代码:我认为你自己的自定义侦听器必须从生成的hellollistener继承。你可以在那里打印。
还要尝试解析无效输入,看看解析器是否启动。我不确定行与getattr(解析器,rule_name)()虽然。我遵循了Antlr4 Python目标文档中的步骤(不幸的是非常短):https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Python+Target
您还可以在那里找到一些关于侦听器的文档。
这个问题似乎很老了,但我也有同样的问题,并找到了如何处理它。当在python中使用字符串时,你必须使用这里指出的函数antlr4.InputStream
所以,最后,你可以得到一个使用这种代码的工作示例(基于图灵的答案和dzone的示例)
from antlr4 import *
from grammar.HelloListener import HelloListener
from grammar.HelloLexer import HelloLexer
from grammar.HelloParser import HelloParser
import sys
class HelloPrintListener(HelloListener):
def enterHi(self, ctx):
print("Hello: %s" % ctx.ID())
def main():
giveMeInput = input ("say hello XXXXn")
print("giveMeInput is {0}".format(giveMeInput))
# https://www.programcreek.com/python/example/93166/antlr4.InputStream
# https://groups.google.com/forum/#!msg/antlr-discussion/-9VJ5H9NcDs/OukVNCTQCAAJ
i_stream = InputStream(giveMeInput)
lexer = HelloLexer(i_stream)
t_stream = CommonTokenStream(lexer)
parser = HelloParser(t_stream)
tree = parser.hi()
printer = HelloPrintListener()
walker = ParseTreeWalker()
walker.walk(printer, tree)
if __name__ == '__main__':
main()
antlr文档已更新,以记录对python 3和python 4目标的支持。从antlr书中转换到python3的示例可以在这里找到,它们足以让任何人入门。
我为Python 2创建了一个使用Hello语法的示例。
相关代码如下:
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()
如上文所述,关键是从生成的hellollistener继承。在这个问题上似乎有些挑剔,正如您可以看到的,如果您修改我的HelloPrintListener
以直接继承ANTLR的ParseTreeListener
。我认为这可以工作,因为生成的HelloListener
只有空方法,但是我看到了与您看到的相同的行为(从未调用侦听器方法)。
尽管缺乏Python侦听器的文档,但可用的方法与Java相似。