我正在编写编译器的扫描程序,我遇到了输入“{\ 0}”的麻烦。 我的扫描仪应该做的是:跳过空白,识别'{',识别无效的字符,识别'}',跳过空白,检测eof。相反,它只会跳过\ 0。
我的扫描仪以这种方式完成,它将跳过任何“无用”字符(值小于或等于'')。出于这个原因,将跳过\ 0 char,而不是作为无效字符常量处理(我还没有实现此错误情况,但无论如何我的代码没有进入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 <= ' ')
替换为while(ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'|| ch == '\b' || ch == '\f' || ch == '\"' || ch == '\'' || ch == '\\')
来解决我的问题,以便检测所有转义序列并使用默认条件处理其余转义序列。然而,我的课程幻灯片说\ r,\ n,\ t应该被视为字符常量(在我看来,我会把它带到一个摊位,除非我能找到一种方法将这些序列视为'\'后跟一个炭)。
答案 0 :(得分:0)
其实我觉得我明白了。这不是关于阅读'\'而是仅仅跳过正确的角色。这些字符是转义序列,其值低于''(十进制的ASCII值:32)。因此,要跳过的字符是'\b'
(val:8),'\t'
(val:9),'\n'
(val:10),'\f'
(val:12) ,'\r'
(val:13),而所有其他人将由我的开关的默认情况处理。因此,我改变了我的观点:
while (ch == ' ' || ch == '\b' || ch == '\t' || ch == '\n' || ch == '\f' || ch == '\r')
// skip blanks and all esc. seq. with value < ' ' (others, like '\'' might need to be treated)
nextCh();
实际上案件'\''在这里没有任何关系(与我给出的输入不符),所以这可能是我投票的原因。只有当我试图识别上面提到的转义序列时,它才会发挥作用,如果它们明确地出现在输入中(例如,输入" '\\n' "
)。