问题描述
我正在尝试将AST与ANTLR4一起使用,包含以下文件:
I'm trying to use ASTs with ANTLR4, with this files:
Builder.java
Builder.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:
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)
{
}
}
Expr.g:
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很难理解访客。
I find it hard to understand visitors with ANTLR4.
我有树目标:
- 获取MEASU的收集INT RE和ACTION(分为两组)
- 替换一些OP(例如!= by<>)
- 获取condexpr(顶部) item)字符串与OPs重新播放(我之前的观点)
推荐答案
你可以使用树标签使用,设置解析的上下文,然后使用访问者类和触发器方法遍历观察图形的叶子,以便根据语言源代码中的表达式创建操作。因此,在初始访问时,收听者不处理实际的访问者模式。实际的访问者模式和访问处理是通过expressionbase监听器类扩展的方法完成的。
A tree label you could use, to set the context of the parse and then walks the leaves of the observed graph with a visitor class and trigger methods in order to create actions from the expressions in the language source code. Thus, at the initial visitation, the listener does not process the actual visitor pattern. The actual visitor pattern and the processing through visitation is done by the methods of the expressionbase listener class extension.
监听器识别表达式:
@Override public void enterListener(ExprParser.EXPR_CONTEXTContext ctx) {
//some code to view the compilation process
}
表达式规则获取名称标签:
'EXPR_CONTEXT' expression # EXPR_CONTEXT //the tree label
表达式walker已实现:
public class ExprWalker extends ExprBaseListener {
@Override
public void enterListener(ExprParser.EXPR_CONTEXTContext ctx) {
java.util.List<ExprParser.ExpressionContext> e = ctx.expression();
System.out.println("EXPRESSION: " //print action
+ e.get(0).getText() + ", " //first element
+ e.get(1).getText() //second element
+ ", " + ... + ", " //number of elements
+ e.get(N).getText()); //last element
}
主文件然后走与walker:
ParseTree tree = parser.parse(); //parse the tree
intermezzo:在应用walker访问模式之前,可以想象树段优化 - 或者处理模式。解析的树可以在这里作为源代码树的单独归纳处理。这种方法可以实现更复杂的代码和树处理模式。
intermezzo: before applying the walker visitation pattern one may imagine tree segment optimisation- or processing patterns. The parsed tree could be handled here as a seperate induction of the source code tree. This approach enables more complicated code- and tree processing patterns.
ParseTreeWalker walker = new ParseTreeWalker(); //get the walker
walker.walk(new ExprWalker(), tree); //start visiting
这篇关于ANTLR 4和AST访客的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!