Пример #1
0
        public void ReduceRoot()
        {
            if (this.Tokens.Count == 1)
            {
                Token token = this.LastToken;

                // Delete naked groups
                if (token is PartialCompletedExpression g)
                {
                    this.Tokens.Clear();
                    this.Tokens.AddRange(g.Tokens);
                }

                // Artificially insert a bogus operator for values
                if (token is ValueToken)
                {
                    this.AddToken(OperatorToken.CreateFromString("*", -1));
                    this.AddToken(ValueToken.Create(1, -1));
                }
            }
        }
Пример #2
0
    private static List <Token> Tokenize(string expression)
    {
        Stack <ParsingContext> parsingContextStack = new Stack <ParsingContext>();
        ParsingContext         parsingContext      = new ParsingContext();
        int index;

        void CompleteNumber()
        {
            StringBuilder currentToken = parsingContext.CurrentToken;

            if (currentToken.Length > 0)
            {
                parsingContext.AddToken(ValueToken.CreateFromString(currentToken.ToString(), index));
            }

            currentToken.Clear();
        }

        void CompleteMinusExpression(bool isOperator)
        {
            if (parsingContext.PossiblePendingOperator != '-')
            {
                return;
            }

            if (isOperator)
            {
                parsingContext.AddToken(
                    OperatorToken.CreateFromString("-", index + 1)
                    );

                parsingContext.PossiblePendingOperator = Char.MinValue;
                return;
            }

            if (parsingContext.LastToken is PartialCompletedExpression g)
            {
                List <Token> tokenList = new List <Token>
                {
                    ValueToken.CreateFromString("-1", index),
                    OperatorToken.CreateFromString("*", index),
                    g
                };

                // Last is a group, and "-(1 * 3)" is actually "-1 * (1 * 3)"
                parsingContext.ReplaceToken(
                    parsingContext.LastToken,
                    PartialCompletedExpression.Create(
                        tokenList
                        )
                    );
            }
            else if (parsingContext.LastToken is ValueToken vt)
            {
                parsingContext.ReplaceToken(
                    parsingContext.LastToken,
                    ValueToken.Create(-1 * vt.Value, vt.Position)
                    );
            }
            else
            {
                parsingContext.AppendToPartiallyCompletedToken(parsingContext.PossiblePendingOperator);
            }

            parsingContext.PossiblePendingOperator = Char.MinValue;
        }

        // Parse token from right to left
        for (index = expression.Length - 1; index >= 0; index--)
        {
            char ch = expression[index];

            // Whitespace does not matter
            if (Char.IsWhiteSpace(ch))
            {
                continue;
            }

            // Group take precedence
            if (ch == ')')
            {
                CompleteNumber();
                CompleteMinusExpression(true);

                parsingContextStack.Push(parsingContext);
                parsingContext = new ParsingContext();
                continue;
            }

            // Group end
            if (ch == '(')
            {
                CompleteMinusExpression(false);
                CompleteNumber();

                ParsingContext groupContext = parsingContext;
                parsingContext = parsingContextStack.Pop();

                parsingContext.AddToken(
                    PartialCompletedExpression.Create(groupContext.Tokens)
                    );

                continue;
            }

            if (ch == '-')
            {
                // Otherwise it is probably part of a number, so just prepend it
                CompleteNumber();
                if (parsingContext.PossiblePendingOperator == ch)
                {
                    CompleteMinusExpression(false);
                }

                parsingContext.PossiblePendingOperator = ch;
                continue;
            }

            if (Char.IsDigit(ch) || ch == '.')
            {
                CompleteMinusExpression(true);

                parsingContext.AppendToPartiallyCompletedToken(ch);
            }
            else
            {
                CompleteMinusExpression(false);
                CompleteNumber();

                parsingContext.AddToken(OperatorToken.CreateFromString(ch.ToString(), index));
            }
        }

        CompleteNumber();
        CompleteMinusExpression(false);

        parsingContext.ReduceRoot();
        return(parsingContext.Tokens);
    }