Beispiel #1
0
        static private ParseTree Parse(string expression, IResolver resolver)
        {
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            ParseTree     tokenTree = new ParseTree();
            StringBuilder literal   = new StringBuilder();
            CharReader    reader    = new CharReader(expression);
            Token         last      = Token.Null;

            while (reader.Next())
            {
                Debug.Assert(literal.Length == 0);
                char c = reader.Read();

                switch (c)
                {
                case '(':
                {
                    switch (last.Type)
                    {
                    case TokenType.Prefix:
                    case TokenType.Operation:
                    case TokenType.Expression:
                    case TokenType.None:
                        last = Token.Create(TokenType.Expression, null);
                        tokenTree.Append(last);
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                }
                break;

                case ')':
                {
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        last = Token.Create(TokenType.EndExpression, null);
                        tokenTree.Append(last);
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                }
                break;

                case '?':
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        last = Token.CreateOperator(c.ToString());
                        tokenTree.Append(last);
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '|':
                case '&':
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.Expression:
                        literal.Append(c);
                        if (!reader.Next())
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }
                        if (reader.Current != c)
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }

                        literal.Append(reader.Read());

                        last = Token.CreateOperator(literal.ToString());
                        tokenTree.Append(last);
                        literal.Length = 0;
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '!':
                    switch (last.Type)
                    {
                    case TokenType.Operation:
                    case TokenType.Expression:
                    case TokenType.None:
                        // prefix
                        last = Token.CreatePrefix(c.ToString());
                        tokenTree.Append(last);
                        break;

                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        // operator
                        literal.Append(c);
                        if (!reader.Next())
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }
                        if (reader.Current != '=')
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }

                        literal.Append(reader.Read());

                        last = Token.CreateOperator(literal.ToString());
                        tokenTree.Append(last);
                        literal.Length = 0;
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '-':
                    switch (last.Type)
                    {
                    case TokenType.Operation:
                    case TokenType.Expression:
                    case TokenType.None:
                        // prefix
                        last = Token.CreatePrefix(c.ToString());
                        tokenTree.Append(last);
                        break;

                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        // operator
                        last = Token.CreateOperator(c.ToString());
                        tokenTree.Append(last);
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '+':
                case '*':
                case '/':
                case '%':
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        last = Token.CreateOperator(c.ToString());
                        tokenTree.Append(last);
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '>':
                case '<':
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        literal.Append(c);
                        if (!reader.Next())
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }
                        if (reader.Current == '=')
                        {
                            literal.Append(reader.Read());
                        }
                        last = Token.CreateOperator(literal.ToString());
                        tokenTree.Append(last);
                        literal.Length = 0;
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '=':
                    switch (last.Type)
                    {
                    case TokenType.Boolean:
                    case TokenType.Number:
                    case TokenType.String:
                    case TokenType.Variable:
                    case TokenType.Function:
                    case TokenType.EndExpression:
                        literal.Append(c);
                        if (!reader.Next())
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }
                        if (reader.Current != '=')
                        {
                            throw ThrowSyntaxError(reader.Position);
                        }

                        literal.Append(reader.Read());

                        last = Token.CreateOperator(literal.ToString());
                        tokenTree.Append(last);
                        literal.Length = 0;
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                case '\'':
                    switch (last.Type)
                    {
                    case TokenType.Operation:
                    case TokenType.Expression:
                    case TokenType.None:
                        last = ExpandString(reader, literal);
                        tokenTree.Append(last);
                        literal.Length = 0;
                        break;

                    default:
                        throw ThrowSyntaxError(reader.Position);
                    }
                    break;

                default:
                    if (char.IsLetter(c))
                    {
                        switch (last.Type)
                        {
                        case TokenType.Prefix:
                        case TokenType.Operation:
                        case TokenType.Expression:
                        case TokenType.None:
                            literal.Append(c);
                            last = ExpandVariable(reader, literal, resolver);
                            tokenTree.Append(last);
                            literal.Length = 0;
                            break;

                        default:
                            throw ThrowSyntaxError(reader.Position);
                        }
                    }
                    else if (char.IsDigit(c))
                    {
                        switch (last.Type)
                        {
                        case TokenType.Prefix:
                        case TokenType.Operation:
                        case TokenType.Expression:
                        case TokenType.None:
                            literal.Append(c);
                            last = ExpandNumber(reader, literal);
                            tokenTree.Append(last);
                            literal.Length = 0;
                            break;

                        default:
                            throw ThrowSyntaxError(reader.Position);
                        }
                    }
                    else
                    {
                        // it is whitespace or newline, to do nothing...
                    }
                    break;
                }
            }
            return(tokenTree);
        }