/// <summary>
        /// 
        /// </summary>
        /// <param name="currentPos">结束后指向该Token的下一个字符处</param>
        /// <param name="end"></param>
        /// <param name="matched">
        /// string: 已处理转义符
        /// var: 不含$符,即matched就是变量名
        /// int, float, operator: 不变
        /// </param>
        /// <returns></returns>
        private MatchTokenResult MatchToken(int currentPos, int end)
        {
            //string matched = null;
            MatchTokenResult result = new MatchTokenResult();
            result.BeginPos = currentPos;

            for (; isWhiteSpace(expr[result.BeginPos]) && result.BeginPos < end; result.BeginPos++) ;
            if (result.BeginPos >= end)
            {
                result.EndPos = result.BeginPos;
                result.TokenType = TokenType.Null;
                return result;
            }
            result.EndPos = result.BeginPos;

            char c = expr[result.EndPos];
            switch (c)
            {
                case '+':
                case '-':
                case '*':
                case '/':
                case '^':
                case '(':
                case ')':
                    result.Matched = c.ToString();
                    result.EndPos++;
                    result.TokenType = TokenType.Operator;
                    return result;

                case '=':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                    {
                        result.Matched = "==";
                        result.EndPos += 2;
                    }
                    else
                    {
                        result.Matched = "=";
                        result.EndPos++;
                    }
                    result.TokenType = TokenType.Operator;
                    return result;

                case '!':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                    {
                        result.Matched = "!=";
                        result.EndPos += 2;
                    }
                    else
                    {
                        result.Matched = "!";
                        result.EndPos++;
                    }
                    result.TokenType = TokenType.Operator;
                    return result;

                case '&':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '&')
                    {
                        result.Matched = "&&";
                        result.EndPos += 2;
                        result.TokenType = TokenType.Operator;
                        return result;
                    }
                    else
                    {
                        kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                        result.TokenType = TokenType.Error;
                        return result;
                    }

                case '|':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '|')
                    {
                        result.Matched = "||";
                        result.EndPos += 2;
                        result.TokenType = TokenType.Operator;
                        return result;
                    }
                    else
                    {
                        kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                        result.TokenType = TokenType.Error;
                        return result;
                    }

                case '>':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                    {
                        result.Matched = ">=";
                        result.EndPos += 2;
                    }
                    else
                    {
                        result.Matched = ">";
                        result.EndPos ++;
                    }
                    result.TokenType = TokenType.Operator;
                    return result;

                case '<':
                    if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                    {
                        result.EndPos += 2;
                        result.Matched = "<=";
                    }
                    else
                    {
                        result.EndPos++;
                        result.Matched = "<";
                    }
                    result.TokenType = TokenType.Operator;
                    return result;

                case '"':
                    result.EndPos++;
                    if (result.EndPos >= end)
                    {
                        kernel.IssueError(ErrorType.SingleQuote, loc.Offset(result.EndPos));
                        result.TokenType = TokenType.Error;
                        return result;
                    }

                    StringBuilder matchedBuilder = new StringBuilder();
                    bool escape = false;

                    while (result.EndPos < end)
                    {
                        if (expr[result.EndPos] == '\\')
                        {
                            if(escape)
                            {
                                matchedBuilder.Append('\\');
                                escape = false;
                            }
                            else
                            {
                                escape = true;
                            }
                        }
                        else if (expr[result.EndPos] == '"')
                        {
                            if (escape)
                            {
                                matchedBuilder.Append('"');
                                escape = false;
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            if (escape)
                            {
                                switch (expr[result.EndPos])
                                {
                                    case 'n':
                                        matchedBuilder.Append('\n');
                                        break;

                                    case 't':
                                        matchedBuilder.Append('\t');
                                        break;

                                    case 'r':
                                        matchedBuilder.Append('\r');
                                        break;

                                    default:
                                        kernel.IssueError(ErrorType.UnknownEscapeChar, loc.Offset(result.EndPos), expr[result.EndPos].ToString());
                                        result.TokenType = TokenType.Error;
                                        return result;
                                }
                                escape = false;
                            }
                            else
                            {
                                matchedBuilder.Append(expr[result.EndPos]);
                            }
                        }

                        result.EndPos++;
                    }

                    if (result.EndPos < end)       //遇到引号后跳出while
                    {
                        result.EndPos++;           //跳过引号
                        result.Matched = matchedBuilder.ToString();
                        result.TokenType = TokenType.String;
                        return result;
                    }
                    else                        //遇到End而跳出while,即没有配对引号
                    {
                        kernel.IssueError(ErrorType.SingleQuote, loc.Offset(result.EndPos));
                        result.TokenType = TokenType.Error;
                        return result;
                    }

                default:
                    string substr = expr.Substring(result.EndPos, end - result.EndPos);
                    Match m;
                    if ((m = floatPattern.Match(substr)).Success)
                    {
                        result.Matched = m.Groups[0].Value;
                        result.EndPos += m.Length;
                        result.TokenType = TokenType.Float;
                        return result;
                    }
                    else if ((m = intPattern.Match(substr)).Success)
                    {
                        result.Matched = m.Groups[0].Value;
                        result.EndPos += m.Length;
                        result.TokenType = TokenType.Int;
                        return result;
                    }
                    else if ((m = varPattern.Match(substr)).Success)
                    {
                        result.Matched = m.Groups[1].Value;
                        result.EndPos += m.Length;
                        result.TokenType = TokenType.Variable;
                        return result;
                    }
                    else if ((m = boolPattern.Match(substr)).Success)
                    {
                        result.Matched = m.Groups[0].Value;
                        result.EndPos += m.Length;
                        result.TokenType = TokenType.Bool;
                        return result;
                    }
                    else
                    {
                        kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                        result.TokenType = TokenType.Error;
                        return result;
                    }
            }
        }
Example #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="currentPos">结束后指向该Token的下一个字符处</param>
        /// <param name="end"></param>
        /// <param name="matched">
        /// string: 已处理转义符
        /// var: 不含$符,即matched就是变量名
        /// int, float, operator: 不变
        /// </param>
        /// <returns></returns>
        private MatchTokenResult MatchToken(int currentPos, int end)
        {
            //string matched = null;
            MatchTokenResult result = new MatchTokenResult();

            result.BeginPos = currentPos;

            for (; isWhiteSpace(expr[result.BeginPos]) && result.BeginPos < end; result.BeginPos++)
            {
                ;
            }
            if (result.BeginPos >= end)
            {
                result.EndPos    = result.BeginPos;
                result.TokenType = TokenType.Null;
                return(result);
            }
            result.EndPos = result.BeginPos;

            char c = expr[result.EndPos];

            switch (c)
            {
            case '+':
            case '-':
            case '*':
            case '/':
            case '^':
            case '(':
            case ')':
                result.Matched = c.ToString();
                result.EndPos++;
                result.TokenType = TokenType.Operator;
                return(result);

            case '=':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                {
                    result.Matched = "==";
                    result.EndPos += 2;
                }
                else
                {
                    result.Matched = "=";
                    result.EndPos++;
                }
                result.TokenType = TokenType.Operator;
                return(result);

            case '!':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                {
                    result.Matched = "!=";
                    result.EndPos += 2;
                }
                else
                {
                    result.Matched = "!";
                    result.EndPos++;
                }
                result.TokenType = TokenType.Operator;
                return(result);

            case '&':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '&')
                {
                    result.Matched   = "&&";
                    result.EndPos   += 2;
                    result.TokenType = TokenType.Operator;
                    return(result);
                }
                else
                {
                    kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                    result.TokenType = TokenType.Error;
                    return(result);
                }

            case '|':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '|')
                {
                    result.Matched   = "||";
                    result.EndPos   += 2;
                    result.TokenType = TokenType.Operator;
                    return(result);
                }
                else
                {
                    kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                    result.TokenType = TokenType.Error;
                    return(result);
                }

            case '>':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                {
                    result.Matched = ">=";
                    result.EndPos += 2;
                }
                else
                {
                    result.Matched = ">";
                    result.EndPos++;
                }
                result.TokenType = TokenType.Operator;
                return(result);

            case '<':
                if (result.EndPos + 1 < end && expr[result.EndPos + 1] == '=')
                {
                    result.EndPos += 2;
                    result.Matched = "<=";
                }
                else
                {
                    result.EndPos++;
                    result.Matched = "<";
                }
                result.TokenType = TokenType.Operator;
                return(result);

            case '"':
                result.EndPos++;
                if (result.EndPos >= end)
                {
                    kernel.IssueError(ErrorType.SingleQuote, loc.Offset(result.EndPos));
                    result.TokenType = TokenType.Error;
                    return(result);
                }

                StringBuilder matchedBuilder = new StringBuilder();
                bool          escape         = false;

                while (result.EndPos < end)
                {
                    if (expr[result.EndPos] == '\\')
                    {
                        if (escape)
                        {
                            matchedBuilder.Append('\\');
                            escape = false;
                        }
                        else
                        {
                            escape = true;
                        }
                    }
                    else if (expr[result.EndPos] == '"')
                    {
                        if (escape)
                        {
                            matchedBuilder.Append('"');
                            escape = false;
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (escape)
                        {
                            switch (expr[result.EndPos])
                            {
                            case 'n':
                                matchedBuilder.Append('\n');
                                break;

                            case 't':
                                matchedBuilder.Append('\t');
                                break;

                            case 'r':
                                matchedBuilder.Append('\r');
                                break;

                            default:
                                kernel.IssueError(ErrorType.UnknownEscapeChar, loc.Offset(result.EndPos), expr[result.EndPos].ToString());
                                result.TokenType = TokenType.Error;
                                return(result);
                            }
                            escape = false;
                        }
                        else
                        {
                            matchedBuilder.Append(expr[result.EndPos]);
                        }
                    }

                    result.EndPos++;
                }

                if (result.EndPos < end)           //遇到引号后跳出while
                {
                    result.EndPos++;               //跳过引号
                    result.Matched   = matchedBuilder.ToString();
                    result.TokenType = TokenType.String;
                    return(result);
                }
                else                            //遇到End而跳出while,即没有配对引号
                {
                    kernel.IssueError(ErrorType.SingleQuote, loc.Offset(result.EndPos));
                    result.TokenType = TokenType.Error;
                    return(result);
                }

            default:
                string substr = expr.Substring(result.EndPos, end - result.EndPos);
                Match  m;
                if ((m = floatPattern.Match(substr)).Success)
                {
                    result.Matched   = m.Groups[0].Value;
                    result.EndPos   += m.Length;
                    result.TokenType = TokenType.Float;
                    return(result);
                }
                else if ((m = intPattern.Match(substr)).Success)
                {
                    result.Matched   = m.Groups[0].Value;
                    result.EndPos   += m.Length;
                    result.TokenType = TokenType.Int;
                    return(result);
                }
                else if ((m = varPattern.Match(substr)).Success)
                {
                    result.Matched   = m.Groups[1].Value;
                    result.EndPos   += m.Length;
                    result.TokenType = TokenType.Variable;
                    return(result);
                }
                else if ((m = boolPattern.Match(substr)).Success)
                {
                    result.Matched   = m.Groups[0].Value;
                    result.EndPos   += m.Length;
                    result.TokenType = TokenType.Bool;
                    return(result);
                }
                else
                {
                    kernel.IssueError(ErrorType.UnknownToken, loc.Offset(result.EndPos));
                    result.TokenType = TokenType.Error;
                    return(result);
                }
            }
        }