Esempio n. 1
0
        Token GetNextToken(StringReader reader)
        {
            int peekResult = reader.Peek();

            if (peekResult == -1)
            {
                throw new InvalidOperationException("Stream is empty");
            }

            char firstSymbol = (char)peekResult;

            if (ParseRules.IsValidNumberFirstChar(firstSymbol))
            {
                return(GetNumber(reader));
            }
            if (ParseRules.IsValidIdentifierFirstChar(firstSymbol))
            {
                return(GetIdentifier(reader));
            }
            if (ParseRules.IsValidSymbolChar(firstSymbol))
            {
                return(GetSymbol(reader));
            }

            throw new ArgumentException(String.Format("Unexpected token: \"{0}\"", firstSymbol));
        }
Esempio n. 2
0
        Token GetIdentifier(StringReader reader)
        {
            StringBuilder identifierBuilder = new StringBuilder();

            char symbol;

            while (true)
            {
                int peekResult = reader.Peek();
                if (peekResult == -1)
                {
                    break;
                }
                symbol = (char)peekResult;

                if (ParseRules.IsValidIdentifierChar(symbol))
                {
                    identifierBuilder.Append(symbol);
                    reader.Read();
                    continue;
                }

                if (ParseRules.IsStopForIdentifierOrLiteralChar(symbol))
                {
                    break;
                }

                throw new ArgumentException(String.Format("Unexpected character in identifier token: \"{0}\"", symbol));
            }

            return(new IdentifierToken(identifierBuilder.ToString()));
        }
Esempio n. 3
0
        // expression is parsed using modified Dijkstra's shunting-yard algorithm.
        TreeNode ParseExpression(ConstructionContext context, params char[] stopSymbols)
        {
            Stack <TreeNode> termStack = new Stack <TreeNode>();
            Stack <BinaryOperatorOperation> operatorStack = new Stack <BinaryOperatorOperation>();

            termStack.Push(ParseTermWithPossibleFactorial(context));             // expression should have at least one term

            // then there should be exactly one binary operator and one term every iteration
            while (context.TryPeekNextToken(out Token token))
            {
                if (token is SymbolToken symbolToken)
                {
                    if (ParseRules.IsBinaryOperatorChar(symbolToken.Symbol))
                    {
                        context.EatLastToken();                         // eat binary operator

                        BinaryOperatorOperation curOperation = BinaryOperatorOperation.OperatorDictionary[symbolToken.Symbol.ToString()];
                        while (operatorStack.Count > 0)
                        {
                            BinaryOperatorOperation topOperation = operatorStack.Peek();
                            if ((topOperation.Precedence > curOperation.Precedence) ||
                                (topOperation.Precedence == curOperation.Precedence) && topOperation.IsLeftAssociative)
                            {
                                PopOperatorAndPushResult(termStack, operatorStack);
                            }
                            else
                            {
                                break;
                            }
                        }
                        operatorStack.Push(curOperation);

                        termStack.Push(ParseTermWithPossibleFactorial(context));
                        continue;
                    }
                    else if (stopSymbols.Contains(symbolToken.Symbol))
                    {
                        while (operatorStack.Count > 0)
                        {
                            PopOperatorAndPushResult(termStack, operatorStack);
                        }
                        return(termStack.Pop());
                    }
                }
                throw new Exception(String.Format("Unexpected token: '{0}', expected binary operator or stop-symbol", token));
            }

            if (stopSymbols.Length > 0)
            {
                throw new Exception(String.Format("Unfinished expression: expected stop symbol '{0}'", stopSymbols[0]));
            }

            while (operatorStack.Count > 0)
            {
                PopOperatorAndPushResult(termStack, operatorStack);
            }
            return(termStack.Pop());
        }
Esempio n. 4
0
        Token GetNumber(StringReader reader)
        {
            StringBuilder literalBuilder = new StringBuilder();

            char symbol, lastSymbol = (char)0;
            bool pointWasPut = false, exponentSignWasPut = false, exponentWasPut = false;

            while (true)
            {
                int peekResult = reader.Peek();
                if (peekResult == -1)
                {
                    break;
                }
                symbol = (char)peekResult;

                if (ParseRules.IsValidNumberChar(symbol, lastSymbol, pointWasPut, exponentSignWasPut, exponentWasPut))
                {
                    if (ParseRules.IsDecimalPointChar(symbol))
                    {
                        pointWasPut = true;
                    }
                    if (ParseRules.IsSignChar(symbol))
                    {
                        exponentSignWasPut = true;
                    }
                    if (ParseRules.IsExponentChar(symbol))
                    {
                        exponentWasPut = true;
                    }

                    literalBuilder.Append(symbol);
                    lastSymbol = symbol;
                    reader.Read();
                    continue;
                }

                if (ParseRules.IsStopForIdentifierOrLiteralChar(symbol))
                {
                    break;
                }

                throw new ArgumentException(String.Format("Unexpected character in number token: \"{0}\"", symbol));
            }

            return(new NumberToken(Double.Parse(literalBuilder.ToString(), System.Globalization.NumberStyles.AllowExponent | System.Globalization.NumberStyles.AllowDecimalPoint, System.Globalization.CultureInfo.InvariantCulture)));
        }