コンパイラのスキャナを書いていますが、入力 " {\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 定数として扱われるべきであると述べています (私の意見では、シーケンスを '\' の後にチャー)。