Parse a formula using ANTLR4

醉酒当歌 提交于 2019-12-10 00:10:30

问题


I am trying to parse a mathematical formula to a subset of LaTeX using ANTLR4. For example it should parse (a+4)/(b*10) to \frac{a+4}{b\cdot 10}.

My simple grammar creates a tree like this:

Now I am trying to implement parse tree listeners to somehow construct the LaTeX String while the tree is traversed. Here, I am failing because to construct a String like \frac{}{} it has to be built recursively. The parse tree walker, however, visits one tree node after the other (in a breadth-first way as far as I can tell).

I've read about parse tree visitors that might be what I need. But I wasn't able to find some examples how these visitors are applied.

Could you provide an example how parse tree listeners/visitors can be used in this particular case? Do you think my approach to use ANTLR for the parser makes sense in the first place?


回答1:


You can create a parse tree walker by implementing the ParseTreeVisitor interface. For ease of use, you can specify Antlr to generate a base visitor when compiling the grammar (in Antlrworks, Run->Generate Recognizer->Next->Generate Visitor->Next->Finish). The base visitor will be called MyGrammarBaseVisitor. Note that the visitor has a generic type T, which every single visit method should return. I recommend using Void for manual manipulation or String for ease of use during code generation.

After you extend the base visitor (I'll assume here we're dealing with String), you need to override the visit methods. These methods are named after the grammar rules you have. Each of these methods will receive a ParserContext ctx parameter, which you use to visit child rules and/or get terminal values. For example, you could do this:

class MyVisitor extends MyGrammarBaseVisitor<String> {
    @Override
    public String visitMultiplicative(MyGrammarParser.MultiplicativeContext ctx) {
        if (ctx.opMult().getText().equals("/")) return "\\frac{" + visit(ctx.expr(0)) + "}{" + visit(ctx.expr(1)) + "}";
        else return visit(ctx.expr(0)) + "\\cdot " + visit(ctx.expr(1));
    }
    // visit methods for other rules...
}

I'm assuming your multiplicative rule looks like multiplicative: expr opMult expr; opMult: '*' | '/'; You can find more information in The Definitive Antlr 4 Reference. You may also find more information and examples in the Antlr documentation.



来源:https://stackoverflow.com/questions/26468348/parse-a-formula-using-antlr4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!