在我的语法中,我验证如下所示的布尔表达式:
((foo == true) && (bar != false) || (qux == norf))
我通过调用getText()
:
def enterBody(self, ctx):
expression = ctx.condition.getText() # condition here being shorthand for a grammar rule (`condition=expr`)
然而,字符串返回整个(即每个单独的标记之间没有空格),我无法知道每个标记是什么:
((foo==true)&&(bar!=false)||(qux==norf))
理想情况下,我希望它以以下格式存储在列表中:
['(', '(', 'foo', '==', 'true', ')', '&&', '(', 'bar', '!=', 'false', ')', '||', '(', 'qux', '==', 'norf', ')', ')']
ANTLR4 Python文档相当稀疏,我不确定是否有方法可以完成此操作。
Python运行时与Java运行时非常相似,因此您可以查看Java文档,很可能在Python中存在相同的方法。或者浏览源代码,相当容易阅读。
你要求得到一个字符串的平面列表。但是解析器的整个思想就是避免这种情况。所以我认为这很可能不是你需要的东西。一定要了解解析树和监听器的工作方式。基本上,你应该使用树而不是平面列表。你要找的可能是ParserRuleContext.getChildren()
。您可以使用它来访问所有子节点:
def enterBody(self, ctx):
print(list(ctx.getChildren()))
更有可能的是,您希望访问特定类型的子节点以执行某些操作。看看ANTLR为您生成的解析器。你会发现一堆*Context
类,其中包含访问每种类型的子节点的方法。例如,enterBody()
方法的ctx
参数是BodyContext
的实例,您可以使用它的所有方法来访问特定类型的子节点。
UPD如果您的语法只定义一个布尔表达式,并且仅将其用于验证和标记化,则根本不需要解析器。只需使用lexer获取所有令牌的列表:
input_stream = antlr4.FileStream('input.txt')
# Instantiate an run generated lexer
lexer = BooleanLexer(input_stream)
tokens = antlr4.CommonTokenStream(lexer)
# Parse all tokens until EOF
tokens.fill()
# Print tokens as text (EOF is stripped from the end)
print([token.text for token in tokens.tokens][:-1])