6

我正在尝试将 Antlr 用于一些类似 IDE 的文本功能——特别是解析文件以识别代码折叠点和应用语法突出显示。

第一个问题——Antlr 是否适合这个要求,还是有点矫枉过正?这可以使用正则表达式和/或手动解析器来实现……但似乎 Antlr 可以为我完成这项工作。

我已经浏览了...以及这里的优秀教程资源。

我已经设法构建了一个 Java 语法(使用标准语法),并将所有内容整齐地解析成一棵树。但是,我希望看到嵌套在树中的元素。实际上,一切都是最顶层元素的子元素。

例如。鉴于:

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

我希望 Foo 的树节点是包声明节点的子节点。同样,myString 将是 Foo 的子代。

相反,我发现Fooand myString(以及其他一切)都是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 的菜鸟,而且我发现学习曲线非常陡峭。

4

2 回答 2

6

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

options {
    output=AST;
}

其次,您需要通过使用树运算符或使用重写规则来告诉它树应该是什么样子。请参阅有关树构造的文档。我通常最终将两者结合起来。

于 2009-12-03T19:13:36.967 回答
1

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

据我所知,在 ANTLR 中,只有 1 个令牌可以是树的根,因此您无法准确获得所需的内容,但可以接近。

查看: http ://www.antlr.org/wiki/display/ANTLR3/Tree+construction

于 2009-11-24T18:15:19.357 回答