2

我正在编写编译器的扫描仪,并且在输入“ {\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 常量(在我看来,这让我陷入了困境,除非我能找到一种方法将序列视为 '\' 后跟字符)。

4

1 回答 1

0

其实我想我明白了。这不是关于阅读“\”,而是只是跳过正确的字符。这些字符是值低于''的转义序列(十进制ASCII val:32)。因此,要跳过的字符是'\b'(val:8), '\t'(val:9), '\n'(val:10), '\f'(val:12), '\r'(val:13),而所有其他字符将由 my 的默认情况处理转变。因此,我将时间更改为:

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();

事实上,案例 '\'' 在这里没有任何关系(与我提供的输入不匹配),所以这可能就是我被否决的原因。只有当我试图识别上面提到的转义序列时,这种情况才会起作用,如果它们明确出现在输入中(例如, input " '\\n' ")。

于 2012-10-16T09:50:16.490 回答