了解ANTLR中的树

时间:2009-11-24 14:46:06

标签: java antlr

我正在尝试将Antlr用于某些类似IDE的函数 - 专门解析文件以识别代码折叠的点,以及应用语法高亮。

第一个问题 - Antlr是否适合此要求,还是过度杀伤?这个可以使用正则表达式和/或手动解析器实现......但似乎Antlr就在那里为我做这项工作。

我已经浏览了......和优秀的教程资源here

我设法建立了一个Java语法(使用standard grammar),并将所有内容整齐地解析为树。但是,我希望看到嵌套在树中的元素。事实上,一切都是最重要元素的孩子。

EG。给出:

package com.example
public class Foo {
   String myString = "Hello World"
   // etc
}

我原本期望Foo的树节点成为包声明节点的子节点。同样,myString将是Foo的孩子。

相反,我发现FoomyString(以及其他所有问题)都是package的孩子。

以下是进行解析的相关摘录:

public void init() throws Exception {
    CharStream c = new ANTLRFileStream(
            "src/com/inversion/parser/antlr/Test.code");

    Lexer lexer = new JavaLexer(c);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    JavaParser parser = new JavaParser(tokens);
    parser.setTreeAdaptor(adaptor);

    compilationUnit_return result = parser.compilationUnit();
}

static final TreeAdaptor adaptor = new CommonTreeAdaptor() {
    public Object create(Token payload) {
        if (payload != null)
        {
            System.out.println("Create " + JavaParser.tokenNames[payload.getType()] + ":  L" + payload.getLine() + ":C" + payload.getCharPositionInLine() + " " + payload.getText());
        }
        return new CommonTree(payload);
    }
};

检查result.getTree()会返回一个CommonTree实例,其子项是解析的结果。

预期值(可能不正确)

package com.example (4 tokens)
   |
   +-- public class Foo (3 tokens)
        |
        +--- String myString = "Hello World" (4 tokens)
        +--- Comment "// etc"

(或类似的东西)

实际值(所有值都是result.getTree()根节点的子节点)

package
com
.
example
public
class
Foo
String
myString
=
"Hello World"

我对这应该如何工作的理解是正确的吗?

到目前为止,我在Antlr是一个完整的菜鸟,我发现学习曲线非常陡峭。

2 个答案:

答案 0 :(得分:6)

antlr.org上文件共享部分顶部的Java-6语法不包括树构建。你需要做两件事。首先,告诉ANTLR你想建立一个AST:

options {
    output=AST;
}

其次,您需要通过使用树运算符或使用重写规则来告诉它树的外观。请参阅documentation on tree construction。我通常最终会将两者结合起来。

答案 1 :(得分:1)

要构建树,您应该设置output = AST。 (抽象语法树)

据我所知,在ANTLR中,只有1个令牌可以是树的根,所以你无法得到你正在寻找的东西,但你可以靠近。

退房: http://www.antlr.org/wiki/display/ANTLR3/Tree+construction