我正在编写编译器的扫描仪,并且在输入“ {\0} ”时遇到了问题。我的扫描仪应该做的是:跳过空白,识别'{',识别无效字符,识别'}',跳过空白,检测eof。相反,它只会跳过 \0 。
我的扫描仪是这样完成的,它会跳过任何“无用”字符(值小于或等于'')。出于这个原因,\0 字符将被跳过,而不是作为无效字符常量处理(我还没有实现这个错误情况,但无论如何我的代码在这种情况下没有进入readCharConst(Token t)
函数......) . 我想知道的是我应该怎么做才能让它处理 '\0' 作为 '\' 后跟 '0' 而不是单个字符。
以下是我的一些功能:
public Token next() {
while (ch <= ' ') {
nextCh(); // skip blanks, tabs, eols
}
Token t = new Token(Kind.none, line, col);
switch (ch) {
// cases for identifiers, numbers, meta-chars, ...
case '\'':
readCharConst(t);
break;
default:
error(t, Message.INVALID_CHAR, ch);
nextCh();
t.kind = Kind.none;
}
return t;
}
和:
public void nextCh() {
try {
ch = (char) in.read();
if (ch == LF) { // detects new_line
col = 0;
line++;
} else if (ch != EOF) { // do not increment col for EOF
col++;
}
} catch (IOException e) {
ch = EOF;
e.printStackTrace();
}
}
和:
private void readCharConst(Token t) {
nextCh();
if (ch == '\'') {
error(t, Message.EMPTY_CHARCONST);
} else {
t.val = (int) ch;
t.kind = Kind.charConst;
nextCh();
if (ch != '\'') {
error(t, Message.MISSING_QUOTE);
}
nextCh();
}
}
while (ch <= ' ')
注意:我通过将a替换为解决了我的问题while(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'|| ch == '\b' || ch == '\f' || ch == '\"' || ch == '\'' || ch == '\\')
,以便检测所有转义序列并使用默认条件处理其余部分。尽管如此,我的课程幻灯片说 \r, \n, \t 应该被视为 char 常量(在我看来,这让我陷入了困境,除非我能找到一种方法将序列视为 '\' 后跟字符)。