在 Python2.7 ANTLR4 中,从解析器规则中提取标记并将它们存储在列表中

问题描述 投票:0回答:1

在我的语法中,我验证看起来像这样的布尔表达式:

((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 parsing antlr antlr4 grammar
1个回答
2
投票

Python 运行时与 Java 运行时非常相似,因此您可以查看 Java 文档,很可能 Python 中存在相同的方法。或浏览源代码,非常容易阅读。

你要求得到一个简单的字符串列表。但是解析器的整个思想就是避免这种情况。所以我认为这很可能不是你需要的东西。确保了解 parse tree 以及 listeners 的工作方式。基本上你应该使用树而不是平面列表。您可能正在寻找的是

ParserRuleContext.getChildren()
。您可以使用它来访问所有子节点:

def enterBody(self, ctx):
    print(list(ctx.getChildren()))

更有可能的是,您想访问特定类型的子节点以执行某些操作。看一下 ANTLR 为您生成的解析器。你会发现一堆

*Context
类,其中包含访问每种类型的子节点的方法。例如,
ctx
方法的
enterBody()
参数是
BodyContext
的实例,您可以使用它的所有方法来访问其特定类型的子节点。

UPD 如果你的语法只定义了一个布尔表达式并且你只将它用于验证和标记化,你根本不需要解析器。只需使用词法分析器获取所有标记的列表:

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])
© www.soinside.com 2019 - 2024. All rights reserved.