【问题标题】:How to obtain line and/or column from parsed java source from Eclipse JDT Parser from all nodes?如何从所有节点的 Eclipse JDT Parser 解析的 java 源中获取行和/或列?
【发布时间】:2012-08-11 01:38:58
【问题描述】:

我已经使用 AST 玩了很长时间,并试图从 eclipse 中获取与在此插件上解析的给定节点相关联的行和列信息。根据记录的apihere我发现getStartPosition()方法可以给我解析文件的字符位置,但这不是我想要的。

我在CompilationUnit class api documentation 上找到了getLineNumber(int position)getColumnNumber(int position) 的方法,据我所知,它们可以解决问题。 position 参数不亚于getStartPosition() 方法通过执行node.getStartPosition() 返回的内容。

现在,问题是在源文件上获取行和列的两种方法似乎不适用于所有节点。例如,method declaration nodes 没有它们!

如何获得所有树的此类信息?我知道这不是不可能的,因为我能够使用其他语言的解析器,对于 每个 ast 节点都有与之关联的行和列。事实上,我相信javaparser 是 java 的其中之一,因为该类包含硬编码的行和列的属性。看到 Eclipse JDT 对我来说似乎更加健壮并且在那里呆了很长一段时间,我会惊讶于无法获得这样的信息。

编辑:同样,问题是从仅出现在根目录中的编译单元的不同内容中获取行号:

<type 'org.eclipse.jdt.core.dom.CompilationUnit'>
1
<type 'org.eclipse.jdt.core.dom.TypeDeclaration'>
<type 'org.eclipse.jdt.core.dom.Javadoc'>
<type 'org.eclipse.jdt.core.dom.TagElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>
<type 'org.eclipse.jdt.core.dom.TextElement'>

谢谢。

【问题讨论】:

    标签: java eclipse parsing abstract-syntax-tree eclipse-jdt


    【解决方案1】:

    为了后代,我将重新发布我在 jdt-core-dev 邮件列表上发布的答案。 (我的回答和上面 Ryan 的建议差别不大)

    嗨,卡洛斯,

    您对 CompilationUnit.getLineNumber(int) 方法是正确的。你按如下方式使用它:

    int lineNumber = compilationUnit.getLineNumber(node.getStartPosition()) - 1;

    但是,我不明白你在哪里卡住了。为什么需要为 MethodDeclaration 定义的 getLineNumber(..)?你只需要找到方法声明节点,然后使用下面的代码找到它对应的CompilationUnit,然后使用上面的代码行找到行号。我在这里遗漏了什么吗?

    ASTParser parser = ASTParser.newParser(AST.JLS3); // or JLS_4 for java 7 and above
    
    parser.setKind(ASTParser.K_COMPILATION_UNIT);
    parser.setSource(source); // give your java source here as char array
    parser.setResolveBindings(true);
    
    CompilationUnit compilationUnit = parser.createAST(null);
    

    干杯! 阿尤什

    【讨论】:

    • 谢谢我没有意识到 CU 与给定的 java 文件相关联,因此拥有与 ast 相关的节点的行位置信息是合理的那个文件。我更习惯于每个节点都有其所属的关联行和列的心理模型,因为这是我见过的唯一模型。这一切都归结为设置类职责的方式,而这个新的职责是没有意义的。现在一切运行正常。自从我从您的回答中意识到这一点以来,我投票并将您的回答设为已回答。
    【解决方案2】:

    我面前没有正在运行的程序,但根据您上面链接到的文档和 Eclipse 的源代码,您似乎可以通过调用 @ 来获得 ASTNodeCompilationUnit 987654325@ 并将其转换为 CompilationUnit。或者,从ASTParserjavadocibm 的示例中可以看出,ASTParser.createAST(IProgressMonitor) 几乎总是返回一个CompilationUnit,它代表您正在解析的源。

    在你有一个名为rootCompilationUnit 之后,你应该能够使用root.getLineNumber(node.getStartPosition())root.getColumnNumber(node.getStartPosition()) 方法。

    final ASTParser p = ASTParser.newParser(AST.JLS3);
    p.setSource(source);
    final CompilationUnit root = (CompilationUnit) p.createAST(null);
    // stuff happens
    final ASTNode node = //get a node
    
    final int line = root.getLineNumber(node.getStartPosition());
    final int column = root.getColumnNumber(node.getStartPosition());
    System.out.println("Node started at (" + line + ", " + column + ")";
    

    【讨论】:

    • 谢谢,我对答案投了赞成票,因为它也很连贯。投票给另一个作为最终答案,因为它帮助我意识到我的心理模型在如何解决问题上的不同。注意到另一个答案的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-11
    相关资源
    最近更新 更多