【发布时间】:2015-07-10 21:33:23
【问题描述】:
我正在寻找一种可用于常见命令式语言(Java、C、python、ruby 等)的抽象语法树表示。我希望它尽可能接近源代码(而不是像 LLVM 这样的东西)。我在网上找到了Rose,但它只能处理 C 和 Fortran。这存在吗?
【问题讨论】:
标签: parsing abstract-syntax-tree imperative-programming
我正在寻找一种可用于常见命令式语言(Java、C、python、ruby 等)的抽象语法树表示。我希望它尽可能接近源代码(而不是像 LLVM 这样的东西)。我在网上找到了Rose,但它只能处理 C 和 Fortran。这存在吗?
【问题讨论】:
标签: parsing abstract-syntax-tree imperative-programming
您不会找到可以代表多种语言的“一种”通用 AST。人们已经寻找了 50 年。
本质原因是 AST 节点隐含地表示了它所编码的运算符的精确语言语义,而不同的语言对于显然相同的运算符具有不同的语义。
例如,现代 Fortran 中的“+”运算符将添加整数、实数、复数值和此类事物的数组切片。 Java "+" 将整数、实数和粘合字符串相加。如果我在“通用AST”中写“a+b”,你怎么知道对应的AST编码的语义效果是什么?
您可以做的是构建一个系统,在其中统一表示不同语言的 AST,以便您可以跨多种语言共享工具基础架构。这是由许多 Program Transformation Systems (PTS) 完成的,您可以在其中提供语法(或从可用库中选择一个),然后 PTS 使用其统一表示来解析和构建 AST。大多数 PTS 提供额外的支持来分析和转换代码。
所以,您只需要一个 PTS 和一些汗水来定义一个语法。这真的不是真的。为真正的语言找到正确的语法实际上非常困难。更糟糕的是,Life After Parsing 有很多内容,因为您需要符号的含义以及控制和数据流分析等附加推理。所以你需要完整的前端(例如,解析、名称/类型解析、流分析……),或者尽可能多的,如果你不想在开始真正的工作之前分心几个月。
这在实践中意味着您希望找到一种工具来处理您感兴趣的语言,并且已经有成熟的前端可用:
Clang 处理 C 和 C++。 Clang 还使用手工构建的前端。它还可以通过手写 AST walks/smashes 转换代码,并提供少量模式匹配支持。据我了解,您必须使用 Clang 的 LLVM 部分进行流量分析。
我们的DMS Software Reengineering Toolkit 拥有适用于 C、C++、Java 和 COBOL 的完整前端,以及适用于 Python 等更多语言的完整解析器。 DMS 提供基于模式的分析和源到源的转换。它直接根据语法进行操作(参见Oberon, Nicklaus Wirth's latest language)。 (我不知道任何处理 Ruby 的工具,它以难以解析着称;我知道它的语法是模棱两可的,而 DMS 擅长处理模棱两可的语法)。
【讨论】: