示例#1
0
        public TernaryOperatorNode Build()
        {
            TernaryOperatorNode ternaryNode = new TernaryOperatorNode();

            while (_reader.HasNext())
            {
                var node = new AstNodeBuilder(_reader, _block, _interceptChars).Build();

                if (node == null)
                {
                    throwError("ternary empty expression is not allowed!");
                }

                /*
                 * expression end
                 *
                 */
                if (_reader.Current().Value == ";")
                {
                    if (ternaryNode.Operands.Count == 2)//more two
                    {
                        throwError("ternary expression incorrect!");
                    }
                    else if (ternaryNode.Operands.Count == 0)// only  one
                    {
                        throwError("ternary expression incorrect!");
                    }
                    else
                    {
                        ternaryNode.Operands.Add(node);

                        return(ternaryNode);
                    }
                }

                /*
                 * start a new ternary builder
                 *
                 */
                else if (_reader.Current().Value == "?")
                {
                    if (!node.OutputType.IsBool())
                    {
                        throwError("before '?' require a expression which output is bool! ");
                    }

                    var ternaryNode2 = new TerbaryBuilder(_reader, _block).Build();
                    ternaryNode2.Operands.Insert(0, node);

                    ternaryNode.Operands.Add(ternaryNode2);

                    if (_reader.Current().Value == ";")
                    {
                        if (ternaryNode.Operands.Count != 2)
                        {
                            throwError("incompleted ternary exception!");
                        }

                        return(ternaryNode);
                    }
                }
                else if (_reader.Current().Value == ":")
                {
                    if (ternaryNode.Operands.Count == 1)
                    {
                        ternaryNode.Operands.Add(node);

                        return(ternaryNode);
                    }
                    else
                    {
                        ternaryNode.Operands.Add(node);
                    }
                }
            }

            throwError("incompleted ternary expression!");

            return(ternaryNode);
        }
示例#2
0
        public OperatorNode Build()
        {
            while (_reader.HasNext())
            {
                _reader.Next();

                if (_interceptChars.Contains(_reader.Current().Value))
                {
                    return(finishBuild());
                }

                switch (_reader.Current().TokenType)
                {
                /*
                 * in this builder keywords are not allowed
                 */
                case TokenType.Keyword:

                    throwUnexceptedError();

                    break;

                case TokenType.Operator:


                    /*
                     * check priority
                     *
                     * 1. if current operator is higher than current
                     * start a builder,reader go back and reset current operator 's right operand
                     * 2. if current operator's priority is lower than current and has parent builder ,Back one token and return
                     * 3. main build loop.
                     */
                    var priority = _reader.Current().OperatorType.GetPriority();

                    /*
                     *
                     *  first set priority
                     */
                    if (_currentPriority == -2)
                    {
                        _currentPriority = priority;
                    }
                    else
                    {
                        /*
                         *  start a new priority builder
                         *
                         */

                        if (priority > _currentPriority)
                        {
                            buildNewPriority();
                            continue;
                        }
                        else if (priority < _currentPriority && _hasParent && _reader.Current().OperatorType != OperatorType.LeftParenthesis)
                        {
                            return(finishBuild());
                        }
                    }

                    switch (_reader.Current().OperatorType)
                    {
                    //can not post to here
                    //those operator should be handled or intercepted by higher level builder
                    case OperatorType.Binary:
                    case OperatorType.Function:
                    case OperatorType.Coma:
                    case OperatorType.Declare:
                    case OperatorType.ExpressionEnd:
                    case OperatorType.Break:
                    case OperatorType.Continue:
                    case OperatorType.RightParenthesis:
                    case OperatorType.RightBrace:
                    case OperatorType.RightSquare:

                        throwUnexceptedError();

                        break;

                    case OperatorType.Assignment:

                        pushOrderedNode(OperatorNodeFactory.CreateAssigment(_block));

                        break;

                    case OperatorType.AddAsignment:

                        pushOrderedNode(OperatorNodeFactory.CreateAddAssignment(_block));

                        break;

                    case OperatorType.SubtractAsignment:

                        pushOrderedNode(OperatorNodeFactory.CreateSubtractAssignment(_block));

                        break;

                    case OperatorType.MutiplyAsignment:

                        pushOrderedNode(OperatorNodeFactory.CreateMultiplyAssignment(_block));

                        break;

                    case OperatorType.DevideAsignment:

                        pushOrderedNode(OperatorNodeFactory.CreateDevideAsignmentOperatorNode(_block));

                        break;


                    case OperatorType.Ternary:

                        var ternaryNode = new TerbaryBuilder(_reader, _block).Build();

                        ternaryNode.Operands.Insert(0, _currentNode);

                        /*
                         * back one token ,because ';' has been intercepted by ternary builder;
                         *
                         */

                        //  _reader.Back();

                        return(ternaryNode);

                    case OperatorType.Minus:
                        break;

                    case OperatorType.And:

                        pushOrderedNode(OperatorNodeFactory.CreateAnd());

                        break;

                    case OperatorType.Or:

                        pushOrderedNode(OperatorNodeFactory.CreateOr());

                        break;

                    case OperatorType.Not:

                        pushNot(OperatorNodeFactory.CreateNot());

                        break;

                    case OperatorType.Equel:

                        pushOrderedNode(OperatorNodeFactory.CreateCompareEquel());

                        break;

                    case OperatorType.NotEquel:

                        pushOrderedNode(OperatorNodeFactory.CreateCompareNotEquel());

                        break;

                    case OperatorType.MemberAccess:

                        pushOrderedNode(OperatorNodeFactory.CreateMemeber());

                        break;

                    case OperatorType.LeftParenthesis:

                        /*
                         *  maybe new heighest priority operator or method call
                         *
                         *  method call intercepted by push identifier
                         *
                         */
                        if (_currentNode == null)
                        {
                            /*
                             *  expressiomn starts with "("
                             */
                            _currentNode = new ParenthesisBuilder(_reader, _block).Build();

                            /*
                             *  _current priority has been set by "(",we should ignore  that operator
                             */
                            _currentPriority = -2;
                        }
                        else
                        {
                            if (_reader.Last().TokenType == TokenType.Identifier)
                            {
                                /*
                                 * call at epression start
                                 */
                                if (_currentPriority == -1)
                                {
                                    var node = new CallBuilder(_reader, _block).Build();
                                    node.Operands.Insert(0, _currentNode);
                                    _currentNode     = node;
                                    _currentPriority = 8;
                                }

                                /*
                                 * member call
                                 */
                                else if (_currentPriority == 8)
                                {
                                    var node = new CallBuilder(_reader, _block).Build();

                                    node.Operands.Insert(0, _currentNode);
                                    _currentNode = node;
                                }

                                /*
                                 * start a new priority then build call
                                 */
                                else
                                {
                                    buildNewPriority();
                                }
                            }
                            else if (_reader.Last().TokenType != TokenType.Operator)        //"ssss"(5+8)
                            {
                                throwUnexceptedError();
                            }
                            else
                            {
                                //start a  new builder
                                var node = new ParenthesisBuilder(_reader, _block).Build();
                                _currentNode.Operands.Add(node);
                            }
                        }

                        break;

                    /*
                     *  can just be object literal
                     */

                    case OperatorType.LeftBrace:

                        if (_currentNode != null)
                        {
                            throwUnexceptedError();
                        }
                        else
                        {
                            _currentNode = new OperandNode(new ObjectLiteralBuilder(_reader, _block).Build());
                        }

                        break;

                    /*
                     * array index call or array literal
                     *
                     * array index call intercepted by pushidentifier
                     *
                     */

                    case OperatorType.LeftSquare:

                        if (_currentNode != null)
                        {
                            if (_reader.Last().TokenType != TokenType.Identifier)
                            {
                                throwUnexceptedError();
                            }
                            else
                            {
                                /*
                                 * call at epression start
                                 */
                                if (_currentPriority == -1)
                                {
                                    var node = new ArrayIndexBuilder(_reader, _block).Build();
                                    node.Operands.Insert(0, _currentNode);
                                    _currentNode     = node;
                                    _currentPriority = 8;
                                }

                                /*
                                 * member call
                                 */
                                else if (_currentPriority == 8)
                                {
                                    var node = new ArrayIndexBuilder(_reader, _block).Build();

                                    node.Operands.Insert(0, _currentNode);
                                    _currentNode = node;
                                }

                                /*
                                 * start a new priority
                                 */
                                else
                                {
                                    buildNewPriority();
                                }
                            }
                        }
                        else
                        {
                            _currentNode = new OperandNode(new JMappingObject(new ArrayLiteralBuilder(_reader, _block).Build()));
                        }

                        break;

                    case OperatorType.Add:

                        pushOrderedNode(OperatorNodeFactory.CreateAdd());

                        break;

                    case OperatorType.Subtract:

                        pushOrderedNode(OperatorNodeFactory.CreateReduce());

                        break;

                    case OperatorType.Mod:

                        pushOrderedNode(OperatorNodeFactory.CreateMod());

                        break;

                    case OperatorType.Mutiply:

                        pushOrderedNode(OperatorNodeFactory.CreateMutiply());

                        break;

                    case OperatorType.Devide:

                        pushOrderedNode(OperatorNodeFactory.CreateDevide());

                        break;

                    case OperatorType.Bigger:

                        pushOrderedNode(OperatorNodeFactory.CreateBigger());

                        break;

                    case OperatorType.BiggerEquel:

                        pushOrderedNode(OperatorNodeFactory.CreateBiggerEquelNode());

                        break;

                    case OperatorType.Less:

                        pushOrderedNode(OperatorNodeFactory.CreateLess());

                        break;

                    case OperatorType.LessEquel:

                        pushOrderedNode(OperatorNodeFactory.CreateLessEquel());

                        break;

                    // just suppoort left increment and decrement
                    case OperatorType.Increment:

                        pushUnaryOperator(OperatorNodeFactory.CreateIncrement(_block));

                        break;

                    case OperatorType.Decrement:

                        pushUnaryOperator(OperatorNodeFactory.CreateDecremnet(_block));

                        break;

                    case OperatorType.NewInstance:

                        pushNew(OperatorNodeFactory.CreateNew());

                        break;
                    }

                    break;

                case TokenType.Identifier:

                    pushIdentifier(OperatorNodeFactory.CreateOperrand(new JString(_reader.Current().Value)));

                    break;

                case TokenType.String:

                    pushValue(OperatorNodeFactory.CreateOperrand(new JString(_reader.Current().Value)));

                    break;

                case TokenType.Number:


                    pushValue(OperatorNodeFactory.CreateOperrand(new JNumber(_reader.Current().Value)));

                    break;

                case TokenType.Bool:


                    pushValue(OperatorNodeFactory.CreateOperrand(new JBool(_reader.Current().Value)));

                    break;
                }
            }

            /*
             * this builder should finish by interceptor not by  finsh iteration
             *
             *
             */

            throwError("expression incomplete;");

            return(null);
        }