예제 #1
0
 /// <summary>
 /// トークンに区切ります。
 /// </summary>
 private void SplitToToken()
 {
     // 最初にインデントを数える
     indentCount = CountIndent();
     indentLevel = 0;
     // 繰り返しトークンを取得する
     while (!IsEOF)
     {
         var token = GetToken();
         if (token == null)
         {
             lastTokenType = NakoTokenType.EOL;
             continue;
         }
         lastTokenType = token.Type;
         // 展開あり文字列をここで展開
         if (token.Type == NakoTokenType.STRING_EX)
         {
             foreach (var extractToken in StringTokenExtract(token))
             {
                 tokens.Add(extractToken);
             }
         }
         else
         {
             tokens.Add(token);
         }
     }
     // レベルが合うまで SCOPE_END を追加する
     CheckScope();
 }
예제 #2
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類、行番号、インデントレベル、値を使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 /// <param name="lineNo">行番号。</param>
 /// <param name="indentLevel">インデントレベル。</param>
 /// <param name="value">値。</param>
 public NakoToken(NakoTokenType type, int lineNo, int indentLevel, string value)
 {
     Type        = type;
     LineNo      = lineNo;
     IndentLevel = indentLevel;
     Value       = value;
     Josi        = "";
 }
예제 #3
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類、行番号、インデントレベル、値を使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 /// <param name="lineNo">行番号。</param>
 /// <param name="indentLevel">インデントレベル。</param>
 /// <param name="value">値。</param>
 public NakoToken(NakoTokenType type, int lineNo, int indentLevel, string value)
 {
     Type = type;
     LineNo = lineNo;
     IndentLevel = indentLevel;
     Value = value;
     Josi = "";
 }
예제 #4
0
        /// <summary>
        /// 現在のカーソル位置から keytype のトークンがないか調べる (EOLStop=trueのときはEOLまで)
        /// </summary>
        /// <param name="keytype"></param>
        /// <param name="EOLStop"></param>
        /// <returns></returns>
        public bool SearchToken(NakoTokenType keytype, bool EOLStop)
        {
            int       i = cur;
            NakoToken t;
            int       par_nest = 0;
            int       bla_nest = 0;

            while (i < this.Count)
            {
                t = this[i];
                // break?
                if (t.Type == keytype)
                {
                    return(true);
                }
                if (EOLStop)
                {
                    if (t.Type == NakoTokenType.EOL)
                    {
                        break;
                    }
                }
                // ---
                // nest check
                if (t.Type == NakoTokenType.BRACKETS_L)
                {
                    bla_nest++;
                }
                if (t.Type == NakoTokenType.BRACKETS_R)
                {
                    bla_nest--;
                    if (bla_nest < 0)
                    {
                        return(false);              // tokenが見つかる前に角カッコの不整合を見つけた
                    }
                }
                // ---
                if (t.Type == NakoTokenType.PARENTHESES_L)
                {
                    par_nest++;
                }
                if (t.Type == NakoTokenType.PARENTHESES_R)
                {
                    par_nest--;
                    if (par_nest < 0)
                    {
                        return(false);              // tokenが見つかる前に丸カッコの不整合を見つけた
                    }
                }
                i++;
            }
            return(false);
        }
예제 #5
0
 /// <summary>
 /// 指定したソースコードからトークンに区切るだけの解析をします。文法を一切考慮しません。
 /// </summary>
 /// <param name="source">解析するソースコード。</param>
 /// <param name="lineNo">開始する行番号。</param>
 /// <param name="indentLevel">開始するインデントレベル。</param>
 /// <returns>指定したソースコードから解析した、トークン一覧。</returns>
 public NakoTokenList TokenizeSplitOnly(string source, int lineNo, int indentLevel)
 {
     Initialization();
     this.source      = source;
     this.indentLevel = indentLevel;
     this.lineNo      = lineNo;
     // 繰り返しトークンを取得する
     while (!IsEOF)
     {
         var token = GetToken();
         if (token == null)
         {
             continue;
         }
         lastTokenType = token.Type;
         tokens.Add(token);
     }
     return(tokens);
 }
예제 #6
0
 /// <summary>
 /// 現在のトークンが指定したタイプと合致しているか
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 protected bool Accept(NakoTokenType type)
 {
     return (tok.CurrentTokenType == type);
 }
예제 #7
0
 /// <summary>
 /// 現在のトークンが指定したタイプと合致しているか
 /// </summary>
 /// <param name="type"></param>
 /// <returns></returns>
 protected bool Accept(NakoTokenType type)
 {
     return(tok.CurrentTokenType == type);
 }
예제 #8
0
 /// <summary>
 /// 現在のトークンが、指定したトークンタイプtと合致するか
 /// </summary>
 /// <param name="t"></param>
 /// <returns></returns>
 public bool Accept(NakoTokenType t)
 {
     return(t == CurrentTokenType);
 }
예제 #9
0
 /// <summary>
 /// トークンを探す
 /// </summary>
 /// <param name="keytype"></param>
 /// <returns></returns>
 public bool SearchToken(NakoTokenType keytype)
 {
     return(SearchToken(keytype, false));
 }
예제 #10
0
        /// <summary>
        /// 現在の位置からトークンを 1 つ取得します。
        /// </summary>
        /// <returns>取得したトークン。位置がソースコードの終端に達している場合は null。</returns>
        /// <remarks>
        /// このメソッドは取得したトークンの文字数だけ位置を進めます。
        /// </remarks>
        private NakoToken GetToken()
        {
            if (IsEOF)
            {
                return(null);
            }
            var  token = new NakoToken(NakoTokenType.UNKNOWN, lineNo, indentLevel);
            char nc;

            switch (CurrentChar)
            {
            // BOM かどうか確認
            case (char)0xFEFF:
                position++;
                return(null);

            // 行末かどうか確認
            case '\r':
                position++;
                return(null);

            case '\n':
                token.Type    = NakoTokenType.EOL;
                lastTokenType = NakoTokenType.EOL;
                position++;
                lineNo++;
                tokens.Add(token);
                CheckScope();
                return(null);

            // インデントかどうか確認
            case ' ':
            case '\t':
                position++;     // skip
                return(null);

            // 句読点かどうか確認
            case ';':
                token.Type    = NakoTokenType.EOL;  // 明確な区切り
                lastTokenType = NakoTokenType.EOL;
                position++;
                return(token);

            case ',':
                position++;
                return(null);

            // 記号かどうか確認
            case '=':
                nc = NextChar;
                if (nc == '=')
                {
                    position  += 2;
                    token.Type = NakoTokenType.EQ_EQ;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.EQ;
                }
                return(token);

            case '&':
                nc = NextChar;
                if (nc == '&')
                {
                    position  += 2;
                    token.Type = NakoTokenType.AND_AND;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.AND;
                }
                return(token);

            case '|':
                nc = NextChar;
                if (nc == '|')
                {
                    position  += 2;
                    token.Type = NakoTokenType.OR_OR;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.OR;
                }
                return(token);

            case '<':
                nc = NextChar;
                if (nc == '=')
                {
                    position  += 2;
                    token.Type = NakoTokenType.LT_EQ;
                }
                else if (nc == '>')
                {
                    position  += 2;
                    token.Type = NakoTokenType.NOT_EQ;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.LT;
                }
                return(token);

            case '>':
                nc = NextChar;
                if (nc == '=')
                {
                    position  += 2;
                    token.Type = NakoTokenType.GT_EQ;
                }
                else if (nc == '<')
                {
                    position  += 2;
                    token.Type = NakoTokenType.NOT_EQ;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.GT;
                }
                return(token);

            case '!':
                nc = NextChar;
                if (nc == '=')
                {
                    position  += 2;
                    token.Type = NakoTokenType.NOT_EQ;
                }
                else
                {
                    position++;
                    token.Type = NakoTokenType.NOT;
                }
                return(token);

            case '「':
            case '『':
            case '"':
            case '`':
                return(GetStringToken());

            case '+':
                token.Type = NakoTokenType.PLUS;
                position++;
                return(token);

            case '-':
                token.Type = NakoTokenType.MINUS;
                position++;
                return(token);

            case '*':
                if (lastTokenType == NakoTokenType.EOL ||
                    lastTokenType == NakoTokenType.UNKNOWN)
                {
                    token.Type = NakoTokenType.DEF_FUNCTION;
                }
                else
                {
                    token.Type = NakoTokenType.MUL;
                }
                position++;
                return(token);

            case '/':
                // コメントかどうか確認
                nc = NextChar;
                if (nc == '*')
                {
                    return(GetRangeCommentToken());
                }
                if (nc == '/')
                {
                    return(GetLineCommentToken());
                }
                // 割り算かどうか確認
                token.Type = NakoTokenType.DIV;
                position++;
                return(token);

            case '%':
                token.Type = NakoTokenType.MOD;
                position++;
                return(token);

            case '^':
                token.Type = NakoTokenType.POWER;
                position++;
                return(token);

            case '(':
                token.Type = NakoTokenType.PARENTHESES_L;
                position++;
                return(token);

            case ')':
                token.Type = NakoTokenType.PARENTHESES_R;
                position++;
                CheckJosi(token);
                return(token);

            case '{':
                token.Type = NakoTokenType.BRACES_L;
                position++;
                return(token);

            case '}':
                token.Type = NakoTokenType.BRACES_R;
                position++;
                CheckJosi(token);
                return(token);

            case '[':
                token.Type = NakoTokenType.BRACKETS_L;
                position++;
                return(token);

            case ']':
                token.Type = NakoTokenType.BRACKETS_R;
                position++;
                CheckJosi(token);
                return(token);

            case '\\':
                token.Type = NakoTokenType.YEN;
                position++;
                return(token);

            case '#':
                return(GetLineCommentToken());

            default:
                token = GetNotFlagToken();
                if (token.Type == NakoTokenType.UNKNOWN)
                {
                    char   ch  = CurrentChar;
                    string msg = "未定義の文字列: " + (ch < 0x20 ? String.Format("0x{0,0:X2}", (int)ch) : "`" + ch + "`");
                    throw new NakoTokenizerException(msg, token);
                }
                return(token);
            }
        }
예제 #11
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類、行番号、インデントレベルを使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 /// <param name="lineNo">行番号。</param>
 /// <param name="indentLevel">インデントレベル。</param>
 public NakoToken(NakoTokenType type, int lineNo, int indentLevel)
     : this(type, lineNo, indentLevel, "")
 {
 }
예제 #12
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類を使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 public NakoToken(NakoTokenType type)
     : this(type, 0, 0)
 {
 }
예제 #13
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類、行番号、インデントレベルを使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 /// <param name="lineNo">行番号。</param>
 /// <param name="indentLevel">インデントレベル。</param>
 public NakoToken(NakoTokenType type, int lineNo, int indentLevel)
     : this(type, lineNo, indentLevel, "")
 {
 }
예제 #14
0
 /// <summary>
 /// NakoToken クラスの新しいインスタンスを、指定した種類を使用して初期化します。
 /// </summary>
 /// <param name="type">種類。</param>
 public NakoToken(NakoTokenType type)
     : this(type, 0, 0)
 {
 }
예제 #15
0
 /// <summary>
 /// 指定したソースコードからトークンに区切るだけの解析をします。文法を一切考慮しません。
 /// </summary>
 /// <param name="source">解析するソースコード。</param>
 /// <param name="lineNo">開始する行番号。</param>
 /// <param name="indentLevel">開始するインデントレベル。</param>
 /// <returns>指定したソースコードから解析した、トークン一覧。</returns>
 public NakoTokenList TokenizeSplitOnly(string source, int lineNo, int indentLevel)
 {
     Initialization();
     this.source = source;
     this.indentLevel = indentLevel;
     this.lineNo = lineNo;
     // 繰り返しトークンを取得する
     while (!IsEOF)
     {
         var token = GetToken();
         if (token == null)
         {
             continue;
         }
         lastTokenType = token.Type;
         tokens.Add(token);
     }
     return tokens;
 }
예제 #16
0
 /// <summary>
 /// トークンに区切ります。
 /// </summary>
 private void SplitToToken()
 {
     // 最初にインデントを数える
     indentCount = CountIndent();
     indentLevel = 0;
     // 繰り返しトークンを取得する
     while (!IsEOF)
     {
         var token = GetToken();
         if (token == null)
         {
             lastTokenType = NakoTokenType.EOL;
             continue;
         }
         lastTokenType = token.Type;
         // 展開あり文字列をここで展開
         if (token.Type == NakoTokenType.STRING_EX)
         {
             foreach (var extractToken in StringTokenExtract(token))
             {
                 tokens.Add(extractToken);
             }
         }
         else tokens.Add(token);
     }
     // レベルが合うまで SCOPE_END を追加する
     CheckScope();
 }