如何理解java antlr4 lexer文件中的CHAR_LITERAL规则

a64a0gku  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(139)

java antlr4 lexer file

CHAR_LITERAL:       '\'' (~['\\\r\n] | EscapeSequence) '\'';

fragment EscapeSequence
    : '\\' 'u005c'? [btnfr"'\\]
    | '\\' 'u005c'? ([0-3]? [0-7])? [0-7]
    | '\\' 'u'+ HexDigit HexDigit HexDigit HexDigit
    ;

为什么'\r'、'\n'、'''、''在第一部分中被排除,而'\b'、'\t'、'\f'、'"'在第一部分中未被排除?
如果我把规则改成这个,是不是和以前的规则是等价的

CHAR_LITERAL:       '\'' (~['\\\r\n\b\f\t\"] | EscapeSequence) '\'';

或者改成这个

CHAR_LITERAL:       '\'' (~['\\] | EscapeSequence) '\'';
vkc1a9a2

vkc1a9a21#

它并不试图排除这样的东西:

char x = `\r`;

它试图排除:

char x = '
';

最后一个是非法的java.一个'(打开一个char literal)可以跟一个EscapeSequence,或者一个字符,但例外的是,不是一个换行符.(就像在你的编辑器中按回车键,而不是\n,它不是一个换行符,它是一个代表一个新行的转义序列).
换句话说,在单引号之后,任何字符都是可以的,除了需要排除的反斜杠,因为EscapeSequence处理这个问题,以及除了文字unicode值0D/0A(CR和LF,在antlrspeak中,\r\n)。
这可能会让人有点困惑-只要确保你非常非常仔细地计算反斜杠:

['\\\r\n]

也就是说,不包括4个unicode值,只有4个:

  • char x = '';不是法律的的java。
  • 因为ANTLR语法需要跳转到EscapeSequence部分来解析. char x = '\';是不法律的的。
  • 一个新行,一个(CR或LF)-因为你实际上不能在你的字符中间开始一个新行。

相比之下,转义序列并不寻找\n,而是寻找一个反斜杠符号,然后是实际的字母'n'。

相关问题