Exemple #1
0
        /// <summary>
        /// 現在の位置から数字のトークンを 1 つ取得します。
        /// </summary>
        /// <returns>取得した数字のトークン。</returns>
        /// <remarks>
        /// このメソッドは取得したトークンの文字数だけ位置を進めます。
        /// </remarks>
        private NakoToken GetNumberToken()
        {
            var    token = new NakoToken(NakoTokenType.INT, lineNo, indentLevel);
            string str   = "";

            for (; !IsEOF; position++)
            {
                char ch = CurrentChar;
                if (!NakoUtility.IsNumber(ch))
                {
                    break;
                }
                str += ch;
            }
            if (CurrentChar == '.' && NakoUtility.IsNumber(NextChar))
            {
                str       += CurrentChar;
                token.Type = NakoTokenType.NUMBER;
                position++;
                for (; !IsEOF; position++)
                {
                    char ch = CurrentChar;
                    if (!NakoUtility.IsNumber(ch))
                    {
                        break;
                    }
                    str += ch;
                }
            }
            token.Value = str;
            CheckJosi(token);
            return(token);
        }
Exemple #2
0
 /// <summary>
 /// 送り仮名を削除します。
 /// </summary>
 /// <param name="name">名前。</param>
 /// <param name="isTrimAllHiragana">ひらがなを全て消すかどうか。消さない場合は末尾のひらがなを消す</param>
 /// <returns>送り仮名を削除した名前。</returns>
 public static string TrimOkurigana(string name, bool isTrimAllHiragana)
 {
     if (name == "")
     {
         return("");
     }
     if (isTrimAllHiragana == true)
     {
         return(TrimOkurigana(name));
     }
     else
     {
         // 1文字目がひらがななら省略を諦める
         if (NakoUtility.IsHiragana(name [0]))
         {
             return(name);
         }
         string result = "";
         // 送りがなを省略する
         bool trimFlag = false;
         foreach (char c in name)
         {
             if (!NakoUtility.IsHiragana(c))
             {
                 result  += c;
                 trimFlag = false;
             }
             else if (trimFlag == false)
             {
                 result += c;
             }
         }
         return(result);
     }
 }
Exemple #3
0
        /// <summary>
        /// 現在の位置から記号以外のトークンを 1 つ取得します。
        /// </summary>
        /// <returns>取得した記号以外のトークン。未定義の文字列が検出された場合は不明なトークン。</returns>
        /// <remarks>
        /// このメソッドは取得したトークンの文字数だけ位置を進めます。
        /// </remarks>
        private NakoToken GetNotFlagToken()
        {
            char c = CurrentChar;

            // 数字の場合
            if (NakoUtility.IsNumber(c))
            {
                return(GetNumberToken());
            }
            // 単語の場合
            if (c > 0xFF || NakoUtility.IsAlpha(c) || c == '_')
            {
                return(GetWordToken());
            }
            return(new NakoToken(NakoTokenType.UNKNOWN, lineNo, indentLevel));
        }
Exemple #4
0
 /// <summary>
 /// 送り仮名を削除します。
 /// </summary>
 /// <param name="name">名前。</param>
 /// <returns>送り仮名を削除した名前。</returns>
 public static string TrimOkurigana(string name)
 {
     if (name == "") return "";
     // 1文字目がひらがななら省略を諦める
     if (NakoUtility.IsHiragana(name[0]))
     {
         return name;
     }
     string result = "";
     // 送りがなを省略する
     foreach (char c in name)
     {
         if (!NakoUtility.IsHiragana(c))
         {
             result += c;
         }
     }
     return result;
 }
Exemple #5
0
        /// <summary>
        /// 現在の位置から単語のトークンを 1 つ取得します。
        /// </summary>
        /// <returns>取得した単語のトークン。</returns>
        /// <remarks>
        /// このメソッドは取得したトークンの文字数だけ位置を進めます。
        /// </remarks>
        private NakoToken GetWordToken()
        {
            var token   = new NakoToken(NakoTokenType.WORD, lineNo, indentLevel);
            var builder = new StringBuilder();

            while (!IsEOF)
            {
                char c = CurrentChar;
                if (NakoUtility.IsAlpha(c) || NakoUtility.IsNumber(c) || c == '_' || c == '!' || c == '?')
                {
                    builder.Append(c);
                    position++;
                    continue;
                }
                // 助詞なら区切る
                if (NakoUtility.IsHiragana(c))
                {
                    if (CheckJosi(token))
                    {
                        break;
                    }
                }
                // 全角文字なら読む
                if (c >= 0xFF)
                {
                    builder.Append(c);
                    position++;
                    // 特別な予約語なら区切る
                    if (builder.ToString() == "もし" || builder.ToString() == "ならば")
                    {
                        break;
                    }
                    continue;
                }
                break;
            }
            token.Value = builder.ToString();
            return(token);
        }
Exemple #6
0
 /// <summary>
 /// 現在の位置から助詞が存在するかどうかを調査します。もし助詞が存在する場合は、指定したトークンに助詞を設定します。
 /// </summary>
 /// <param name="token">助詞を設定するトークン。</param>
 /// <returns>助詞が存在する場合は true。それ以外の場合は false。</returns>
 /// <remarks>
 /// このメソッドは、助詞が存在する場合、助詞の文字数だけ位置を進めます。
 /// </remarks>
 private bool CheckJosi(NakoToken token)
 {
     if (IsEOF)
     {
         return(false);
     }
     // 助詞はひらがななので
     if (!NakoUtility.IsHiragana(CurrentChar))
     {
         return(false);
     }
     // 助詞を 1 つずつ調べる
     foreach (string josi in NakoJosi.Instance)
     {
         if (this.Equals(josi))
         {
             token.Josi = josi;
             position  += josi.Length;
             return(true);
         }
     }
     return(false);
 }
Exemple #7
0
        /// <summary>
        /// 展開あり文字列トークンを再帰的に展開します。
        /// </summary>
        /// <param name="token">展開あり文字列トークン。</param>
        /// <returns>再帰的に展開したトークン一覧。</returns>
        private static NakoTokenList StringTokenExtract(NakoToken token)
        {
            var    tokens  = new NakoTokenList();
            string tmp     = "";
            string str     = token.Value;
            int    i       = 0;
            bool   isFirst = true;

            while (i < str.Length)
            {
                char ch = str[i];
                if (ch == '{' || ch == '{')
                {
                    if (isFirst)
                    {
                        isFirst = false;
                    }
                    else
                    {
                        // "&" トークンを追加
                        tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
                    }
                    i++;
                    // 展開する文字列 ("{" と "}" との間) を取得する
                    string exString = "";
                    {
                        char end = (ch == '{') ? '}' : '}';
                        for (; i < str.Length; i++)
                        {
                            if (str[i] == end)
                            {
                                i++;
                                break;
                            }
                            exString += str[i];
                        }
                    }
                    // 文字列展開だけの特殊メソッド ('\' メソッド)
                    if (exString.Length > 0 && exString[0] == '\\')
                    {
                        if (exString == "\\t")
                        {
                            // \t の場合
                            tmp     += '\t';
                            exString = "";
                        }
                        else if (exString == "\\r")
                        {
                            // \r の場合
                            tmp     += '\r';
                            exString = "";
                        }
                        else if (exString == "\\n")
                        {
                            // \n の場合
                            tmp     += '\n';
                            exString = "";
                        }
                        else if (NakoUtility.IsNumber(exString[1]))
                        {
                            // \0 のような場合
                            exString = exString.Substring(1);
                            tmp     += (char)int.Parse(exString);
                            exString = "";
                        }
                        else if (exString[1] == '$')
                        {
                            // \$00 のような場合
                            exString = "0x" + exString.Substring(2);
                            tmp     += (char)int.Parse(exString);
                            exString = "";
                        }
                        else
                        {
                            new NakoTokenizerException("展開あり文字列内の利用できない`\\'メソッド:" + exString, token);
                        }
                    }
                    // 文字列展開だけの特殊メソッド ('~' メソッド)
                    else if (exString.Length == 1 && exString[0] == '~')
                    {
                        tmp     += "\r\n";
                        exString = "";
                    }
                    // 文字列トークンを追加
                    tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, tmp));
                    tmp = "";
                    if (exString != "")
                    {
                        // "&" トークンを追加
                        tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
                        // "(" トークンを追加
                        tokens.Add(new NakoToken(NakoTokenType.PARENTHESES_L, token.LineNo, token.IndentLevel));
                        // 再帰的にトークンを解析
                        var innerTokens = new NakoTokenizer().TokenizeSplitOnly(exString, token.LineNo, token.IndentLevel); // とりあえず区切るだけ
                        foreach (var innerToken in innerTokens)
                        {
                            tokens.Add(innerToken);
                        }
                        // ")" トークンを追加
                        tokens.Add(new NakoToken(NakoTokenType.PARENTHESES_R, token.LineNo, token.IndentLevel));
                    }
                    continue;
                }
                tmp += ch;
                i++;
            }
            if (tmp != "")
            {
                if (!isFirst)
                {
                    // "&" トークンを追加
                    tokens.Add(new NakoToken(NakoTokenType.AND, token.LineNo, token.IndentLevel));
                }
                // 文字列トークンを追加
                tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, tmp));
            }
            else
            {
                // 必要なら空文字列トークンを追加
                if (isFirst)
                {
                    tokens.Add(new NakoToken(NakoTokenType.STRING, token.LineNo, token.IndentLevel, ""));
                }
            }
            // 助詞をコピー
            tokens[tokens.Count - 1].Josi = token.Josi;
            return(tokens);
        }