1. antlr4是用来干什么的?
是用来生成某语言lexer和parser的。
通俗点说,就是输入一个语言的规则描述文件,输出这个语言的lexer和parser。
2. 什么是lexer和parser?
编译可以分成词法分析,语法分析,语义分析等若干步骤,
以如下c++代码为例
int b;
int a=b+1;
词法分析是把源代码分成一个token序列,lexer就是负责词法分析的程序,lexer中文叫分词器或词法分析器,上述代码可能会被lexer分成如下token序列
int 'int'
identifier 'b'
semi ';'
int 'int'
identifier 'a'
equal '='
identifier 'b'
plus '+'
numeric_constant '1'
semi ';'
eof ''
语法分析是把经词法分析得到的token序列,转换成一颗抽象语法树,parser就是负责语法分析的程序,parser的中文叫语法分析器或解析器,上述代码可能会被解析成如下抽象语法树
|-VarDecl 0x1cf11c82838 used b 'int'
`-VarDecl 0x1cf11c82918 a 'int' cinit
`-BinaryOperator 0x1cf11c829e0 'int' '+'
|-ImplicitCastExpr 0x1cf11c829c8 'int' <LValueToRValue>
| `-DeclRefExpr 0x1cf11c82980 'int' lvalue Var 0x1cf11c82838 'b' 'int'
`-IntegerLiteral 0x1cf11c829a0 'int' 1
3. 使用antlr4生成某语言的lexer和parser的具体过程
在下文中为了避免混淆,先澄清一些名词的含义。例如,我们使用ANTLR4工具生成了用于解析XML语言lexer和parser,而生成的lexer和parser的源代码是Python的。在这个例子中,XML语言是要解析的语言,而Python是最终生成的代码的目标语言。
下文使用术语“被解析语言”来指代需要解析的语言,它既可以是编程语言,也可以是其他类型的语言。而“目标语言”则严格指代生成的代码所采用的编程语言。ANTLR4工具支持通过编写语言规则文件来支持各种自定义的“被解析语言”。目前,ANTLR4支持十几种常见的目标语言,如C++、Java、Python等。
具体生成lexer/parser的过程如下:
- 安装antlr4,参考https://github.com/antlr/antlr4/blob/master/doc/getting-started.md
- 编写被解析语言的规则文件,规则文件的具体写法可参考https://github.com/antlr/antlr4/blob/master/doc/grammars.md,antlr4项目本身已经包含了大量写好的常见语言的规则文件,在仓库https://github.com/antlr/grammars-v4里,这样大部分常见语言都不用自己写规则文件了。
- 根据规则文件生成对应的lexer/parser和对应lexer/paser依赖的运行时库,参考https://github.com/antlr/antlr4/blob/master/doc/getting-started.md,其中需要注意的是选择是否生成ast对应的visitor或listener,visitor和listener都是用来遍历抽象语法树的。
4. 其他
antlr4一般是用来生成自定义语言或者比较小众的语言的语法分析器的,如果是需要解析比较常用的语言,可能用现成的lexer/parser,比使用antlr4生成的lexer/parser更合适。例如解析c++有clang,解析python有ast标准库,都比antlr4方便且强大。