Token ごとに処理する
Token ごとに処理する
これまで、ソースを1文字ずつ返す関数を利用して来たが、
文字列を1区切りごとに、文字列の種類とともに返してくれる関数 getToken があれば便利である。
たとえば、「private string s = "a"; //文字列」という文字列を読み込んだ場合、
1 | private | 予約語 |
---|---|---|
2 | その他 | |
3 | string | 予約語 |
4 | その他 | |
5 | s | 識別子 |
6 | その他 | |
7 | = | 演算子 |
8 | その他 | |
9 | "a" | 文字列 |
10 | ; | 区切り記号 |
11 | その他 | |
12 | //文字列 | コメント |
13 | \n | その他 |
呼び出し側では、文字列の種類に応じた色指定タグで挟んで出力する。
//*********************************************************************
// HTML に書式化して出力
//*********************************************************************
public void tohtml(Reader reader, Writer writer)
{
//ファイルの終わりまで、1区切りずつ読んで
Token token;
while((token = getToken(reader)) != null)
{
//文字列の種類に応じた色指定タグで挟んで出力する
if (token.tokenKind == "予約語")
{
writer.putString("<FONT COLOR=\"BLUE\">");
writer.putString(token.tokenString);
writer.putString("</FONT>");
}
else if (token.tokenKind == "コメント")
{
writer.putString("<FONT COLOR=\"GREEN\">");
writer.putString(token.tokenString);
writer.putString("</FONT>");
}
else
{
writer.putString(token.tokenString);
}
}
}
//*********************************************************************
// 文字列情報クラス
//*********************************************************************
private class Token
{
internal string tokenString;
internal string tokenKind;
}
いきなり、Token ごとの処理を実現するのも骨が折れるので、
まずは、「1文字ずつ読んで1文字ずつ返す」
これまでと同じ処理のgetToken を作成する。
//*********************************************************************
// 1区切りの文字列と 文字列の種類を返す
//*********************************************************************
private int _col = 0; //現在位置を保持
private Token getToken(Reader reader)
{
//ファイルの終わりまで、1文字ずつ読んで
char c = reader.getChar();//ファイルの終わり
if (c == EOF) return null;Token token = new Token();
if (c == TAB) //TAB文字なら
{
//TAB位置まで空白で埋める
string s = "";
do
{
s += BLANK; //空白を追加
} while (!TabPos(++_col)); //TAB位置まで進んだら抜ける
token.tokenString = s; //文字列情報を設定
token.tokenKind = "その他";
return token;
}//TAB でなければ
if (c == NEWLINE) //改行コードなら
{
_col = 0; //現在位置をクリア
}
else //TABでも 改行コードでも なければ
{
_col += getLength(c); //現在位置を文字幅だけ進める
}token.tokenString = getHtmlChar(c); //"<",">","&" を変換して出力
token.tokenKind = "その他";
return token;
}