ANTLR 4 和 StringTemplate 4 - 使用带模板的 tree walker [英] ANTLR 4 and StringTemplate 4 - using tree walker with templates

查看:72
本文介绍了ANTLR 4 和 StringTemplate 4 - 使用带模板的 tree walker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

免责声明:我在上个月之前从未使用过 Java,在那之前我也从未听说过 ANTLR 或 StringTemplate.在今年夏天的实习中,我得到了一个使用公司其他人从未使用过的工具的项目.每个人都相信我",相信我会弄清楚".因此,我的理解存在巨大差距.我喜欢这个项目并且我学到了很多东西,所以不要把这当成抱怨.我只是想让它工作.

Disclaimer: I never used Java before last month, and I had never heard of ANTLR or StringTemplate before then either. For my internship this summer I was given a project using tools that nobody else at the company has ever used. Everyone "has faith in me" that I will "figure it out." Hence the huge gaps in my understanding. I love this project and I've learned a ton, so don't take this as complaining. I just want to make it work.

现在我正在为旧的特定领域语言开发一个漂亮的打印机概念证明.我的 ANTLR 语法生成了很好的解析树,并且我能够输出简单的 StringTemplate 示例,就像介绍中的示例一样.

Right now I'm working on a pretty printer proof of concept for an old domain-specific language. My ANTLR grammar is producing nice parse trees, and I'm able to output simple StringTemplate examples like the ones in the introduction.

假设我的 .stg 文件中有一个简单的模板:

Say I have an simple template in my .stg file:

module(type, name, content) ::= "<type> MODULE <name>; <content>; END MODULE."

在 Java 中,我可以使用 add() 来设置每个模板参数的值:

In Java I'm able to use add() to set the values for each of the template arguments:

STGroup g = new STGroupFile("example.stg");
ST st = g.getInstanceOf("module");
st.add("type", "MAIN");
st.add("name", "test");
st.add("content", "abc");
System.out.println(st.render()); 
// prints "MAIN MODULE test; abc; END MODULE."

如何让 ANTLR 和 ST 读取文本文件并生成漂亮的打印输出?

How do I get ANTLR and ST to read in a text file and produce pretty-printed output?

MAIN MODULE test;
abc;
END MODULE.

应该变成

MAIN MODULE test; abc; END MODULE.

例如.(这不是我计划格式化所有输出的方式,别担心.打印出来的效果会比那更漂亮.)

For example. (That's not how I plan to format all the output, don't worry. It'll pretty print much prettier than that.)

这个答案中,我了解到 ANTLR 4 会自动生成步行者.假设我的 ANTLR 语法正确/写得很好,我如何将 ANTLR 规则/标记与我的模板参数匹配以从输入文本文件生成输出?

In this answer I learned that ANTLR 4 generates walkers automatically. Assuming my ANTLR grammar is correct/well-written, how do I match up the ANTLR rules/tokens to my template arguments to generate output from an input text file?

如果我在文档中的某个地方遗漏了它,请告诉我.ANTLR 4 和 ST 4 的例子比之前的版本少了很多.

If I missed it in the documentation somewhere let me know. There are much fewer examples of ANTLR 4 and ST 4 than the previous versions.

推荐答案

给定解析器规则

r : a b c ;

生成的解析树将包含一个节点 rContext 和子节点 aContextbContextcContex,对于输入流中匹配规则的每个实例,每个可能有更多的子节点.

the generated parse-tree will contain a node rContext with child nodes aContext, bContext, cContex, each potentially having further child nodes, for each instance in the input stream where the rule is matched.

walk 会产生一系列监听器(或访问者)调用

The walk will produce the series of listener (or visitor) calls

enterR
enterA
....
exitA
enterB
....
exitB
enterC
....
exitC
exitR

每个调用都包含对解析树中实例上下文的引用,从而可以访问可以以相对于中间子节点的前缀/后缀顺序传递给 ST 的实际值.

Each call contains a reference to the instance context within the parse-tree, giving access to the actual values that could be passed to ST in prefix/suffix order relative to intervening child nodes.

如果仅使用简单的前缀/后缀访问排序是不够的(或不合需要的复杂),请使用一个或多个先前的解析树遍历来分析更复杂的节点并使用分析产品注释节点实例.在最终输出步中,参考分析产品以将值传递给 ST.

Where simple prefix/suffix access ordering alone is not sufficient (or undesirably complex), use one or more prior parse-tree walks to analyze the more complex nodes and annotate the node instances with the analysis products. In the final output walk, reference the analysis products for the values to pass to ST.

根据实际情况,分析一个节点从其子节点收集值,将批次传递给模板进行细节扩展,格式化等,并将结果存储为节点注释字符串pending输出在最终输出行走中.

Depending on actual circumstances, it would not be unusual for the analysis of a node to collect values from its children, pass the lot to a template for detail expansion, formatting, etc, and store the result as a node annotation string pending output in the final output walk.

更新

要注释解析树节点,您可以使用 ParseTreeProperty.

To annotate parse-tree nodes, you can use ParseTreeProperty.

在注释集变得不仅仅是琐碎"的情况下,一个典型的选择是将节点类型特定的装饰器"类实例与解析树节点/上下文实例相关联,主要作为更好的数据容器.当然,然后可以将特定于节点类型的方法嵌入到它们对应的装饰器类中,以很好地分离关注点.

Where the annotation set becomes more than 'trivial', a typical option is to associate a node-type specific 'decorator' class instance with a parse-tree node/context instance largely as a better data container. Of course, the node-type specific methods can then be embedded into their corresponding decorator classes to keep concerns nicely separated.

监听器方法变成这样:

public void exitNodeB(NodeBContext ctx) {
    super.exitNodeB(ctx);
    NodeBDescriptor descriptor = (NodeBDescriptor) getDescriptor(ctx);
    if (analysisPhase) {
        descriptor.process(); // node-type specific analysis
    } else {
        descriptor.output();  // node-type specific output generation
    }
}

何时分析(进入、退出或两者)以及何时输出的细节将取决于特定的应用程序.根据您的目的实施.

The specifics of when to analyze (on enter, exit, or both) and when to output will be dependent on the particular application. Implement to suit your purposes.

这篇关于ANTLR 4 和 StringTemplate 4 - 使用带模板的 tree walker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆