gpt4 book ai didi

java - 如何将 ANTLR 4 生成的 AST 翻译成它的源代码

转载 作者:行者123 更新时间:2023-11-30 11:29:26 26 4
gpt4 key购买 nike

我正在编写一个简单的解析器来将查询转换为 SQL。我已经完成了解析器并获得了 AST,但现在我需要使用 ANTLR 4 将这些语法转换为 SQL。有人知道如何在 ANTLR 4 中打印或翻译查询 "SELECT"as "SELECT"、"FROM"to "FROM" 等吗?

我遵循权威的 ANTLR 4 引用书。因为我们必须创建 2 个 java 文件。

在第一个 java 文件中,我想遵循这些步骤而不是

public void enterInit(ArrayInitParser.InitContext ctx)
{
System.out.print('"');
}

我已经改成了

public void enterSelect(ArrayInitParser.SelectContext ctx) 
{
System.out.print('SELECT');
}

ShortToUnicodeString.java

public class ShortToUnicodeString extends ArrayInitBaseListener 
{

/** Translate { to " */

@Override

public void enterInit(ArrayInitParser.InitContext ctx)
{
System.out.print('"');
}

/** Translate } to " */

@Override

public void exitInit(ArrayInitParser.InitContext ctx)

{
System.out.print('"');
}

/** Translate integers to 4-digit hexadecimal strings prefixed with \\u */

@Override

public void enterValue(ArrayInitParser.ValueContext ctx)

{
// Assumes no nested array initializers
int value = Integer.valueOf(ctx.INT().getText());
System.out.printf("\\u%04x", value);
}
}

在第二个 java 文件中,我遵循了以下步骤:

Translate.java

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

public class Translate
{

public static void main(String[] args) throws Exception
{

// create a CharStream that reads from standard input
ANTLRInputStream input = new ANTLRInputStream(System.in);
// create a lexer that feeds off of input CharStream
ArrayInitLexer lexer = new ArrayInitLexer(input);
// create a buffer of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// create a parser that feeds off the tokens buffer
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init(); // begin parsing at init rule
// Create a generic parse tree walker that can trigger callbacks
ParseTreeWalker walker = new ParseTreeWalker();
// Walk the tree created during the parse, trigger callbacks
walker.walk(new ShortToUnicodeString(), tree);
System.out.println(); // print a \n after translation
}
}

尝试使用字符串模板

我已经尝试在 antlr 4 中使用 StringTemplate。我可以翻译查询 select, from, where 但是当我翻译查询 and 时我不能。我的代码如下所示:

import org.stringtemplate.v4.*;

public class ToSql extends BaseListener
{

/** Translate select to select */
@Override
public void enterSelect( Parser.SelectContext ctx)
{
ST select = new ST("select");
System.out.print(select.render()+"\t");
}

/** Translate from to from */
@Override
public void enterFrom( Parser.FromContext ctx)
{
ST from = new ST("from");
System.out.print(from.render()+"\t");
}

/** Translate where to where */
@Override
public void enterWhere( Parser.WhereContext ctx)
{
ST where = new ST("where");
System.out.print(where.render()+"\t");
}

/** Translate boolOp to AND|OR|XOR */
@Override
public void enterBoolOp( Parser.BoolOpContext ctx)
{
ST boolOp = new ST("<and>");
if (boolOp == and)
{
boolOp.add("and", "AND");
System.out.print(boolOp.render()+"\t");
}
}
}

我的部分语法:

boolean 运算:或|异或|与;

谢谢。

最佳答案

我不知道代码生成在 v4 中是如何工作的,但根据我的一点经验,我认为你可以通过让你的语法中的规则吐出生成的输出来进行语法定向翻译来实现这一点。

  boolOp returns[String output] : OR {$output=$OR.text}
| XOR {$output=$XOR.text}
| AND{$output=$AND.text}
;

然后在你的 select 语句中,你也可以做同样的事情来返回字符串“select”“where”等等。您可以通过将 walker 的对象传递给 sysout 来遍历树并打印输出。

您只需处理您的格式(换行符、制表符等)以获得 pretty-print 输出。

关于java - 如何将 ANTLR 4 生成的 AST 翻译成它的源代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18339851/

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