【问题标题】:Combined unparser/parser generator组合的解析器/解析器生成器
【发布时间】:2012-09-13 02:58:16
【问题描述】:

是否有一个解析器生成器也实现了反向,即从相同的语法规范中解析域对象(又名漂亮打印)?据我所知,ANTLR 不支持这个。

【问题讨论】:

  • 当你有任意动作时似乎有点难,但使用属性语法它似乎很容易......我迫不及待地想被一个聪明的答案谦卑:D
  • @delnan:事实上,使用属性语法“很容易”。看我的回答; Prettyprinter 规范是一个语法有趣的属性语法。

标签: parsing grammar


【解决方案1】:

我已经用 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

【讨论】:

    【解决方案2】:
    【解决方案3】:

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

    也可以使用definite clause grammars实现源代码的bidirectional transformations。在 SWI-Prolog 中,phrase/2 谓词可以将输入文本转换为解析树,反之亦然。

    【讨论】:

      【解决方案4】:

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

      了解 DMS 直接根据语法生成树会很有帮助。

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

      例如,可以编写以下 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 还捕获 cmets,将它们附加到 AST 节点,并在输出时重新生成它们。该实现有点奇特,因为大多数解析器不处理 cmets,但使用起来很容易,甚至是“免费的”; cmets 将自动插入到它们原始位置的漂亮打印结果中。

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

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

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

      通过编写一组足够有趣的漂亮打印机规则,您可以构建东西like JavaDoc extended to include hyperlinked source code

      【讨论】:

        【解决方案5】:

        一般情况下是不可能的。

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

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

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

        【讨论】:

        • 我在想这个。一些语法(比如 C 的语法)在空格等方面具有很大的灵活性。但是有些语法没有,所以任何打印机都会自动成为漂亮的打印机。但似乎你可以用关于哪些选择是“漂亮”的信息来注释语法,然后你可以从中生成一个漂亮的打印机。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-27
        • 1970-01-01
        • 2015-09-15
        相关资源
        最近更新 更多