トークン読み込み用クラス (各言語共通)

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

TokenReaderCommon.jsl


package SourceToHtml;

//*******************************************************************************************************
// トークンごとに 文字列と その種類を返す ( 共通 )
//*******************************************************************************************************
public abstract class TokenReaderCommon extends TokenReader
{
//予約語 コレクション
protected System.Collections.Specialized.StringCollection _keyWords;

//演算子 コレクション
protected String _operators;
//---------------------------------------------------------------------------------------------------
// 初期化
//---------------------------------------------------------------------------------------------------
protected TokenReaderCommon(Reader reader, String langType)
{
super(reader, langType);

//予約語 コレクションを設定
initKeyWord(langType);

//演算子 コレクションを設定
initOperator(langType);
}
//---------------------------------------------------------------------------------------------------
// 終了
//---------------------------------------------------------------------------------------------------
protected void Finalize()
{
_keyWords = null;
}
//---------------------------------------------------------------------------------------------------
// 予約語 コレクションを設定
//---------------------------------------------------------------------------------------------------
private void initKeyWord(String langType)
{
//予約語 コレクションを設定 (".\cs7\key.txt")
_keyWords = new System.Collections.Specialized.StringCollection();

//予約語ファイルがなければ、予約語コレクションは空っぽ
if (System.IO.File.Exists(System.Windows.Forms.Application.get_StartupPath() + "\\" + langType + "\\key.txt"))
{
System.IO.StreamReader keyReader = new System.IO.StreamReader(System.Windows.Forms.Application.get_StartupPath() + "\\" + langType + "\\key.txt", System.Text.Encoding.GetEncoding("Shift_JIS"));
String s;
while ((s = keyReader.ReadLine()) != null)
{
_keyWords.Add(s);
}
keyReader.Close();
keyReader = null;
}
}
//---------------------------------------------------------------------------------------------------
// 演算子 コレクションを設定
//---------------------------------------------------------------------------------------------------
private void initOperator(String langType)
{
_operators = "";

//演算子ファイルがなければ、演算子コレクションは空っぽ
if (System.IO.File.Exists(System.Windows.Forms.Application.get_StartupPath() + "\\" + langType + "\\ope.txt"))
{
System.IO.StreamReader opeReader = new System.IO.StreamReader(System.Windows.Forms.Application.get_StartupPath() + "\\" + langType + "\\ope.txt", System.Text.Encoding.GetEncoding("Shift_JIS"));
String s;
while ((s = opeReader.ReadLine()) != null)
{
_operators += s;
}
opeReader.Close();
opeReader = null;
}
}
//---------------------------------------------------------------------------------------------------
// 状態を更新
//---------------------------------------------------------------------------------------------------
protected void getNextToken()
{
super.getNextToken();

do
{
if (_context.State.Equals("その他")) getNextStateOther();
else if (_context.State.Equals("演算子")) getNextStateOther();
else if (_context.State.Equals("区切り記号")) getNextStateOther();
else if (_context.State.Equals("不明")) getNextStateOther();
else if (_context.State.Equals("単一行コメント")) getNextStateComSin();
else if (_context.State.Equals("複数行コメント")) getNextStateComMul();
else if (_context.State.Equals("文字列")) getNextStateStr();
else if (_context.State.Equals("文字列中のエスケープシーケンス")) getNextStateStrEsc();
else if (_context.State.Equals("逐語的文字列")) getNextStateStrLit();
else if (_context.State.Equals("文字")) getNextStateCha();
else if (_context.State.Equals("文字中のエスケープシーケンス")) getNextStateChaEsc();
else if (_context.State.Equals("識別子")) getNextStateIdw();
else if (_context.State.Equals("エスケープされた識別子")) getNextStateIdwEsc();
else if (_context.State.Equals("数字")) getNextStateNum();
else if (_context.State.Equals("ディレクティブ")) getNextStateDir();
else if (_context.State.Equals("日付")) getNextStateDtm();

} while(_context.State.Equals("不明"));
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (その他・区切り記号・不明)
//---------------------------------------------------------------------------------------------------
private void getNextStateOther()
{
_context.State = "その他";
_context.nextToken.tokenKind = "その他";

// 状態を更新
if (IsIdent()) _context.State = "識別子";
else if (IsEscape()) _context.State = "エスケープされた識別子";
else if (IsNumber()) _context.State = "数字";
else if (IsDirective()) _context.State = "ディレクティブ";
else if (IsComSingle()) _context.State = "単一行コメント";
else if (IsComMulti()) _context.State = "複数行コメント";
else if (IsString()) _context.State = "文字列";
else if (IsChar()) _context.State = "文字";
else if (IsLiteral()) _context.State = "逐語的文字列";
else if (IsDate()) _context.State = "日付";
else if (IsDelim()) _context.State = "区切り記号";
else if (IsOperator()) _context.State = "演算子";
else _context.State = "その他";

// トークンの種類を取得
if (_context.State.Equals("逐語的文字列")) _context.nextToken.tokenKind = "文字列";
else if (_context.State.Equals("エスケープされた識別子")) _context.nextToken.tokenKind = "識別子";
else if (_context.State.Equals("単一行コメント")) _context.nextToken.tokenKind = "コメント";
else if (_context.State.Equals("複数行コメント")) _context.nextToken.tokenKind = "コメント";
else if (_context.State.Equals("日付")) _context.nextToken.tokenKind = "文字列";
else _context.nextToken.tokenKind = _context.State;
}
//---------------------------------------------------------------------------------------------------
// 単一行コメントか?
//---------------------------------------------------------------------------------------------------
protected boolean IsComSingle()
{
return ((_context.currChar == '/') && (_context.nextChar == '/'));
}
//---------------------------------------------------------------------------------------------------
// 複数行コメントか?
//---------------------------------------------------------------------------------------------------
protected boolean IsComMulti()
{
return ((_context.currChar == '/') && (_context.nextChar == '*'));
}
//---------------------------------------------------------------------------------------------------
// 文字列か?
//---------------------------------------------------------------------------------------------------
protected boolean IsString()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// 文字か?
//---------------------------------------------------------------------------------------------------
protected boolean IsChar()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// 逐語的文字列か?
//---------------------------------------------------------------------------------------------------
protected boolean IsLiteral()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// ディレクティブか?
//---------------------------------------------------------------------------------------------------
protected boolean IsDirective()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// 識別子か?
//---------------------------------------------------------------------------------------------------
protected boolean IsIdent()
{
return (System.Char.IsLetter(_context.currChar) || (_context.currChar == '_'));
}
//---------------------------------------------------------------------------------------------------
// エスケープされた識別子か?
//---------------------------------------------------------------------------------------------------
protected boolean IsEscape()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// 数字か?
//---------------------------------------------------------------------------------------------------
protected boolean IsNumber()
{
return (System.Char.IsDigit(_context.currChar));
}
//---------------------------------------------------------------------------------------------------
// 演算子か?
//---------------------------------------------------------------------------------------------------
protected boolean IsOperator()
{
if (System.Char.IsPunctuation(_context.currChar) || System.Char.IsSymbol(_context.currChar))
{
if (_operators.IndexOf(_context.currChar) >= 0) return true;
}
return false;
}
//---------------------------------------------------------------------------------------------------
// 区切り記号か?
//---------------------------------------------------------------------------------------------------
protected boolean IsDelim()
{
if (System.Char.IsPunctuation(_context.currChar) || System.Char.IsSymbol(_context.currChar))
{
if (_operators.IndexOf(_context.currChar) < 0) return true;
}

return false;
}
//---------------------------------------------------------------------------------------------------
// 日付か?
//---------------------------------------------------------------------------------------------------
protected boolean IsDate()
{
return false;
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (単一行コメント)
//---------------------------------------------------------------------------------------------------
protected void getNextStateComSin()
{
_context.State = "単一行コメント";
_context.nextToken.tokenKind = "コメント";

if (_context.currChar == '\n')
{
_context.State = "その他";
_context.nextToken.tokenKind = "その他";
}
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (複数行コメント)
//---------------------------------------------------------------------------------------------------
protected void getNextStateComMul()
{
_context.State = "複数行コメント";
_context.nextToken.tokenKind = "コメント";

if ((_context.prevChar == '*')
&& (_context.currChar == '/'))
_context.State = "その他";
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (文字列)
//---------------------------------------------------------------------------------------------------
protected void getNextStateStr()
{
_context.State = "文字列";
_context.nextToken.tokenKind = "文字列";

// 各派生クラスで処理する
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (文字列中のエスケープシーケンス)
//---------------------------------------------------------------------------------------------------
protected void getNextStateStrEsc()
{
_context.State = "文字列";
_context.nextToken.tokenKind = "文字列";
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (逐語的文字列)
//---------------------------------------------------------------------------------------------------
protected void getNextStateStrLit()
{
_context.State = "逐語的文字列";
_context.nextToken.tokenKind = "文字列";

// 各派生クラスで処理する
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (文字)
//---------------------------------------------------------------------------------------------------
protected void getNextStateCha()
{
_context.State = "文字";
_context.nextToken.tokenKind = "文字";

// 各派生クラスで処理する
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (文字中のエスケープシーケンス)
//---------------------------------------------------------------------------------------------------
protected void getNextStateChaEsc()
{
_context.State = "文字";
_context.nextToken.tokenKind = "文字";
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (識別子)
//---------------------------------------------------------------------------------------------------
protected void getNextStateIdw()
{
_context.State = "識別子";
_context.nextToken.tokenKind = "識別子";

if (!System.Char.IsLetter(_context.currChar) && !System.Char.IsDigit(_context.currChar) && (_context.currChar != '_'))
{
_context.State = "不明";

//文字種が変わったら、識別子が 予約語ではないか 確認する
String keyWord;
if ((keyWord = getKeyWord()).get_Length() > 0)
{
_context.currToken.tokenKind = "予約語";
_context.currToken.tokenString = keyWord;
}
}
}
//---------------------------------------------------------------------------------------------------
// 予約語ではないか?
//---------------------------------------------------------------------------------------------------
protected String getKeyWord()
{
return "";
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (エスケープされた識別子)
//---------------------------------------------------------------------------------------------------
protected void getNextStateIdwEsc()
{
_context.State = "エスケープされた識別子";
_context.nextToken.tokenKind = "識別子";

// 各派生クラスで処理する
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (数字)
//---------------------------------------------------------------------------------------------------
protected void getNextStateNum()
{
_context.State = "数字";
_context.nextToken.tokenKind = "数字";

if ((_context.currChar == '.') && (_context.nextChar == '.'))
_context.State = "不明";

else if (!System.Char.IsLetter(_context.currChar) && !System.Char.IsDigit(_context.currChar) && (_context.currChar != '.'))
{
_context.State = "不明";

// "+" か "-" で
if ((_context.currChar == '+') || (_context.currChar == '-'))
{
//1つ前の文字が "e" か "E" で
if ((_context.prevChar == 'e') || (_context.prevChar == 'E'))
{
//16進表記でなければ、数字
if (IsNotHex())
_context.State = "数字";
}
}
}
}
//---------------------------------------------------------------------------------------------------
// 16進表記か?
//---------------------------------------------------------------------------------------------------
protected boolean IsNotHex()
{
// 0x で始まっていたら、16進
if (_context.currToken.tokenString.get_Length() > 1)
if (_context.currToken.tokenString.charAt(0) == '0')
if ((_context.currToken.tokenString.charAt(1) == 'x') || (_context.currToken.tokenString.charAt(1) == 'X'))
return false;

return true;
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (ディレクティブ)
//---------------------------------------------------------------------------------------------------
protected void getNextStateDir()
{
_context.State = "ディレクティブ";
_context.nextToken.tokenKind = "ディレクティブ";

// 各派生クラスで処理する
}
//---------------------------------------------------------------------------------------------------
// 状態を更新 (日付)
//---------------------------------------------------------------------------------------------------
protected void getNextStateDtm()
{
_context.State = "日付";
_context.nextToken.tokenKind = "文字列";

// 各派生クラスで処理する (VBだけ)
}
}