在Python2.7 ANTLR4中,从解析器规则中提取令牌并将其存储在列表中



在我的语法中,我验证如下所示的布尔表达式:

((foo == true) && (bar != false) || (qux == norf))

我通过调用getText():

从ANTLR4的上下文对象中获得字符串
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])

相关内容

  • 没有找到相关文章

最新更新