gpt4 book ai didi

java - ANTLR 4 和 AST 访问者

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:55:02 29 4
gpt4 key购买 nike

我正在尝试将 AST 与 ANTLR4 一起使用,并使用以下文件:

生成器.java

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;

public class Builder
{

public static void main(String[] args)
{
CharStream input = new ANTLRInputStream("ON M1==2 && M3 == 5 && (M2 > 1 || M5 <= 5.0) "
+ "DO P5:42 P4:10");
ExprLexer lexer = new ExprLexer(input);
TokenStream tokens = new CommonTokenStream(lexer);
ExprParser parser = new ExprParser(tokens);
parser.addParseListener(new ExprTestListener());
ExprParser.ExpressionContext uu = parser.expression();
}

}

ExprTestListener:

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.tree.ErrorNode;

public class ExprTestListener extends ExprBaseListener {
@Override public void enterExpression(ExprParser.ExpressionContext ctx)
{
System.out.println(ctx);
}
@Override public void exitExpression(ExprParser.ExpressionContext ctx)
{
System.out.println(ctx);
}

@Override public void enterActionexpr(ExprParser.ActionexprContext ctx)
{
System.out.println(ctx);
}
@Override public void exitActionexpr(ExprParser.ActionexprContext ctx)
{
System.out.println(ctx);
}

@Override public void enterCondexpr(ExprParser.CondexprContext ctx)
{
System.out.println(ctx);
}
@Override public void exitCondexpr(ExprParser.CondexprContext ctx)
{
System.out.println(ctx);
}

@Override public void enterCond(ExprParser.CondContext ctx)
{
System.out.println(ctx);
}
@Override public void exitCond(ExprParser.CondContext ctx)
{
System.out.println(ctx);
}

@Override public void enterEveryRule(ParserRuleContext ctx)
{
System.out.println(ctx);
}
@Override public void exitEveryRule(ParserRuleContext ctx)
{
System.out.println(ctx);
}
@Override public void visitTerminal(TerminalNode node)
{
}
@Override public void visitErrorNode(ErrorNode node)
{
}
}

表达式:

grammar Expr;
options
{
// antlr will generate java lexer and parser
language = Java;

}
WS : [ \t\r\n]+ -> skip ;
OP : '&&' | '||';
COMP : '==' | '<' | '>' | '<=' | '>=' | '!=';
fragment INT : [0-9]+;
REAL : INT '.' INT | INT;

ACTION : 'P' INT ':' INT;
MEASURE : 'M' INT;

// ***************** parser rules:
cond : MEASURE COMP REAL;
condexpr : '(' condexpr ')' | cond OP condexpr | cond;
actionexpr : ACTION actionexpr | ACTION;
expression : 'ON' condexpr 'DO' actionexpr;

我有这个输出:

[]
[]
[29]
[29]
[16 29]
[16 29]
[16 29]
[16 29]
[18 29]
[18 29]
[16 18 29]
[16 18 29]
[16 18 29]
[16 18 29]
[18 18 29]
[18 18 29]
[13 18 18 29]
[13 18 18 29]
[16 13 18 18 29]
[16 13 18 18 29]
[16 13 18 18 29]
[16 13 18 18 29]
[18 13 18 18 29]
[18 13 18 18 29]
[20 18 13 18 18 29]
[20 18 13 18 18 29]
[20 18 13 18 18 29]
[20 18 13 18 18 29]
[18 13 18 18 29]
[18 13 18 18 29]
[13 18 18 29]
[13 18 18 29]
[18 18 29]
[18 18 29]
[18 29]
[18 29]
[29]
[29]
[31]
[31]
[24 31]
[24 31]
[24 31]
[24 31]
[31]
[31]
[]
[]

我发现很难用 ANTLR4 理解访问者。

我有树木目标:

  • 收集 MEASURE 和 ACTION 的 INT(在两个不同的集合中)
  • 替换一些 OP(例如 != 为 <>)
  • 获取重新放置 OP 的 condexpr(最上面的项目)字符串(这是我之前的观点)

最佳答案

首先,我将解释您在上面观察到的内容:

首先,请阅读您调用的方法的文档。 Parser.addParseListener文档包括以下注释:

THIS IS ONLY FOR ADVANCED USERS. Please give your ParseTreeListener to a ParseTreeWalker instead of giving it to the parser!!!!

ParserRuleContext 类的 toString() 的实现只是在创建上下文时打印规则调用堆栈。当监听器输入规则时打印一次,退出时打印一次。对于 actionexprcondcondexpr,您再次打印它,每个上下文总共产生 4 条相同的输出行。

现在请注意您的目标:

  • enterCondexitCond 中,MEASURE 文本可通过调用 ctx.MEASURE().getText()
  • enterActionexprexitActionexpr 中,ACTION 文本可通过调用 ctx.ACTION().getText()
  • 您可以通过为更新的 token 创建新的 TerminalNodeImplCommonToken 并将其分配给正确的索引来更改 COND token 使用访问者或监听器的字段 CondContext.children

关于java - ANTLR 4 和 AST 访问者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14667781/

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