だから、宿題用のコンパイラスキャナーを書く必要があり、正規表現を使うのは「エレガント」だと思いました。実は、以前はめったに使わなかったのですが、昔のことです。だから私はそれらについてのほとんどのものを忘れて、周りを見回す必要がありました。私はそれらを識別子にうまく使用しました(または少なくとも私はそう思うので、さらにいくつかのテストを行う必要がありますが、今のところすべて問題ないように見えます)が、数字の認識に問題があります。
この関数nextCh()
は、入力の次の文字(先読み文字)を読み取ります。ここでやりたいのは、この文字が正規表現と一致するかどうかを確認することです[0-9]*
。現在のトークンのフィールドに一致するすべての文字を追加してstr
から、このフィールドのint値を読み取ります。「123」などの単一の数値入力を認識しますが、私が抱えている問題は、入力「123 456」の場合、最後のstrが「123456」になり、フィールド「123」と「」を持つ2つの別々のトークンを取得する必要があることです。 456"。「」が一致するのはなぜですか?
private void readNumber(Token t) {
t.str = "" + ch; // force conversion char --> String
final Pattern pattern = Pattern.compile("[0-9]*");
nextCh(); // get next char and check if it is a digit
Matcher match = pattern.matcher("" + ch);
while (match.find() && ch != EOF) {
t.str += ch;
nextCh();
match = pattern.matcher("" + ch);
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
ありがとうございました!
PS:以下のコードを使用して問題を解決しました。それでも、正規表現のどこに欠陥があるのかを理解したいと思います。
t.str = "" + ch;
nextCh(); // get next char and check if it is a number
while (ch>='0' && ch<='9') {
t.str += ch;
nextCh();
}
t.kind = Kind.number;
try {
int value = Integer.parseInt(t.str);
t.val = value;
} catch(NumberFormatException e) {
error(t, Message.BIG_NUM, t.str);
}
編集:私の正規表現は識別子の認識にも機能しないことが判明したため(ここでも空白が含まれています)、「ソリューション」と同様のシステムに切り替える必要がありました(多くの条件があります)。正規表現をもう一度勉強する必要があると思います:O