Exemplo n.º 1
0
        /// <summary>
        /// 获取当前Token
        /// </summary>
        /// <returns>当前Token</returns>
        private Token CurrentToken()
        {
            while (Char.IsWhiteSpace(currentChar))
            {
                NextChar();
            }

            TokenType type;
            int       tokenPos = currentPosition;

            if (OperatorChar.Contains(currentChar))
            {
                type = TokenType.Operator;
                string mark = currentChar.ToString();
                // 处理双操作符
                NextChar();
                if (OperatorChar.Contains(currentChar))
                {
                    mark = mark + currentChar.ToString();
                    if (OperatorWord.Contains(mark))
                    {
                        NextChar();
                    }
                }
            }
            else if (Char.IsLetter(currentChar) || currentChar == MarkChar.Parameter || currentChar == MarkChar.Underline)
            {
                type = TokenType.Identifier;
                do
                {
                    NextChar();
                } while (Char.IsLetterOrDigit(currentChar) || currentChar == MarkChar.Underline || currentChar == OperatorChar.Question);
            }
            else if (PackageValue.Contains(currentChar))
            {
                type = TokenType.PackageValue;
                char mark = currentChar;
                do
                {
                    NextChar();
                } while (currentChar != mark && currentPosition < sourceLength);

                if (currentPosition == sourceLength)
                {
                    throw new ArgumentException(string.Format("PackageValue not matched to paired {0}", mark));
                }

                NextChar();
            }
            else if (Char.IsDigit(currentChar))
            {
                type = TokenType.DigitValue;
                do
                {
                    NextChar();
                } while (Char.IsDigit(currentChar));

                // 数值尾标
                if (DigitValue.Contains(currentChar))
                {
                    NextChar();
                }
                else if (currentChar == MarkChar.Dot)
                {
                    NextChar();
                    ValidateDigit();
                    do
                    {
                        NextChar();
                    } while (Char.IsDigit(currentChar));

                    // 指数
                    if (MarkChar.Exponent.Contains(currentChar))
                    {
                        NextChar();
                        if (currentChar == MarkChar.Positive || currentChar == MarkChar.Negative)
                        {
                            NextChar();
                        }

                        ValidateDigit();

                        while (Char.IsDigit(currentChar))
                        {
                            NextChar();
                        }
                    }

                    // 数值尾标
                    if (DigitValue.Contains(currentChar))
                    {
                        NextChar();
                    }
                }
            }
            else if (currentChar == MarkChar.End)
            {
                type = TokenType.End;
            }
            else
            {
                throw new ArgumentException(string.Format("Unsupported Char {0}", currentChar));
            }

            var text = source.Substring(tokenPos, currentPosition - tokenPos);

            return(new Token {
                Type = type, Text = text, Index = tokenPos
            });
        }
        /// <summary>
        /// 处理表达式前缀.
        /// </summary>
        private void ProcessLambdaPrefix()
        {
            // 检查是否有 Lambda 前置符(如: m => )
            if (spResult.Any(p => p.Is(OperatorWord.LambdaPrefix)))
            {
                Token token = spResult.Next();
                if (token.Is(OperatorWord.LeftBracket))
                {
                    // 有括号时,可以有多个参数
                    var bracketContent = spResult.SkipUntil(p => p.Is(OperatorWord.RightBracket));
                    bracketContent.RemoveAt(bracketContent.Count - 1);

                    // 检测下一个Token是否为LambdaPrefix
                    if (!spResult.Next().Is(OperatorWord.LambdaPrefix))
                    {
                        spResult.ReturnToIndex();
                        return;
                    }

                    // 解析参数
                    IEnumerable <Token> parameters = ResolveParameters(bracketContent);
                    int index = 0;
                    foreach (var item in parameters)
                    {
                        expParams.Add(Expression.Parameter(parameterTypes[index++], item.Text));
                    }
                }
                else if (token.Type == TokenType.Identifier && (char.IsLetter(token.Text[0]) || token.Text[0] == MarkChar.Underline) && !OperatorWord.Contains(token.Text))
                {
                    // 无括号时,最多只有一个参数
                    // 检测下一个Token是否为LambdaPrefix
                    if (!spResult.Next().Is(OperatorWord.LambdaPrefix))
                    {
                        spResult.ReturnToIndex();
                        return;
                    }

                    expParams.Add(Expression.Parameter(parameterTypes[0], token.Text));
                }

                // 参数表达式个数和传入委托参数个数不匹配判断
                if (expParams.Count != parameterTypes.Length)
                {
                    throw new ArgumentOutOfRangeException("The count of parameters is not equal.");
                }
            }
        }