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());
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值