ANTLR 3 を使用して、Answer-Set Programs (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 の子の数と内容が変わります。