私が理解していないのは、このツリーの上に「idList」ノードを取得する方法です(実際のところ、文法ノードも同様です)。リライトとそれらの演算子を使用してこのツリーを再現するにはどうすればよいですか?
^
一人では使えません!
。これらの演算子は既存のトークンに対してのみ機能しますが、追加のトークンを作成する必要があります(そして、これらをサブツリーのルートにします)。これは、書き換えルールを使用し、いくつかの架空のトークンを定義することで実行できます。
簡単なデモ:
grammar test;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
IdList;
Id;
}
@parser::members {
private static void walk(CommonTree tree, int indent) {
if(tree == null) return;
for(int i = 0; i < indent; i++, System.out.print(" "));
System.out.println(tree.getText());
for(int i = 0; i < tree.getChildCount(); i++) {
walk((CommonTree)tree.getChild(i), indent + 1);
}
}
public static void main(String[] args) throws Exception {
testLexer lexer = new testLexer(new ANTLRStringStream("abc abc123"));
testParser parser = new testParser(new CommonTokenStream(lexer));
walk((CommonTree)parser.program().getTree(), 0);
}
}
program : idList EOF -> idList;
idList : id* -> ^(IdList id*);
id : ID -> ^(Id ID);
ID : LETTER (LETTER | DIGIT)*;
SPACE : ' ' {skip();};
fragment LETTER : 'a' .. 'z' | 'A' .. 'Z';
fragment DIGIT : '0' .. '9';
上記のデモを実行すると、コンソールに次のように出力されます。
IdList
Id
abc
Id
abc123
ご覧のとおり、レクサールールと同様に、架空のトークンも大文字で始める必要があります。text
架空のトークンに、それらが表すパーサールールと同じものを与えたい場合は、代わりに次のようにします。
idList : id* -> ^(IdList["idList"] id*);
id : ID -> ^(Id["id"] ID);
印刷されます:
idList
id
abc
id
abc123