使用ANTLR2,您可以在语法定义文件中定义类似的内容:
options
{
language = "CSharp";
namespace = "Extended.Tokens";
}
tokens {
TOKEN<AST=Extended.Tokens.TokenNode>;
}
然后,你可以创建一个类:
public class TokenNode: antlr.BaseAST
{
...
}
如果可以使用这样的任何ideea(将类创建委托给AST工厂而不是我手动进行树复制)?它只是通过从旧格式到新格式的简单语法定义复制工作,我试图搜索他们的网站和样本以寻找类似的东西。任何提示?
我不是要创建自定义令牌,而是自定义“节点解析器”。
为了'执行'一棵树你有2个选择(据我所知):
在v2的情况下,我可以将树节点装饰成我想要的方法,然后在解析器运行之后通过从根节点调用类似'execute'之类的方法来调用它们。
答案 0 :(得分:4)
我对C#知之甚少,但与Java目标应该没什么区别。
您可以通过设置ASTLabelType
部分中的options { ... }
(在这种情况下为XTree
)来创建 - 并让ANTLR使用 - 自定义树:
grammar T;
options {
output=AST;
ASTLabelType=XTree;
}
tokens {
ROOT;
}
@parser::header {
package demo;
import demo.*;
}
@lexer::header {
package demo;
import demo.*;
}
parse
: Any* EOF -> ^(ROOT Any*)
;
Any
: .
;
然后创建一个扩展CommonTree
的自定义类:
package demo;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class XTree extends CommonTree {
public XTree(Token t) {
super(t);
}
public void x() {
System.out.println("XTree.text=" + super.getText() + ", children=" + super.getChildCount());
}
}
当您创建TParser
的实例时,您必须创建并设置自定义TreeAdaptor
,以创建XTree
的实例:
package demo;
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
public class Main {
public static void main(String[] args) throws Exception {
String source = "ABC";
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();
root.x();
}
}
运行演示:
java -cp antlr-3.2.jar org.antlr.Tool T.g -o demo/
javac -cp antlr-3.2.jar demo/*.java
java -cp .:antlr-3.2.jar demo.Main
将打印:
XTree.text=ROOT, children=3
有关详细信息,请参阅:http://www.antlr.org/wiki/display/ANTLR3/Tree+construction