Пример #1
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);
        }
Пример #2
0
 /// <summary>
 /// NakoTokenizer クラスの新しいインスタンスを初期化します。
 /// </summary>
 public NakoTokenizer()
 {
     tokens      = new NakoTokenList();
     indentStack = new Stack <int>();
 }