使用场合:我们想通过编写程序来操纵输入数据的话,只需要继承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());
}
}