ANTLR TSQL语法新增DAYZ函数后同类规则生成解析树差异原因问询
问题原因分析
核心问题出在ANTLR的词法分析与语法分析的分离执行机制,以及你没有为新增的DAYZ函数定义对应的词法规则:
- ANTLR的执行流程是先运行词法分析器,把输入的文本切分成一个个token,再把token流送给语法分析器匹配规则。语法规则里引用的大写标识符(比如你写的
DAYZ)本质是要匹配对应名称的token,不是直接匹配文本。 - 原有语法里的
DATEDIFF、DATEADD早就已经在词法规则中被定义为独立的关键字token,且定义顺序排在普通ID(_Id)规则之前,所以词法分析阶段不会把它们识别为普通ID,语法分析时就能顺利匹配到built_in_functions里的对应分支。 - 你只在语法规则里加了
DAYZ的匹配分支,没有在词法规则里声明DAYZ为关键字token,所以词法分析阶段DAYZ会被判定为普通的_Idtoken,语法规则里要求匹配DAYZtoken的分支自然无法命中,就会出现解析异常。
解决步骤
- 找到你使用的TSql语法对应的词法规则文件(一般是
TSqlLexer.g4),找到内置函数关键字的定义区段(可以搜索DATEDIFF定位到对应位置)。 - 在该区段新增
DAYZ的词法规则,要注意和原有其他函数关键字的大小写匹配规则保持一致,参考写法如下:
DAYZ: D A Y Z;
(注:原有TSql语法一般会预定义大小写不敏感的字母片段规则,直接按原有其他函数的写法对齐即可)
3. 确保DAYZ的词法规则定义在普通ID(_Id)规则的前面:ANTLR词法规则匹配优先级是同匹配长度下,先定义的规则优先级更高,如果写在ID规则之后,DAYZ还是会被优先识别为普通ID。
4. 重新生成ANTLR的词法、语法分析代码,再用grun测试即可正常匹配DAYZ的内置函数规则。
内容的提问来源于stack exchange,提问作者QFirstLast
相关产品推荐
相关产品推荐

