首页 > 解决方案 > 在 ANTLR4 中正确捕获未闭合的字符串

问题描述

我必须在 ANTLR4 中定义字符串文字并捕获 UNCLOSE_STRING 异常。

字符串被一对 "" 包围,并且可能支持转义:

\b \f \r \n \t \’ \\

"出现在字符串中 的唯一方法是附加一个'('")。

我尝试了各种方法来定义字符串文字,但它们都被 UNCLOSE_STRING 捕获:

program: global_variable_part function_declaration_part EOF;
<!-- Shenanigans of statements ...-->
fragment Character: ~( [\b\f\r\n\t"\\] | '\'') | Escape | '\'"';
fragment Escape: '\\' ( 'b' | 'f' | 'r' | 'n' | 't' | '\'' | '\\');
fragment IllegalEscape: '\\' ~( 'b' | 'f' | 'r' | 'n' | 't' | '\'' | '\\') ;

STR_LIT: '"' Character* '"' {
    content = str(self.text)
    self.text = content[1:-1]
};

UNCLOSE_STRING: '"' Character* ([\b\f\r\n\t\\] | EOF) {
    esc = ['\b', '\t', '\n', '\f', '\r', '\\']
    content = str(self.text)
    raise UncloseString(content)
};

例如 "ab'"c\\n def" ,将匹配但仅Unclosed String: ab'"c\n def" 生成。

标签: string-literalsantrl4

解决方案


这与 Java 中的字符串规范非常接近。不要害怕从其他语法中“借用”。我对(我认为)符合您需求的Java Lexer 规则进行了轻微修改:

StringLiteral
    :   '"' StringCharacters? '"'
    ;
fragment
StringCharacters
    :   StringCharacter+
    ;
fragment
StringCharacter
    :   ~["\\\r\n]
    |   EscapeSequence
    ;

fragment
EscapeSequence
    :   '\\' [btnfr'\\]
    :   "\'""  // <-- the '" escape match
    ;

如果您知道另一种更接近匹配的语言,您可以在此处查看如何处理它以查找它的语法(ANTLR4 Grammars


推荐阅读