我正在使用 ANTLR 3 来解析和重写答案集程序 (ASP)。我想要做的是解析一个 ASP 程序并输出一个带有一些重写的 AST。我可以轻松地在 AST 中添加和删除节点,但我需要做的是动态地将节点添加到根(实际上是向 ASP 程序添加新规则)。添加哪些节点以及添加多少节点取决于输入的 ASP 程序。
下面我有一个来自我的词法分析器和解析器的示例,它输出一个 AST。r_rule 返回一个根据匹配的内容填充的 LinkedHashMap。对于 LinkedHashMap 的每个成员,在 r_program 的重写中,我想将一个新节点添加到根节点 PROGRAM。但是,我似乎找不到遍历 LinkedHashMap 并添加新节点的方法。
@members {
int rID = 0;
}
r_program
: (a=r_rule)* -> ^(PROGRAM r_rule*);
r_rule returns [LinkedHashMap<String, String> somehm]
@init {
$somehm = new LinkedHashMap<String, String>();
String strrID = Integer.toString(++rID);
}
: (head = r_head) ':-'
body=r_body[strrID] {$vartypes.putAll($body.vartypes); } -> ^(LIMPL $head ^(EXTENSION ^(NUMBER[strrID] $head)) $body);
我可以使用语义谓词,但只能检查 LinkedHashMap 的属性。我可以使用插入的代码任意循环遍历 HashMap,但我不能在每次迭代时添加子节点或触发重写。生成的代码实际上放在错误的位置,甚至使用 Java 以丑陋的方式执行此操作(我无法访问根节点 PARENT)。
我能做些什么呢?也欢迎采用完全不同的方法。非常感谢!
更新 1
一个示例输入是:
head_pred(X, Y, Z) :- body_1(X), body_1(Y), body_1(Z).
一个示例 AST 是,为绘图道歉(nb 严格来说是一个用于可读性的示例,实际上在重写中使用了更多节点)......
PROGRAM
|
|____:-
| |____head_pred(X, Y, X)
| |____body_1(X)
| |____body_1(Y)
| |____body_1(Z)
| |____X == Y
|
|____:-
| |____head_pred(X, Y, X)
| |____body_1(X)
| |____body_1(Y)
| |____body_1(Z)
| |____X == Z
我可以继续说,如果可以绑定变量,每个规则都会以不同的方式绑定变量。不同的输入会改变 PROGRAM 子项的数量和内容。