Antlr4:两条相同词法规则场景下如何调整语法使其正常运行
问题根因
ANTLR4词法分析遵循两个优先级规则:
- 词法规则按定义顺序从上到下匹配,同长度匹配结果优先返回先定义的符号类型
- 优先匹配最长的可识别字符序列
你当前的语法中COLUMN规则[a-z_]+的匹配范围完全被STRING_LITERAL规则[a-zA-Z_]+覆盖,且COLUMN定义在STRING_LITERAL之前,所有小写字母+下划线组成的串都会被识别为COLUMN类型,永远不会返回STRING_LITERAL,导致value节点匹配失败触发解析错误。
解决方案
方案1:字符串加定界符(规范推荐)
给字符串值增加引号定界符,从词法层面彻底消除歧义,是查询类语法的通用实现方案。
修改后语法:
grammar qwe; query : COLUMN OPERATOR value EOF ; COLUMN : [a-z_]+ ; OPERATOR : ('='|'>'|'<') ; // 字符串字面量用单/双引号包裹 STRING_LITERAL : '"' [a-zA-Z_]+ '"' | '\'' [a-zA-Z_]+ '\'' ; value : STRING_LITERAL ; WS : [ \t\r\n]+ -> skip ;
修改后查询语句写法调整为 total_sales>'qwe' 即可正常解析。
方案2:统一词法规则,语法层区分
如果必须保留total_sales>qwe这种无引号的写法,可以把重叠的词法规则合并,在语法层面按位置区分列名和值,后续需要校验列名格式的话可以在语法树遍历阶段单独处理。
修改后语法:
grammar qwe; query : column OPERATOR value EOF ; column : IDENTIFIER ; value : IDENTIFIER ; OPERATOR : ('='|'>'|'<') ; IDENTIFIER : [a-zA-Z_]+ ; WS : [ \t\r\n]+ -> skip ;
该方案无需调整原有查询语句的写法即可正常解析。
内容的提问来源于stack exchange,提问作者Альберт Александров
相关产品推荐
相关产品推荐

