これを行うためのより良い方法はありますか?
よくわかりません。もちろん、別の方法があります。あなたは何が良いかを決定します。
別のオプションは、カスタムASTノードクラス(および対応するノードアダプター)を作成し、解析中に一致したテキストをこのASTノードに追加することです。ここでの秘訣はskip()
、レクサーからトークンを破棄するを使用せずに、それをHIDDEN
チャネルに配置することです。これは事実上同じですが、これらの(非表示の)トークンが一致するテキストはパーサーで引き続き使用できます。
簡単なデモ:これら3つのファイルすべてを次の名前のディレクトリに配置しますdemo
:
デモ/Tg
grammar T;
options {
output=AST;
ASTLabelType=XTree;
}
@parser::header {
package demo;
import demo.*;
}
@lexer::header {
package demo;
import demo.*;
}
parse
: expr EOF -> expr
;
expr
@after{$expr.tree.matched = $expr.text;}
: Int '+' Int ';' -> ^('+' Int Int)
;
Int
: '0'..'9'+
;
Space
: ' ' {$channel=HIDDEN;}
;
demo / XTree.java
package demo;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class XTree extends CommonTree {
protected String matched;
public XTree(Token t) {
super(t);
matched = null;
}
}
demo / Main.java
package demo;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "12 + 42 ;";
TLexer lexer = new TLexer(new ANTLRStringStream(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.setTreeAdaptor(new CommonTreeAdaptor(){
@Override
public Object create(Token t) {
return new XTree(t);
}
});
XTree root = (XTree)parser.parse().getTree();
System.out.println("tree : " + root.toStringTree());
System.out.println("matched : " + root.matched);
}
}
このデモを実行するには、シェルを開いて、ディレクトリを保持しているディレクトリにcdしdemo
、次のコマンドを実行します。
java -cp demo / antlr-3.3.jar org.antlr.Tool demo / Tg
javac -cp demo / antlr-3.3.jar demo/*。java
java -cp。:demo / antlr-3.3.jar demo.Main
これにより、次の出力が生成されます。
ツリー:(+ 12 42)
一致:12 + 42;