ANTLR4中LIT_STRING规则空字符串匹配分支错误排查
解决ANTLR4中LIT_STRING规则的空字符串匹配错误
问题重现
你的词法分析器定义中,LIT_STRING规则触发了错误:
rule LIT_STRING contains a closure with at least one alternative that can match an empty string.
你的词法规则代码如下:
INT : 'Int'; FLOAT : 'Float'; STRING : 'String'; BOOL : 'Bool'; CHAR : 'Character'; LIT_INT : '0' | DIGIT DIGIT*; LIT_FLOAT : DIGIT+ '.' DIGIT+; LIT_STRING : '"' (ESCAPE|.)*? '"'; LIT_CHAR : '\'' (CHARACTER | ESCAPE) '\''; LIT_NIL : 'nil'; WS : [ \t]+ -> skip; ID : [a-zA-Z_][a-zA-Z0-9_]+; LINE_COMMENT : '//' .*? '\r'? '\n' -> skip; COMMNET : '/*' .*? '*/' -> skip; fragment DIGIT : [0-9]; fragment CHARACTER : [a-zA-Z]; fragment ESCAPE : '\\"' | '\\\\' || '\\n';
错误原因
问题出在ESCAPE片段规则的语法错误:你使用了||分隔分支,但ANTLR4仅支持单个|作为分支分隔符。这个||会被ANTLR解析为| |,相当于在分支中插入了一个空匹配项——也就是说ESCAPE规则允许匹配空字符串。
当LIT_STRING中的(ESCAPE|.)*?闭包包含能匹配空的分支时,就触发了该错误提示。
另外,LIT_STRING中的.会匹配任意字符(包括未转义的双引号),可能导致字符串提前终止,这也是一个潜在问题。
修复方案
- 修正ESCAPE规则的语法错误:把
||改成|,确保所有分支都是非空的合法转义序列:fragment ESCAPE : '\\"' | '\\\\' | '\\n'; - 优化LIT_STRING规则:把
.替换成~["](匹配除双引号外的任意字符),避免错误匹配结束引号,同时保证只有转义的引号能出现在字符串内容中:LIT_STRING : '"' (ESCAPE|~["])*? '"';
额外注意
你的COMMNET规则拼写错误,应该是COMMENT,建议一并修正,避免后续出现意外问题。
内容的提问来源于stack exchange,提问作者luisepa1420
相关产品推荐
相关产品推荐

