4

有没有人知道解析器背后的示例和理论,它们将采用(也许)抽象语法树并生成代码,而不是反之亦然。在数学上,至少在直觉上,我相信 code->AST 的功能是可逆的,但我正在努力寻找这方面的工作/示例......除了 Dragon book 等常用资源之外。有任何想法吗?

4

11 回答 11

3

这样的东西被称为访客。Is 遍历树并做任何必须做的事情,例如优化或生成代码。

于 2009-03-19T12:35:53.313 回答
2

我们的DMS Software Reengineering Toolkit坚持将解析器和逆解析器(称为“prettyprinters”)作为对任意语言进行机械处理(分析/转换)的“扑克赌注”。这些提供了完整的往返:源文本到 AST,带有捕获的位置信息(文件/行/列)和注释,以及 AST 到合法源文本,包括重新生成原始令牌位置(“保真打印”)或格式良好(“漂亮打印” ) 选项,包括评论的再生。

解析器通常由语法和词法定义的组合来指定;这些符号通常被编译成高效的解析引擎,正如您所料,DMS 为“解析器”端执行此操作。这里的其他人建议“访问者”是进行漂亮打印的方式,并且像汇编代码一样,它是在最低抽象级别实现漂亮打印的正确方法。但是,DMS 漂亮打印机是根据文本框构造语言指定的在诸如 Latex 之类的语法术语上,它使人们能够控制各种语言元素的水平、垂直、嵌入、间隔、连接、层压等的位置。DMS 将这些编译成有效的低级访问者(正如其他答案所暗示的那样),实现盒子一代。但就像解析器生成器一样,您并没有看到所有丑陋的细节。

DMS 有大约 30 多套这些语言前端,用于各种编程语言和正式符号,范围从 C++、C、Java、C#、COBOL 等到 HTML、XML、来自某些机器的汇编语言、临时属性规范、规范用于可组合的抽象代数等。

于 2011-03-18T20:42:10.240 回答
1

我更喜欢 lewap 的回应:

找到一种表达访问者的数学方法,并且您对解析器具有双重性

但是您要求提供样本,因此请试一下大小:Visual Studio 包含一个具有出色对称性的 UML 编辑器。它和编辑器的实现方式都构成模型的视图,并且编辑任一修改模型导致所有保持同步。

于 2009-03-19T12:58:38.687 回答
1

实际上,从解析树生成代码比解析代码更容易,至少在数学意义上是这样。有许多语法是模棱两可的,也就是说,没有唯一的方法来解析它们,但是解析树总是可以以唯一的方式转换为字符串,模空格。

Dragon 书很好地描述了解析器的理论。

于 2009-06-17T10:51:35.690 回答
1

Haskell 中有可逆解析的理论、工作实现和示例。图书馆由 Paweł Nowak 设计。请参考 https://hackage.haskell.org/package/syntax 作为您的起点。您可以在以下 URL 中找到示例。

于 2015-02-19T00:30:58.973 回答
0

我不知道在哪里可以找到有关该理论的更多信息,但boost::spirit 2.0具有 qi(解析器)和karma(生成器),共享相同的底层结构和语法,因此它是该概念的实际实现。

生成器方面的文档仍然很薄(spirit2 在 Boost 1.38 中是新的,并且仍处于测试阶段),但是周围有一些 karma 示例代码,并且 AFAIK 库处于工作状态并且至少有一些可用的例子

于 2009-03-19T13:01:18.960 回答
0

除了“Visitor”,“unparser”是另一个很好的网络搜索关键字。

于 2009-03-20T01:12:37.713 回答
0

这听起来很像非优化编译器的后端,它的目标语言与源语言相同。

一个问题是您是否需要“未解析”代码与原始代码相同,或者只是功能上等效。

例如,输出是否可以使用与原始样式不同的缩进样式?该信息通常不会存储在 AST 中,因为它在语义上并不重要。

要看的一件事是自动代码重构工具。

于 2009-03-20T01:42:36.160 回答
0

我一直在做这些,并称它们为“DeParse”。

如果您还想重新捕获空白和注释,它只会变得棘手。您必须将它们塞入解析树中,以便在输出时重新生成它们。

于 2009-03-20T21:35:30.660 回答
0

“访客模式”的想法很好。但是,我应该将“访问者”模式视为线性列表模式,或者作为通用模式,并为更具体的情况添加模式,如列表、矩阵和树。

在网络上寻找“分层访问者模式”或“树访问者模式”。

您有一个树数据结构(“集合”)并且想要对数据做一些事情,每次您“访问”、“迭代”或“读取”树中的一个项目。

在您的情况下,您有一个树数据结构,它表示扫描/解析某些源代码的结果。然后您已读取每个项目的数据,并将其转换为目标代码。

于 2011-03-19T17:40:15.780 回答
0

有几种“镜头语言”允许对源代码进行双向转换

也可以使用Prolog中的明确子句语法来实现可逆解析器。在 SWI-Prolog 中,短语/3谓词将解析树转换为文本,反之亦然。本书提供了一些额外的 Prolog 可逆解析示例。

于 2016-09-19T18:30:05.663 回答