java antlr4 lexer file
CHAR_LITERAL: ''' (~['\rn] | EscapeSequence) ''';
fragment EscapeSequence
: '\' 'u005c'? [btnfr"'\]
| '\' 'u005c'? ([0-3]? [0-7])? [0-7]
| '\' 'u'+ HexDigit HexDigit HexDigit HexDigit
;
为什么' r ', ' n ', ''', '' 排除在第一部分,' b ', ' t ', ' f ', '"'不排除在第一部分吗?
如果我把规则改成这个,它是否等于之前的规则
CHAR_LITERAL: ''' (~['\rnbft"] | EscapeSequence) ''';
或者改成这个
CHAR_LITERAL: ''' (~['\] | EscapeSequence) ''';
它并没有试图排除如下内容:
char x = `r`;
它试图排除:
char x = '
';
最后一个是非法java。'
(打开字符字面值)可以后跟EscapeSequence或字符,但例外情况下不能后跟换行符。(例如,在编辑器中按enter键,而不是n
,它不是换行符,它是一个转义序列,表示新行)。
换句话说,在单引号之后,任何字符都可以,除了需要排除的反斜杠,因为EscapeSequence
处理此问题,并且除了文字unicode值0D
/0A
(CR和LF,在antlrspeak中,r
和n
)。
这可能有点令人困惑-只要确保你非常非常仔细地计算反斜杠:
['\rn]
不包括4个unicode值,只有4个:
- 单引号。
char x = '';
是不合法的java. - 一个反斜杠。因为ANTLR语法需要跳转到
EscapeSequence
部分来解析它。char x = '';
不合法 - 一个换行符,一个(CR或LF)都可以——因为你不能在字符字面值的中间开始一个新行。
相反,转义序列不查找n
,它们查找反斜杠符号,然后查找实际的字母'n'。