17

Is there a parser generator that also implements the inverse direction, i.e. unparsing domain objects (a.k.a. pretty-printing) from the same grammar specification? As far as I know, ANTLR does not support this.

4

5 回答 5

2

看看Invertible syntax descriptions: Unifying parsing and pretty printing

于 2014-12-29T12:29:30.880 回答
2

我已经用 Java 和 Kotlin 实现了一组可逆解析器组合器。解析器几乎是用 LL-1 风格编写的,它提供了解析和打印方法,而后者提供了漂亮的打印机。

你可以在这里找到项目:https ://github.com/searles/parsing 这是一个教程:https ://github.com/searles/parsing/blob/master/tutorial.md 这是一个解析器/漂亮的打印机对于数学表达式:https ://github.com/searles/parsing/blob/master/src/main/java/at/searles/demo/DemoInvert.kt

于 2019-07-10T22:30:58.823 回答
1

我们的DMS Software Reengineering Toolkit正是这样做的(并为分析/转换代码提供了许多额外的支持)。它通过用附加属性装饰语言语法来做到这一点,产生所谓的属性语法。我们使用特殊的 DSL 来编写这些规则,以方便编写。

了解 DMS 直接基于语法生成树会有所帮助。

每个 DMS 语法规则都与所谓的“漂亮打印”规则配对。每个漂亮打印规则都描述了如何“漂亮打印”由其相应语法规则识别的句法元素和子元素。漂亮打印过程本质上是水平或垂直制造或组合矩形文本框(带有可选的缩进),叶子生成包含叶子文字值(关键字、运算符、标识符、常量等)的单位高度框。

例如,可以编写以下 DMS 语法规则和匹配的漂亮打印规则:

statement = 'for' '(' assignment ';' assignment ';' conditional_expression ')'
            '{' sequence_of_statements '}' ;
<<PrettyPrinter>>: 
    { V(H('for','(',assignment[1],';','assignment[2],';',conditional_expression,')'),
        H('{', I(sequence_of_statements)),
        '}');

这将解析以下内容:

    for ( i=x*2;
       i--;  i>-2*x ) {  a[x]+=3; 
      b[x]=a[x]-1; }

(对语句和表达式使用额外的语法规则)和漂亮打印它(对那些额外的语法规则使用额外的漂亮打印规则)如下:

    for (i=x*2;i--;i>-2*x)
    {   a[x]+=3;
        b[x]=a[x]-1;
    }

DMS 还捕获评论,将它们附加到 AST 节点,并在输出时重新生成它们。该实现有点奇特,因为大多数解析器不处理注释,但使用起来很容易,甚至是“免费的”;评论将自动插入到它们原始位置的漂亮打印结果中。

DMS 还可以在“保真”模式下打印。在这种形式中,它试图保留标记的形状(例如,数字基数、标识符字符大写、使用了哪个关键字拼写)和已解析标记的列偏移量(到行中)。这将导致重新生成原始文本(或非常接近以至于您认为它没有不同的内容)。

我的 SO answer on Compiling an AST back to source code提供了有关漂亮打印机必须做什么的更多详细信息。DMS 清晰地解决了所有这些主题。

此功能已被 DMS 用于大约 40 多种真实语言,包括完整的 IBM COBOL、PL/SQL、Java 1.8、C# 5.0、C(许多方言)和 C++14。

通过编写一组足够有趣的漂亮打印机规则,您可以构建像 JavaDoc 这样的东西,扩展为包含超链接源代码

于 2014-12-29T15:48:26.867 回答
1

有几个解析器生成器包含一个解解析器的实现。其中之一是用于上下文无关语法的Nearley解析器生成器。

也可以使用明确的子句语法来实现源代码的双向转换。在 SWI-Prolog 中,谓词可以将输入文本转换为解析树,反之亦然。phrase/2

于 2017-06-03T18:34:44.120 回答
0

一般情况下是不可能的。

是什么让印刷品漂亮?打印件很漂亮,如果空格、制表符或换行符位于这些位置,这会使打印件看起来很漂亮。

但是大多数语法忽略空格,因为在大多数语言中空格并不重要。有像 Python 这样的例外,但总的来说,使用空格作为语法是否是一个好主意的问题仍然存在争议。因此大多数语法不使用空格作为语法。

如果抽象语法树不包含空格,因为解析器已经把它们扔掉了,没有生成器可以使用它们来漂亮地打印 AST。

于 2012-10-11T11:58:12.850 回答