hive之SQL解析器Antlr简单学习总结。

HIVEsql解析通过鼎鼎大名的ANTLR完成,具体细节可以在http://www.antlr.org/详细了解,这里只整理一些自己的小心得。

1.       终结符首字母大写,非终结符首字母小写

2.       AntlrLL文法不支持左递归,需要消除文法中的左递归。

3.       代码优先级采用highOpExpr: lowOpExpr op lowOpExpr的方式解决。

 

具体实例:

1.算子优先级问题解决:

解析如下算数表达式: 5+3*4

 

NUM:'0'..'9'('0'..'9')*;

LEFT:'(';

RIGHT:')';

ADD:'+';

MULTI:'*';

 

statement:

         addStatement;

        

addStatement:

         multiStatement ADD multiStatement;

        

multiStatement:

         NUM

         | NUM MULTI NUM;

 

这样就解决了算子优先级问题。

 

2. 嵌套问题解决

解析如下算数表达式

3+(5*(6+2)+2*(4+8))*(6+2)

 

括号优先级比乘法算子高,乘法优先级比加法高,而括号中有嵌套了加法和乘法表达式。

 

NUM:'0'..'9'('0'..'9')*;

LEFTBRACKET:'(';

RIGHTBRACKET:')';

ADD:'+';

MULTI:'*';

WS : (' ' |'\t' |'\n' |'\r' )+ {skip();} ;

 

start         :       

         addStatement;

addStatement:

         multiStatement ( ADD^ multiStatement )*;

        

multiStatement:

         expr ( MULTI^ expr )*;

        

expr:

         NUM|

         LEFTBRACKET! addStatement RIGHTBRACKET!;

 

在子句中引用上层元素,达到了实现嵌套语句目的的同时也消除了左递归问题.

 

整理LL(1)文法编译器简单过程描述。

1.       通过FIRST几个何FOLLOW集合构建预测分支表。

2.       构建辅助栈Stack

3.       将最终的非终结符S入栈Stack

4.       从栈Stack弹出一个元素e

5.       读取token数据流,得到一个tokenA

6.       弹出的元素e如果为非终结符NotTerminal,从预测分支表中以NotTerminaltokenA为主键查询此NoTerminal的构成式并从右向左依次压入堆栈,如果栈顶还是非终结符,弹出该非终结符继续从预测分支表中查询构成式,并从右向左依次压入堆栈,循环此逻辑直到栈顶为终结符,则弹出栈顶元素与元素e比对,如果不同则保错退出。

7.       如果弹出的元素e为终结符,和tokenA进行对比,如果不相等则保错。

8.       继续步骤4,直到栈Stack为空。

 

LL文法主要过程就是从最终的非终结符开始,不断将最左边也就是栈顶的非终结符用产生式进行替换,针对LL(k)的文法过程中一个非终结符+一个token可能会出现多个产生式,需要采取回溯的方式找到最合适的匹配。

 

而针对大部分SQL语句,基本上LL(1)文法就可以描述,因为每个语句元素,通过SQL语句中的第一个词就可以判断出该子句具体是什么操作,比如 SELECT GROUP BY WHERE JOIN等。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值