组合的解析器/解析器生成器

时间:2012-09-20 17:31:20

标签: parsing grammar

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

5 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

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

有助于知道DMS直接根据语法生成树。

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

例如,可以编写以下DMS语法规则并匹配prettyprinting规则:

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节点,并在输出时重新生成它们。实施有点异国情调,因为大多数解析器都不处理评论,但使用很简单,甚至免费&#34 ;;注释将自动插入到原始位置的prettyprinted结果中。

DMS也可以打印&#34;保真度&#34;模式。在这种形式中,它试图保持toke的形状(例如,数字基数,标识符字符大写,使用哪个关键字拼写)解析的标记的列偏移(到行中)。这会导致原始文本(或者某种非常接近的东西,你认为它不同)才能重新生成。

我在Compiling an AST back to source code的答案中提供了有关prettyprinters必须执行的操作的详细信息。 DMS彻底解决了所有这些主题。

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

通过编写一组足够有趣的prettyprinter规则,您可以构建like JavaDoc extended to include hyperlinked source code

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

我已经用Java和Kotlin实现了一组Invertible Parser Combinators。解析器几乎是用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

答案 4 :(得分:0)

一般情况下不可能。

是什么让打印漂亮?如果空格,制表符或换行符位于这些位置,则打印效果很好,这使得打印效果非常好。

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

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