Antlr4-解析顺序
Antlr4是一款十分优秀的语法解析工具,由于其优秀的能力被用于HIive,Spark, Elasticsearch等大型的开源项目中。通过学习Antlr4的使用,我们可以构建自己的语法解析方法。
上次说到Antlr4的解析方式,是从上至下的递归下降的语法分析方式,这次我们具体看一下其解析的顺序与方式。
首先,我们可以先创建如下语法文件。
grammar Hello2; // 定义语法的名字
assign : ID '=' expr ;
expr : 'hello' ID ; // 匹配关键字hello,后面跟着一个标志符
ID : [a-z]+ ; // 匹配小写字母标志符
WS : [ \t\r\n]+ -> skip ; // 跳过空格、制表符、回车符和换行符
如果我们将其中的语法规则assign解析成方法函数的话,根据递归向下的原则,会变成如下的样子:
void assign() { // 根据规则assign生成的方法
match(ID); // 比较ID和当前输入符号然后消费
match('=');
expr(); // 通过调用expr()匹配表达式
}
当调用这个方法去匹配的语句的时候,便会先执行match方法匹配ID词法解析器的词法规则去消费输入的符号,然后再去matrch “=”符号,最后是去执行下一个expr的语法解析规则去匹配接下来的语句剩余部分。
所以根据这个规则,expr的解析出来的方法为:
void expr() {
match("hello");
match(ID);
}
现在我们输入一个字符串” abc = hello abcd”,就可以获得如下的语法解析树
可以看出,根据从上而下的递归解析规则,首先是assign作为根语法解析规则开始匹配字符串,先是词法规则ID根据正则规则匹配到了“abc”字符串,然后直接匹配到了”=”号,之后又将剩余的部分交给了expr语法规则去匹配,expr也执行了一样的流程,匹配到了”hello”和ID词法规则。
这样,语法解析的顺序就十分的清楚了,但是我们一般解析的时候不是只匹配一种规则,需要根据语法的不同进行不同的解析,因此Antlr4也支持类似switch的语法解析方式,我们对之前的语法文件进行修改,如下
grammar Hello2; // 定义语法的名字
assign : ID '=' expr ;
expr
: 'hello' ID
| 'bye' NO ;
ID : [a-z]+ ; // 匹配小写字母标志符
NO : [0-9]+ ; // 匹配小写数字标志符
WS : [ \t\r\n]+ -> skip ; // 跳过空格、制表符、回车符和换行符
可以看到expr的语法解析规则被改变了,多添加了一个‘|’符号以及后面的解析规则,这里可以将expr的匹配视为switch的逻辑,被’|’分开的就是case后腰匹配的规则。现在我们将字符串” abc = bye abcd”,进行解析,可以看到,他的解析规则已经走入’bye’ NO 的匹配,并提示你 “abcd”与他的正则规则不匹配。
当然,你可以将abcd换成任意的数字例如12345,使得NO词法规则可以匹配,然后得到正确的解析:
至此,Antlr4的语法的基本解析顺序就介绍完了
- 点赞
- 收藏
- 关注作者
评论(0)