前言
Antlr4没看到用IDEA的教程,把第一个小练习写出来。
用自然语言解释,翻译过程就是一系列“X映射为Y”的过程:
1)将{翻译为"。
2)将}翻译为"。
3)将每个整数翻译为四位的十六进制形式,然后加前缀\u。
为此,我们需要编写方法,在遇到对应的输入词法符号或者词组的时
候,打印出转换后的字符串。
创建一个语法文件ArrayInit.g4
//语法文件grammar关键字开头
//这是一个名为ArrayInit的语法,它必须和文件名ArrayInit.g4相匹配
grammar ArrayInit;
//----语法分析器 必须以小写字母开头
init : '{' value (',' value)* '}' ; //至少匹配一个value
//一个value可以是嵌套的花括号结构,也可以是一个简单的整数,即INT词法符号
value : init
| INT
;
//----词法分析器必须以大写字母开头
INT : [0-9]+; //定义词法符号INT,它由一个或多个数字组成
WS : [\t\r\n]+ -> skip; //定义词法规则“空白符号”,丢弃之
我们需要通过Antlr的工具来生成如下一些文件
在安装好Antlr4后右击ArrayInit.g4
中的Configure ANTLR
在生成所有输出的输出目录中,选择你要生成的地方与g4文件同目录即可
之后点击generate ANTLR recognizer生成上述文件
文件如下:
之后创建Test.java
package TranslateShortToUnicodeStringTest;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Test {
public static void main(String[] args) throws Exception{
ANTLRInputStream input = new ANTLRInputStream(System.in);
ArrayInitLexer lexer = new ArrayInitLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init();
System.out.println(tree.toStringTree(parser));
}
}
运行test.java中主函数,输入{1,2
后按ctrl+d结束
我们可以看到它已经可以检查语法正确性了。
接着创建文件ShortToUnicodeString.java
继承ArrayInitBaseListener类,覆盖其中必要的方法
package TranslateShortToUnicodeStringTest;
public class ShortToUnicodeString extends ArrayInitBaseListener {
@Override
public void enterInit(ArrayInitParser.InitContext ctx){
System.out.print('"');
}
@Override
public void exitInit(ArrayInitParser.InitContext ctx){
System.out.print('"');
}
@Override
public void enterValue(ArrayInitParser.ValueContext ctx){
int value = Integer.valueOf(ctx.INT().getText());
System.out.printf("\\u%04x",value);
}
}
现在,把之前的Test类扩展成一个翻译程序了,文件Translate.java
package TranslateShortToUnicodeStringTest;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
public class Translate {
public static void main(String[] args) throws Exception{
ANTLRInputStream input = new ANTLRInputStream(System.in);
ArrayInitLexer lexer = new ArrayInitLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ArrayInitParser parser = new ArrayInitParser(tokens);
ParseTree tree = parser.init();
ParseTreeWalker walker = new ParseTreeWalker();
walker.walk(new ShortToUnicodeString(),tree);
System.out.println();
}
}
运行translate.java
输入{99,3,451}
得到输出"\u0063\u0003\u01c3"
参考:ANTLR 4权威指南 (【英】特恩斯·帕尔, ePUBw.COM) (z-lib.org)