我正在为一个小型查询语言构建一个ANTLR解析器。根据定义,查询语言是模糊的,我们需要所有可能的解释(AST)来处理查询。
Example:
query : CLASSIFIED_TOKEN UNCLASSIFIED_TOKEN
| ANY_TOKEN UNCLASSIFIED_TOKEN
;
在这种情况下,如果输入匹配两个规则,我需要获得两个解释的2个AST。 ANTLR将返回第一个匹配的AST。
你知道一种简单的方法来获得相同语法的所有可能的AST吗?我正在考虑多次运行解析器,“关闭”迭代之间已经匹配的规则;这看起来很脏。有更好的主意吗?也许其他具有java支持的lex / parser工具可以做到这一点?
由于
答案 0 :(得分:2)
如果我是你,我会消除歧义。您通常可以通过使用上下文信息来确定实际触发的语法规则。例如,在
中C* X;
在C中的(不是你的语言,但这只是为了说明一点),你无法分辨这是否只是一个毫无意义的乘法(在C中合法写入),或者是一个类型为“的变量X的声明”指向C“的指针。因此,有两个有效(模糊)的解析。但是如果你知道C是一个类型声明(从某些上下文,也许是一个早期的代码声明),你可以破解解析器以消除不适当的选择,最终只有一个“正确”的解析,没有歧义。
如果你真的没有上下文,那么你可能需要一个GLR解析器,它可以在你的最终树中愉快地生成两个解析。我不知道有任何可用的Java。
我们的DMS Software Reengineering Toolkit [不是基于Java的产品]具有GLR解析支持,我们一直使用它来解析带有歧义的困难语言。我们处理上面的C示例的方式是生成两个解析,因为GLR解析器很乐意这样做,然后如果我们有其他信息(例如符号表表),则对树进行后处理以删除不适当的解析。
DMS旨在支持任意语言(如查询语言)的自定义分析和转换,并且可以轻松定义语法。一旦你有了无上下文语法(歧义与否),DMS就可以解析代码,你可以决定以后要做什么。
答案 1 :(得分:1)
我怀疑你是否会在没有批量重写代码的情况下让ANTLR返回多个解析树。
我相信你将不得不将歧义划分为自己的明确语法并多次运行解析。如果模糊产品的总数很大,则可能会有一组难以管理的不同语法。例如,对于三个二元模糊(两个选择),你最终将得到8个不同的语法,但如果一个模糊分支消除了一个或多个其他歧义,则可能会略微减少。
祝你好运