ANTRL 简单翻译器的构成(监听器)

使用场合:我们想通过编写程序来操纵输入数据的话,只需要继承xxxxxBaseListener类,然后覆盖其中方法即可。基本思想是,在遍历器进行语法分析树的遍历时,令每个监听器方法翻译输入数据的一部分并将 结果打印出来。

监听器的优雅之处:不需要自己编写任何遍历语法分析树的代码。只需要知道在语法规则对应的语句的开始和结束位置处,通过监听器方法可以得到通知。

一个翻译工作的项目意味着要处理这样的问题:如何将输入的词法符号或者词组翻译成输出字符串。

程序目标:{99,3,451}翻译为"\u0063\u0003\u01c3"

解决案分解:

1.编写{99,3,451}对应的G4文件【DemoArrayInitPrase.g4】

/*
 * DemoArrayInitPrase
 * 文法ファイルは「grammar」で始まります。
 * 文法名「DemoArrayInitPrase」はg4ファイル名と一致します。
 */
grammar DemoArrayInitPrase;

//grammar解析器規則:規則名は小文字の先頭です。
init :    '{' value (',' value )* '}' ;
value :   init
      |   INT
      ;

//Lexical解析器規則:規則名は大文字の先頭です。
INT:    [0-9]+ ;      //一つ以上の数字
WS :    [ \t\r\n]+ -> skip; //ブランク、記号を破棄する

2.生成对应的antrl代码

准备工作:antrl4.bat提前放置好

antlr4.bat -visitor -listener -o D:\ANTLRTools\START_G4\DemoArrayInit START_G4/DemoArrayInitPrase.g4

运行结果: 

 

 

3.Listener实现类

​​​​package com.demo.g4.ArrayInitPraseImpl;

import com.demo.g4.ArrayInitPrase.DemoArrayInitPraseBaseListener;
import com.demo.g4.ArrayInitPrase.DemoArrayInitPraseParser;

/**
 * {1,3,4}→"\u0001\u0002\u0003"
 */
public class ShortToUnicodeStringListener extends DemoArrayInitPraseBaseListener{
    StringBuilder sb;

    public ShortToUnicodeStringListener(StringBuilder sb){
        this.sb = sb;
    }

    @Override
    public void enterInit(DemoArrayInitPraseParser.InitContext ctx){
        sb.append("\"");
    }

    @Override
    public void exitInit(DemoArrayInitPraseParser.InitContext ctx){
        sb.append("\"");
    }

    @Override
    public void enterValue(DemoArrayInitPraseParser.ValueContext ctx){
        Integer integer = Integer.valueOf(ctx.INT().getText());
        sb.append("\\u" + Integer.toHexString(integer));
    }

}

4.Translate实现类

package com.demo.g4.translate;

import org.antlr.v4.runtime.CharStreams;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeWalker;

import com.demo.g4.ArrayInitPrase.DemoArrayInitPraseLexer;
import com.demo.g4.ArrayInitPrase.DemoArrayInitPraseParser;
import com.demo.g4.ArrayInitPraseImpl.ShortToUnicodeStringListener;

/**
 * {1,3,4}→"\u0001\u0002\u0003"
 */
public class ShortToUnicodeStringTranslate{

    public static void main(String[] args){
        StringBuilder newSb = new StringBuilder();
        DemoArrayInitPraseLexer lexer = new DemoArrayInitPraseLexer(CharStreams.fromString("{1,2,3}"));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        DemoArrayInitPraseParser parser = new DemoArrayInitPraseParser(tokens);
        ParseTree tree = parser.init();

        //新建一个通用的能够触发回调函数的语法分析树遍历器
        ParseTreeWalker walker = new ParseTreeWalker();
        //遍历语法分析过程中生成的语法树,触发回调
        walker.walk(new ShortToUnicodeStringListener(newSb), tree);

        System.out.println(newSb.toString());
    }
}
发布了4 篇原创文章 · 获赞 0 · 访问量 17

猜你喜欢

转载自blog.csdn.net/m0_37727363/article/details/105711108
今日推荐