可逆解析器的理论和示例是什么?

4

有没有人知道解析器的例子和理论,可以将(可能)抽象语法树转换为代码,而不是反过来。从数学上讲,至少直观上,我相信代码->AST的功能是可逆的,但我正在尝试寻找这方面的工作/示例......除了像龙书之类的常规资源之外。有什么想法吗?


5
我是一名研究人员,"实用"和"利润"不是我们特别理解的词汇。 - Dervin Thunk
好的,让我们这样表达:找到一个数学方式来表达一个访问者,你就有了解析器的对偶。 - paweloque
我是一名工程师。"实用和盈利"是我完全理解的词汇,您可以构建解析器和漂亮的打印机来支持商业上有价值的活动。代码分析器、代码重构工具和代码生成/转换工具引起了很多兴趣,其中"反向解析器"非常有用。 - Ira Baxter
@Mike Dunlavey:除了“纯粹的细节”之外,你是正确的。这些“纯粹的细节”包括:缩进、空格的再生(制表符和空格的确切顺序,或者只是等效的空格?)、列限制(遗留的Fortran、COBOL、80列卡片)、换行、用适当的基数和精度再生数字文字、关键字同义词的保留、字符串文字再生、输出流编码与字符流转义的交互、注释再生、预处理器指令、真正可编译的代码。... - Ira Baxter
@Mike Dunlavey:当你混合了最大程度地保留原始文本(“保真打印”)的愿望和需要打印转换或新生成代码的混合文本时,这变得更加困难。在后一种情况下,您希望添加与周围代码风格一致的自动缩进。我知道如何做所有这些事情,除了最后一个 :-( - Ira Baxter
显示剩余2条评论
11个回答

4
这种东西被称为访问者。它遍历树并执行必须要做的操作,例如优化或生成代码。

请问您能否提供一些参考链接(维基百科、论文)? - Dervin Thunk
访问者模式。你正在进行什么样的研究? - paweloque
很好,我曾经在商业应用程序中使用过语法树和访问者模式,但是没有同时使用过。 - umlcat

2
我们的DMS软件重构工具包坚持使用解析器和反解析器(称为“漂亮打印机”)作为对任意语言进行机械处理(分析/转换)的“赌注”。 它们提供完整的往返:源文本到AST,包括捕获位置信息(文件/行/列)和注释,以及AST到合法源文本,包括重新生成原始标记位置(“保真打印”)或漂亮格式化(“漂亮打印”)选项,包括重建注释。
解析器通常由语法和单词的词汇定义的组合指定;这些符号通常被编译成高效的解析引擎,而DMS也对“解析器”部分做了同样的工作。这里还有其他人建议使用“访问者”来实现漂亮的输出,并且,就像汇编代码一样,它是在抽象层次最低的情况下实现美化输出的正确方式。然而,DMS的漂亮输出器是用类似于Latex的文本框构建语言来指定的,该语言允许您水平、垂直地控制各种语言元素的位置,以及嵌入、间隔、连接、覆盖等。DMS将这些编译成高效的低级别访问者(就像其他回答所建议的)来实现框生成。但是,与解析器生成器一样,您不必看到所有丑陋的细节。
DMS拥有30多套这些语言前端,涵盖各种编程语言和形式化符号表示,包括但不限于C++、C、Java、C#、COBOL、HTML、XML、某些机器的汇编语言、临时属性规范、可组合抽象代数规范等。

1

1

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

龙书对解析器理论给出了很好的描述。


1

我比较喜欢lewap的回答:

找到一个数学方式来表达访问者,你就有了解析器的对偶

但是你要求一个样例,那么试试这个:Visual Studio包含一个具有出色对称性的UML编辑器。它和编辑器的实现方式都构成了模型的视图,而编辑任意一个都会修改模型,从而使所有内容保持同步。


0
“访问者模式”是个好主意。但是,我应该将“访问者”模式视为线性列表模式,或者作为通用模式,并添加更具体的模式,如列表、矩阵和树。
在网上寻找“分层访问者模式”或“树形访问者模式”。
您有一个树形数据结构(“集合”),想要对数据执行某些操作,每次从树中“访问”、“迭代”或“读取”一个项目时。
在您的情况下,您有一个树形数据结构,表示扫描/解析某些源代码的结果。然后,您需要读取每个项目的数据,并将其转换为目标代码。

0

有几种“镜头语言”可以实现源代码的双向转换

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


0

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

生成器方面的文档仍然非常薄弱(spirit2是Boost 1.38中的新产品,仍处于测试版阶段),但是有一些karma示例代码可用,并且据我所知,该库处于工作状态并且至少有一些示例可用。


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

另一个流行词是“漂亮打印”和“漂亮打印组合器”。 - Martijn

0

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

一个问题是你是否需要“未解析”的代码与原始代码完全相同,还是仅在功能上等效即可。

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

一个值得考虑的事情是自动代码重构工具。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接