Token の種類を判定する (実数リテラル)

Token の種類を判定する (実数リテラル)

これまで、「+」「-」を演算子として扱ってきたが、
実数リテラルをあらわす、例えば 「1E-6」という表記の「-」は、演算子ではない。
そこで、「+」「-」が出現した場合、前の文字が「E」か「e」のときは、
この「+」「-」を、数値の一部とみなす。

ただし、前の文字が「E」か「e」でも、例えば「0xE-1」の場合、
これは、「0xE」という数字、「-」という演算子、「1」という数字として
扱わなければいけない。


//読み込んだ文字の種類を取得・状態を更新
private Token getCurrToken(char cPrev, char cCurr, char cNext)
{
Token currToken = new Token(cCurr.ToString(), "その他");

do
{
if ((_state == "その他") || (_state == "区切り記号") || (_state == "不明"))
{
if (cCurr == '/')
{
if (cNext == '/')
_state = "単一行コメント";
else if (cNext == '*')
_state = "複数行コメント";
else
_state = "区切り記号";
}
else if (cCurr == '\"')
_state = "文字列";

else if (cCurr == '\'')
_state = "文字";

else if (cCurr == '#')
_state = "ディレクティブ";

else if (Char.IsLetter(cCurr) || (cCurr == '_'))
_state = "識別子";

else if (Char.IsDigit(cCurr))
_state = "数字";

else if (Char.IsPunctuation(cCurr) || Char.IsSymbol(cCurr))
_state = "区切り記号";

else
_state = "その他";

if (_state == "区切り記号")
{
if (_operators.IndexOf(cCurr) >= 0)
currToken.tokenKind = "演算子";
else
currToken.tokenKind = "区切り記号";
}
else if ((_state == "単一行コメント") || (_state == "複数行コメント"))
currToken.tokenKind = "コメント";

else
currToken.tokenKind = _state;
}

else if (_state == "単一行コメント")
{
currToken.tokenKind = "コメント";

if (cCurr == '\n')
{
currToken.tokenKind = "その他";
_state = "その他";
}
}

else if (_state == "複数行コメント")
{
currToken.tokenKind = "コメント";

if ((cCurr == '/') && (cPrev == '*'))
_state = "その他";
}

else if (_state == "文字列")
{
currToken.tokenKind = "文字列";

if ((cCurr == '\"') && (cPrev != '\\'))
_state = "その他";
}

else if (_state == "文字")
{
currToken.tokenKind = "文字";

if ((cCurr == '\'') && (cPrev != '\\'))
_state = "その他";
}

else if (_state == "識別子")
{
currToken.tokenKind = "識別子";

if (!Char.IsLetter(cCurr) && !Char.IsDigit(cCurr) && (cCurr != '_'))
{
_state = "不明";

//文字種が変わって、前のトークンが、"." でなければ、識別子が 予約語ではないか 確認する
if ((prevToken != null) && (prevToken.tokenString != "."))
{
if (_keyWords.Contains(mikakuteiToken.tokenString))
{
mikakuteiToken.tokenKind = "予約語";
}
}
}
}

else if (_state == "数字")
{
currToken.tokenKind = "数字";

if (!Char.IsLetter(cCurr) && !Char.IsDigit(cCurr) && (cCurr != '.'))
{
if ((cCurr == '+') || (cCurr == '-'))
{
//1つ前の文字が "e" か "E" か
if ((cPrev == 'e') || (cPrev == 'E'))
{
//16進表記か?
if ((mikakuteiToken.tokenString.Length > 1) && (mikakuteiToken.tokenString[0] == '0') && ((mikakuteiToken.tokenString[1] == 'x') || (mikakuteiToken.tokenString[1] == 'X')))
_state = "不明";
}
else
_state = "不明";
}
else
_state = "不明";
}
}

else if (_state == "ディレクティブ")
{
currToken.tokenKind = "ディレクティブ";

if (cCurr == '\n')
{
_state = "その他";
currToken.tokenKind = "その他";
}
else if (!Char.IsLetter(cCurr))
_state = "不明";
}

} while(_state == "不明");

return currToken;
}