gpt4 book ai didi

java - 在 Antlr 中使用访问者编辑 AST

转载 作者:行者123 更新时间:2023-12-02 11:16:14 25 4
gpt4 key购买 nike

我是 AntLR 新手,我正在努力执行以下操作:

我想做的是在解析了一个源文件(当然我有一个有效的语法)并且内存中有 AST 之后,去改变一些东西,然后通过访问者将其打印回来API。

例如

int foo() {
y = x ? 1 : 2;
}

并将其变成:

int foo() {
if (x) {
y = 1;
else {
y = 2;
}
}

到目前为止,我已经有了适当的语法来解析此类语法,并且我还创建了一些访问者方法,当我处于正确的位置时,这些方法会被调用。令我困惑的是,在访问期间我无法更改文本。

理想情况下我想要这样的东西:

public Void visitTernExpr(SimpleCParser.TernExprContext ctx) { 
ctx.setText("something");
return null;
}

在我的 Main 中,我想让不同的访问者编辑这个 AST,他们每个人都专门从事某件事。像这样:

ANTLRInputStream input = new ANTLRInputStream(new FileInputStream(filename));
SimpleCLexer lexer = new SimpleCLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
SimpleCParser parser = new SimpleCParser(tokens);
ProgramContext ctx = parser.program();

MyChecker1 mc1 = new MyChecker1();
mc1.visit(ctx);
MyChecker2 mc2 = new MyChecker2();
mc1.visit(ctx);

ctx.printToFile("myfile");

有没有办法在 AntLR 中做这些事情,或者我的方向是非常错误的?

最佳答案

您可以通过破坏 AST 节点和链接来完成此 ANTLR。您将创建所有替换子树节点并将它们拼接到位。然后你必须实现“吐源文本”树遍历;我建议您为此目的研究“字符串模板”。

但最终你必须做很多工作才能达到这个效果。这是因为 ANTLR 工具的目标主要集中在“解析”上,剩下的就交给你了。

如果您想要做的是将一组语法替换为另一组语法,那么您真正想要的是 program transformation system 。这些工具已内置上述所有功能,因此您无需重新设计它们。它们通常还具有源到源的转换,这使得完成您所展示的任务变得非常非常容易。

要使用我们的 DMS 程序转换引擎完成您的示例,您需要编写一个转换规则,然后应用它:

rule replace_ternary_assignment_by_ifthenelse
(l: left_hand_side, c: expression, e1: expression, e2: expression):
statement -> statement
"\l = \c ? \e1 : \e2;"
=> " if (\c) \l = \e1; else \l = \e2 ";

DMS 解析您的代码,构建 AST,查找重写的匹配项,为您构建/拼接所有这些替换节点。最后,DMS 具有内置的 pretty-print 来重新生成文本。重点所有这一切都是为了让您继续修改您的代码,而不是在你可以之前创建一个全新的工程工作做你的任务。轻松阅读我的文章“解析后的生活”通过我的简历或通过谷歌搜索找到有关此主题的更多信息。

[如果您转到 DMS wikipedia page ,你会有趣地发现以该变换的逆作为示例]。

关于java - 在 Antlr 中使用访问者编辑 AST,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33402006/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com