ANTLR4语法无法正确匹配字符串末尾转义引号问题排查
ANTLR4字符串规则无法匹配末尾含转义引号的问题
我正在为一种使用双引号定义字符串、支持反斜杠转义引号的语言开发ANTLR4语法,当前定义的字符串匹配规则如下:
STRING: '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; fragment ESC_SEQ : '\\' ( // The standard escaped character set such as tab, newline, etc. [btnfr"'\\] | | // A Java style Unicode escape sequence UNICODE_ESC | // Invalid escape . | // Invalid escape at end of file EOF ) ; fragment UNICODE_ESC : 'u' (HEX_DIGIT (HEX_DIGIT (HEX_DIGIT HEX_DIGIT?)?)?)? ;
该规则能正确解析类似"test \"string\" that works"的字符串,但无法处理末尾包含转义引号的情况,比如"test string that does \"not work\""(预期解析后为"test string that "works"")。尝试修改规则添加额外分支后问题依旧。
错误原因
- ESC_SEQ的
EOF分支干扰:当解析到字符串末尾的\"时,ANTLR会错误地将后续的闭合引号"识别为ESC_SEQ中的无效转义(因为规则允许\\后跟任意字符甚至EOF),导致STRING规则找不到闭合的双引号。 - 修改后的规则逻辑混乱:添加的
| ('\\' '"')分支属于冗余逻辑,原规则中的ESC_SEQ已经包含了\"的匹配,反而破坏了原有规则的优先级。
修正后的语法
STRING: '"' ( ESC_SEQ | ~('\\'|'"') )* '"' ; fragment ESC_SEQ : '\\' ( // 标准转义字符:tab、换行、引号、反斜杠等 [btnfr"'\\] | // Java风格Unicode转义(严格4位十六进制) UNICODE_ESC | // 无效转义:排除引号和反斜杠,避免吞掉闭合引号 ~["\\] ) ; fragment UNICODE_ESC : 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT ; fragment HEX_DIGIT: [0-9a-fA-F];
关键修正点
- 移除
ESC_SEQ中的EOF分支,避免解析到字符串末尾时误判闭合引号 - 将无效转义的分支从
.改为~["\\],确保字符串的闭合引号不会被当成无效转义的一部分,让STRING规则能正常匹配结束符 - 简化并严格化
UNICODE_ESC规则,要求完整的4位十六进制字符(若需支持不完整转义,可改回原规则) - 直接使用双引号
"替代实体",让规则更易读
内容的提问来源于stack exchange,提问作者Oguzhan Kose
相关产品推荐
相关产品推荐

