我尝试使用 Rascal 从使用 Clang 从 Objective C 代码中创建的 AST 中计算指标。由于 Clang AST 的结构与 Rascal 中使用的结构不同,我认为它需要一些重构或变通方法才能使用它。
一种方法是编写一个解析器来翻译 AST。另一种方法是使用带有递归的正则表达式。但是 Clang AST 中有很多元素,编写解析器或函数需要一些时间。
在 Rascal 中遍历 Clang AST 是否有更省时的方法?
我尝试使用 Rascal 从使用 Clang 从 Objective C 代码中创建的 AST 中计算指标。由于 Clang AST 的结构与 Rascal 中使用的结构不同,我认为它需要一些重构或变通方法才能使用它。
一种方法是编写一个解析器来翻译 AST。另一种方法是使用带有递归的正则表达式。但是 Clang AST 中有很多元素,编写解析器或函数需要一些时间。
在 Rascal 中遍历 Clang AST 是否有更省时的方法?
我相信最好针对 Clang AST API 编写一些代码以以 Rascal 可读形式打印 AST。我们也将此策略用于其他前端。
即使用http://clang.llvm.org/docs/RAVFrontendAction.html中的信息制作一个递归 AST 访问者,打印如下内容:
ifStatement(intConstant(1),[])
ValueIO
在此之后,您可以使用:在 AST 中阅读它readTextValueFile(#node, file)
,或者您可以使用ShellExec
库和readTextValueString
函数。
这将为您提供 AST 类型的表示node
。如果您想要一个类型化的表示,那么还需要生成数据声明,如下所示:
data Statement = ifStatement(Expression cond, list[Statement] body);
顺便说一句,如果有人已经为 Clang AST 编写了 JSON 或 XML 导出器,那么您将是王者,因为 Rascal 有库可以直接读取这些格式。
人们总是试图在工具之间移动 AST,因此他们不必使用原始工具来完成工作。这就是“软件工具总线”的概念。
这通常只是一个令人头疼的问题,因为每个工具都带有一组关于 AST 的结构和含义的假设,而另一个工具没有或没有共享这些假设。因此,您不仅要构建 AST 转换工具,而且还要经常填写“其他工具”。
我从未见过它做得非常成功,而且它真的不节省任何努力。如果您有 Clang AST,并且想要处理它,请坚持使用 Clang。
[我会说所有可能逃脱的人,尤尔根是最有可能的人之一。如果你不是尤尔根,你可能会遇到更多麻烦。]