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