假设我有这个简单而无意义的语法:
propagate : what^ where*;
what : CHAR^;
where : NUMBER -> ^(PLUS NUMBER);
NUMBER : '0'..'9';
CHAR : 'a'..'z';
PLUS : '+';
如果它解析像
a123456789
这样的字符串,它会生成一个 AST,如:我要做的是将
what
解析的 token 传递给 where
并创建一个 AST(对于相同的输入),如:我尝试了以下方式:
propagate : w=what^ where[$w.text]*;
what : CHAR^;
where[String s] : NUMBER -> ^(PLUS CHAR[s] NUMBER);
NUMBER : '0'..'9';
CHAR : 'a'..'z';
PLUS : '+';
如果
what
它是一个单一的标记它可以工作,但是如果它是一棵树呢?这是正确的方法吗?
最佳答案
就是这样:
grammar T;
options {
output=AST;
ASTLabelType=CommonTree;
}
parse
: propagate EOF!
;
propagate
: what^ where[$what.tree]*
;
what
: CHAR
;
where[CommonTree lhs]
: NUMBER -> ^(PLUS {new CommonTree($lhs)} NUMBER)
;
NUMBER : '0'..'9';
CHAR : 'a'..'z';
PLUS : '+';
ANTLRWorks 的调试器可能不会显示正确的 AST:自己创建一个小的驱动程序类:
import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;
public class Main {
public static void main(String[] args) throws Exception {
TLexer lexer = new TLexer(new ANTLRStringStream("a123"));
TParser parser = new TParser(new CommonTokenStream(lexer));
CommonTree tree = (CommonTree)parser.parse().getTree();
DOTTreeGenerator gen = new DOTTreeGenerator();
StringTemplate st = gen.toDOT(tree);
System.out.println(st);
}
}
要运行它,请执行以下操作:
java -cp antlr-3.3.jar org.antlr.Tool T.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main > ast.dot
这将产生一个表示以下 AST 的 DOT 文件:
关于parsing - 树构造 : propagate a subtree to child,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14244849/