示例#1
0
        public ParserResult Evaluate(IParserContext input)
        {
            Stack <SyntaxToken> stack = new Stack <SyntaxToken>();

            foreach (LexicToken lt in input.Stream)
            {
                if (lt is ConstantLexicToken)
                {
                    ConstantLexicToken clt = (ConstantLexicToken)lt;
                    SyntaxToken        st  = SyntaxToken.Constant(double.Parse(clt.Value, CultureInfo.InvariantCulture));
                    stack.Push(st);
                }
                else if (lt is VariableLexicToken)
                {
                    VariableLexicToken vlt = (VariableLexicToken)lt;
                    SyntaxToken        st  = SyntaxToken.Variable(vlt.Name);
                    if (Parser.IsPI(vlt.Name))
                    {
                        st = SyntaxToken.PI;
                    }
                    else if (Parser.IsE(vlt.Name))
                    {
                        st = SyntaxToken.E;
                    }
                    stack.Push(st);
                }
                else if (lt is OperatorLexicToken)
                {
                    if (lt is FactorialLexicToken)
                    {
                        stack.Push(SyntaxToken.Factorial(stack.Pop()));
                        continue;
                    }
                    SyntaxToken right = stack.Pop();
                    SyntaxToken left  = stack.Pop();
                    stack.Push(this.GetOperatorFunction((OperatorLexicToken)lt)(left, right));
                }
                else if (lt is FunctionLexicToken)
                {
                    FunctionType function = input.GetFunction(((FunctionLexicToken)lt).Name);
                    switch (function)
                    {
                    case FunctionType.Sin:
                        stack.Push(SyntaxToken.Sin(stack.Pop()));
                        break;

                    case FunctionType.Cos:
                        stack.Push(SyntaxToken.Cos(stack.Pop()));
                        break;

                    case FunctionType.Tan:
                        stack.Push(SyntaxToken.Tan(stack.Pop()));
                        break;

                    case FunctionType.Cot:
                        stack.Push(SyntaxToken.Cot(stack.Pop()));
                        break;

                    case FunctionType.Asin:
                        stack.Push(SyntaxToken.Asin(stack.Pop()));
                        break;

                    case FunctionType.Acos:
                        stack.Push(SyntaxToken.Acos(stack.Pop()));
                        break;

                    case FunctionType.Atan:
                        stack.Push(SyntaxToken.Atan(stack.Pop()));
                        break;

                    case FunctionType.Acot:
                        stack.Push(SyntaxToken.Acot(stack.Pop()));
                        break;

                    case FunctionType.Log:
                        SyntaxToken right = stack.Pop();
                        SyntaxToken left  = stack.Pop();
                        stack.Push(SyntaxToken.Log(left, right));
                        break;

                    case FunctionType.Ln:
                        stack.Push(SyntaxToken.Ln(stack.Pop()));
                        break;

                    case FunctionType.Abs:
                        stack.Push(SyntaxToken.Abs(stack.Pop()));
                        break;

                    case FunctionType.Unsupported:
                    default: throw new NotSupportedException();
                    }
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            ParserResult result = new ParserResult(stack.Pop());

            if (stack.Any())
            {
                throw new InvalidOperationException("There are still values in the queue.");
            }
            return(result);
        }