Пример #1
0
        public override Production Parse(List <Token> tokens)
        {
            var nonWhitespace = tokens.NextNonWhitespace();

            if (nonWhitespace.TokenClass != TokenClass.Boolean &&
                nonWhitespace.TokenClass != TokenClass.Float &&
                nonWhitespace.TokenClass != TokenClass.Integer &&
                nonWhitespace.TokenClass != TokenClass.ReplacementSymbol &&
                nonWhitespace.TokenClass != TokenClass.StartScope &&
                nonWhitespace.TokenClass != TokenClass.String &&
                nonWhitespace.TokenClass != TokenClass.Symbol)
            {
                return(new Production(null, tokens));
            }
            var remainder = tokens.ToList();

            while (remainder.Any() && Constituents.Count < 3) // An operation must have exactly three items: value op value
            {
                var        currentToken = remainder.First().TokenClass;
                Production current      = null;
                //check whether the right hand side of the operation is another operation
                if (Constituents.Count == 2)
                {
                    current = new OperationExpression().Parse(remainder);
                }
                if (Constituents.Count != 2 || current?.Expression == null)
                {
                    switch (currentToken)
                    {
                    case TokenClass.StartScope:
                        current = new ScopedExpression().Parse(remainder);
                        break;

                    case TokenClass.Whitespace:
                        current = new WhitespaceExpression().Parse(remainder);
                        break;

                    case TokenClass.ReplacementSymbol:
                        current = new ReplacementSymbolExpression().Parse(remainder);
                        break;

                    case TokenClass.Symbol:
                        current = new FunctionExpression().Parse(remainder);
                        if (current.Expression == null)
                        {
                            current = new SymbolExpression().Parse(remainder);
                        }
                        break;

                    case TokenClass.Operator:
                        if (Constituents.Count == 2)
                        {
                            current = NumericExpression.TryParseNumeric(remainder);
                            break;
                        }
                        current = new OperatorExpression().Parse(remainder);
                        break;

                    case TokenClass.Integer:
                    case TokenClass.Float:
                        current = NumericExpression.TryParseNumeric(remainder);
                        break;

                    case TokenClass.String:
                        current = new StringExpression().Parse(remainder);
                        break;

                    case TokenClass.Boolean:
                        current = new BooleanExpression().Parse(remainder);
                        break;

                    default:
                        return(new Production(null, tokens));
                    }
                }
                if (current == null || current.Expression == null)
                {
                    return(new Production(null, tokens));
                }
                remainder = current.RemainingTokens;
                if (!(current.Expression is WhitespaceExpression))
                {
                    Constituents.Add(current.Expression);
                }
            }
            if (Constituents.None(c => c is OperatorExpression))
            {
                return(new Production(null, tokens));
            }
            if (Constituents.Count != 3)
            {
                return(new Production(null, tokens));
            }
            return(new Production(this, remainder));
        }