トークン読み込み用クラス

これまでC# で作成してきた「SourceToHTML」を、VJ# に焼きなおしてみます。

TokenReader.jsl


package SourceToHtml;

//*******************************************************************************************************
// トークンごとに その種類と、内容を返す
//*******************************************************************************************************
public class TokenReader
{
//入力用クラス
private Reader _reader;

//文脈情報 クラス (前後のトークン、前後の文字を保持しておく)
protected Context _context = null;
//---------------------------------------------------------------------------------------------------
// ファクトリー
//---------------------------------------------------------------------------------------------------
public static TokenReader Create(Reader reader, String langType)
{
if (langType.Equals("cs7")) return new TokenReaderCSharp(reader, langType); // VC#.NET
else if (langType.Equals("vc6")) return new TokenReaderCase(reader, langType); // VC++
else if (langType.Equals("vc7")) return new TokenReaderCase(reader, langType); // VC++.NET
else if (langType.Equals("java")) return new TokenReaderCase(reader, langType); // VJ++, VJ#.NET, Java
else if (langType.Equals("js")) return new TokenReaderCase(reader, langType); // JavaScript
else if (langType.Equals("bcb")) return new TokenReaderCase(reader, langType); // C++Builder
else if (langType.Equals("vb6")) return new TokenReaderVB(reader, langType); // VB
else if (langType.Equals("vb7")) return new TokenReaderVB(reader, langType); // VB.NET
else if (langType.Equals("del")) return new TokenReaderDelphi(reader, langType); // Delphi
else if (langType.Equals("psq")) return new TokenReaderPlsql(reader, langType); // PL/SQL
else if (langType.Equals("tsq")) return new TokenReaderTsql(reader, langType); // T-SQL
else return new TokenReader(reader, langType); // other


}
//---------------------------------------------------------------------------------------------------
// 初期化
//---------------------------------------------------------------------------------------------------
protected TokenReader(Reader reader, String langType)
{
//入力用クラス
_reader = reader;

//文脈情報 クラス (前後のトークン、前後の文字を保持しておく)
_context = new Context();

//文字を取得 (1つ先読みする)
_context.nextChar = _reader.getChar();
}
//---------------------------------------------------------------------------------------------------
// 終了
//---------------------------------------------------------------------------------------------------
protected void Finalize()
{
_reader = null;
_context = null;
}
//---------------------------------------------------------------------------------------------------
// トークンごとに その種類と、内容を返す
//---------------------------------------------------------------------------------------------------
private static final char EOF = '\0';
private static final char NEWLINE = '\n';
private static final char TAB = '\t';
private static final char BLANK = ' ';

private int _col = 0; //現在位置を保持

public Token getToken()
{
//ファイルの終わりまで、1文字ずつ読む
do
{
//文字を取得 (1つ先読みする)
_context.prevChar = _context.currChar; //現在の文字を、前の文字に複写
_context.currChar = _context.nextChar; //次の文字を、現在の文字に複写
_context.nextChar = _reader.getChar(); //次の文字を先読み

if (_context.currChar == TAB) //TAB文字なら
{
_context.currChar = BLANK; //空白に置換
do
{
addToken(); //TAB位置まで空白で埋める
}
while (!TabPos(++_col)); //TAB位置まで進んだら抜ける
}
else
{
if (_context.currChar == BLANK) //空白なら
_col++; //現在位置を1つ進める

else if (_context.currChar == NEWLINE) //改行コードなら
_col = 0; //現在位置をクリア

else if (_context.currChar != EOF) //TABでも 改行コードでも 空白でも なければ
_col += getLength(_context.currChar); //現在位置を文字幅だけ進める

addToken(); //読み込み文字列に追加
}
//文字種が変わったら、変わる前のトークンを返す
Token token;
if ((token = getPrevToken()) != null) return token;
}
while(_context.currChar != EOF);

return null;
}
//---------------------------------------------------------------------------------------------------
// 読み込んだ文字を トークンに追加
//---------------------------------------------------------------------------------------------------
private void addToken()
{
//未確定トークン がクリアされていれば、ファイルの終わり
if (_context.currToken == null) return;

//読み込んだ文字の種類を取得、状態を更新 (nextToken にセットする)
getNextToken();

//文字種が変わってなかったら、未確定トークンに 取得した文字を 追加
if ((_context.nextToken.tokenKind == _context.currToken.tokenKind) && (_context.currChar != EOF))
{
_context.currToken.tokenString += _context.nextToken.tokenString;
return;
}

//文字種が変わっても、取得した文字が空っぽなら 何もしない
if (_context.nextToken.tokenString.get_Length() < 1) return;

//文字種が変わったら、確定済みトークン に、未確定トークン を Copy
_context.prevToken.tokenKind = _context.currToken.tokenKind;
_context.prevToken.tokenString = _context.currToken.tokenString;
_context.prevToken.IsFixed = true;

//未確定トークン に、新しいトークン を Copy
_context.currToken.tokenKind = _context.nextToken.tokenKind;
_context.currToken.tokenString = _context.nextToken.tokenString;

//ファイルの終わりに達したら、未確定トークン をクリア
if (_context.currChar == EOF) _context.currToken = null;
}
//---------------------------------------------------------------------------------------------------
// 文字を取得・状態を更新
//---------------------------------------------------------------------------------------------------
protected void getNextToken()
{
_context.nextToken.tokenKind = "その他";
_context.nextToken.tokenString = new Character(_context.currChar).toString();
}
//---------------------------------------------------------------------------------------------------
// 文字種が変わったら、変わる前の文字列情報を返す
//---------------------------------------------------------------------------------------------------
private Token getPrevToken()
{
//確定済みでなければ 何もしない
if (!_context.prevToken.IsFixed) return null;

//1つ前のトークンを未確定状態にして
_context.prevToken.IsFixed = false;

//1つ前のトークンを返す
return _context.prevToken;
}
//---------------------------------------------------------------------------------------------------
// 現在位置が、TAB 位置かどうかを返す
//---------------------------------------------------------------------------------------------------
private boolean TabPos(int col)
{
return ((col % 4) == 0);
}
//---------------------------------------------------------------------------------------------------
// 取得した文字のByte数を返す
//---------------------------------------------------------------------------------------------------
private int getLength(char c)
{
System.Text.Encoding sjis = System.Text.Encoding.GetEncoding("shift-jis");
return sjis.GetByteCount(new Character(c).toString());
}
}