rascal - 从 AST 获取方法时的错误声明
问题描述
我正在尝试使用 AST 获取方法声明,因此我可以遍历它,查找某些语句。它以前工作过,但我不能让它工作了,我得到的声明在我看来就像有某种解析错误。我找不到有关如何解决此问题的信息:
{<|java+method:///MetricsTest/testMethod()|,compilationUnit([],[],src=|java+method:///MetricsTest/testMethod()|(0,30,<1,0>,<2,2>),decl=|java+compilationUnit:///MetricsTest/testMethod()|,messages=[error("Syntax error on token \"void\", @ expected",|java+method:///MetricsTest/testMethod()|(7,4,<1,0>,<1,0>)),error("Syntax error, insert \"enum Identifier\" to complete EnumHeader",|java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))])>}
我的(部分)代码如下:
public rel[loc, loc] getMethods(M3 model) {
return { <x,y> | <x,y> <- model.containment
, x.scheme=="java+class"
, y.scheme=="java+method" || y.scheme=="java+constructor"
};
}
public rel[loc, Declaration] getMethodLocWithDeclaration(M3 model) {
rel[loc, loc] methods = getMethods(model);
rel[loc, Declaration] methodsWithAST = {};
for(<loc c, loc m> <- methods) {
methodsWithAST += <m, createAstFromFile(m, false)>;
}
return methodsWithAST;
}
有谁知道我该如何解决这个问题?
解决方案
createAstFromFile
即使输入文件中存在解析错误,该函数也会返回“一半”的 AST。所以你得到了一个compilationUnit
节点,但紧接着它下面有一个error
节点,其中包含有关解析错误的信息。
顶部compilationUnit
节点似乎也有一个messages
列出当前文件所有错误的字段。
Java 编译器在该特定文件中发现了两个解析错误:
error("Syntax error on token \"void\", @ expected",|java+method:///MetricsTest/testMethod()|(7,4,<1,0>,<1,0>))
error("Syntax error, insert \"enum Identifier\" to complete EnumHeader",|java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))])
为了解决这个问题,我将在 Eclipse 中打开 MetricsTest 类并使用编辑器支持来修复文件。当文件被修复并且您再次尝试 createAstFromFile 函数时,它应该会再次工作。
确保您知道您正在解析的内容的一种方法是使用readFile
IO 库中的函数。很可能您只将文件的一部分发送到 java 解析器,它只能处理完整的文件。
如果您将其添加到您的 for 循环中,您可以检测是否是这种情况:
println("Parsing \'<readFile(m)>\'");
您很可能将这个:|java+method:///MetricsTest/testMethod()|(23,1,<1,0>,<1,0>))
作为 createAstFromFile 的 URI 传递,而这只是MetricsTest.java
文件的一部分。我猜这就是问题所在。
要解决这个问题,您可以从 M3 模型中的关系中查找真正的源位置decls
,然后使用它.top
来覆盖整个文件。另一种方法是为类构造一个java+compilationUnit
URIMetricsTest
并将其提供给函数,或者从关系中createAstFromFile
查找。containment
推荐阅读
- c++ - 查找路径是否存在的最有效算法
- reactjs - React JSX Button with Image inside,点击返回值
- google-apps-script - 如何在工作表中指定子范围以执行 sendEmails
- python - 使用中间件重定向到登录页面导致“重定向过多”问题
- pyspark - 使用两个日期列作为范围匹配日期
- python - 如何使用 Selenium WebDriver (Chrome) 打开页面,而无需等待它在 Python 中加载?
- css - 垫颜色不透明度的第二个参数是什么?
- java - 将两个数组按升序与数组内的未知值组合
- excel - 使用 VBA 将 CustomDocumentProperties 从 Word 导入 Excel
- c# - WinForms 错误:无法从传输连接读取数据:现有连接被远程主机强行关闭