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); }
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); }