Antlr4简介

简介

通过Antlr4可以定义一种新的语言或者规则。它是跨语言的。

一个简单例子如下:

// Tokens
MUL: '*';
DIV: '/';
ADD: '+';
SUB: '-';
NUMBER: [0-9]+;
WHITESPACE: [ \r\n\t]+ -> skip;

// Rules
start : expression EOF;

expression
   : expression op=('*'|'/') expression # MulDiv
   | expression op=('+'|'-') expression # AddSub
   | NUMBER                             # Number
   ;

组成

上面的简单与法例子中,包含两个部分,tokens和rules。Token是语法中最基础(不可分割)元素,传统的lex就是将输入流转换为一个一个tokens。Rules是tokens和其它rules的组合规则,通过定义的优先级,最终将组合成一棵抽象树。抽象树决定的是程序运行的步骤。

对于Antlr4而言,rule和token的另一个区别是rule会有回调函数(listener,后面会提到),通过这些回调函数实现新语法的解析与执行。

获取

wget http://www.antlr.org/download/antlr-4.7-complete.jar
alias antlr='java -jar $PWD/antlr-4.7-complete.jar'
antlr -Dlanguage=Go -o parser Calc.g4

生成文件

calc.tokens
calcLexer.tokens
calc_base_listener.go
calc_base_visitor.go
calc_lexer.go
calc_listener.go
calc_parser.go
calc_visitor.go

主要包含lex, parser, visitorlistener四个部分。Lex的作用是生成tokensparser利用lex生成的tokens按照rule定义的规则生成抽象树,visitorlistener是两种语法解析的方法,通常使用一种即可

Token

上述的例子,会生成一下的tokensNUMBER (1), ADD (+), NUMBER (2), MUL (*), NUMBER (3), EOF

Parser

按照语法的优先级进行结合,下图中红色部分是rule,蓝色部分是token

Listener

抽象树生成后,我们可以遍历该树,Antlr4会在进入(enter)和退出(exit)节点是出发回调函数(event driven manner),这样用户程序就可以感知到正在处理的token和rule。整个遍历过程,相当于代码(规则)编译,编译好后就可以直接执行了。

语法规则

grammar 名称和文件名要一致
Parser 规则(即 non-terminal)以小写字母开始
Lexer 规则(即 terminal)以大写字母开始
所有的 Lexer 规则无论写在哪里都会被重排到 Parser 规则之后
所有规则中若有冲突,先出现的规则优先匹配
用 'string' 单引号引出字符串
| 用于分隔两个产生式,(a|b) 括号用于指定子产生式,?+*用法同正则表达式
在产生式后面 # label 可以给某条产生式命名,在生成的代码中即可根据标签分辨不同产生式
不需要指定开始符号
规则以分号终结
/* block comment */ 以及 // line comment
默认的左结合,可以用 <assoc=right> 指定右结合
可以处理直接的左递归,不能处理间接的左递归
如果用 MUL: '*'; 指定了某个字符串的名字,在程序里面就能用这个名字了
用 fragment 可以给 Lexer 规则中的公共部分命名

 


版权声明:本文为zhanglehes原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。