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) '\'';
1条答案
按热度按时间vkc1a9a21#
它并不试图排除这样的东西:
它试图排除:
最后一个是非法的java.一个
'
(打开一个char literal)可以跟一个EscapeSequence,或者一个字符,但例外的是,不是一个换行符.(就像在你的编辑器中按回车键,而不是\n
,它不是一个换行符,它是一个代表一个新行的转义序列).换句话说,在单引号之后,任何字符都是可以的,除了需要排除的反斜杠,因为
EscapeSequence
处理这个问题,以及除了文字unicode值0D
/0A
(CR和LF,在antlrspeak中,\r
和\n
)。这可能会让人有点困惑-只要确保你非常非常仔细地计算反斜杠:
也就是说,不包括4个unicode值,只有4个:
char x = '';
不是法律的的java。EscapeSequence
部分来解析.char x = '\';
是不法律的的。相比之下,转义序列并不寻找
\n
,而是寻找一个反斜杠符号,然后是实际的字母'n'。