繁体   English   中英

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

[英]In Python2.7 ANTLR4, extract tokens from a parser rule and store them in a list

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

((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类,其中包含访问每种子节点类型的方法。 例如ctx的参数enterBody()方法是实例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])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM