private void AddOperationToTree(CodeElement leftExprCode, CodeElement rightOpCode, CodeElement rightExprCode, List <TextElement> comments) { WordBinaryOperator leftOperator = leftExprCode.ParserElement as WordBinaryOperator; WordBinaryOperator rightOpSymbol = rightOpCode.ParserElement as WordBinaryOperator; // is the insertpoint a value // Or the insertPoint is a completed expression (eg parentheses) if (leftOperator == null || (_binaryOperators.Contains(leftOperator) && _completeOperations.Contains(leftExprCode))) { // insert TextElement parent = leftExprCode.Parent; rightOpCode.Add(leftExprCode); rightOpCode.Add(rightExprCode); parent.ReplaceSubElement(leftExprCode, rightOpCode); rightOpCode.AddRange(comments); return; } // if the insertPoint has higther precedence if (leftOperator.Precedence > rightOpSymbol.Precedence) { // insert TextElement parent = leftExprCode.Parent; rightOpCode.Add(leftExprCode); rightOpCode.Add(rightExprCode); parent.ReplaceSubElement(leftExprCode, rightOpCode); rightOpCode.AddRange(comments); return; } // if the insertPoint has lower precedence if (leftOperator.Precedence < rightOpSymbol.Precedence) { AddOperationToTree(leftExprCode.ChildNodes[1] as CodeElement, rightOpCode, rightExprCode, comments); } // if the insertPoint has same precedence and operator is rigth associative else if (rightOpSymbol.RightAssociative) { AddOperationToTree(leftExprCode.ChildNodes[1] as CodeElement, rightOpCode, rightExprCode, comments); } // if the insertPoint has same precedence and operator is left associative else { // insert TextElement parent = leftExprCode.Parent; rightOpCode.Add(leftExprCode); rightOpCode.Add(rightExprCode); parent.ReplaceSubElement(leftExprCode, rightOpCode); rightOpCode.AddRange(comments); return; } }
public override bool Load(List <TextElement> outElements, int level) { int from = TextBuffer.PointerNextChar; // Read a value first if (!LoadValue(outElements, level, true)) { // if the expression does'nt start with a value; the intire expression fails. return(SetPointerBack(from)); } TextBuffer.Status.ThisIsUnambiguous(this, outElements[outElements.Count - 1]); // Read following operations as alternately binary operators and values. var operations = new List <TextElement>(); from = TextBuffer.PointerNextChar; while (LoadBinaryOperator(operations, level) && LoadValue(operations, level, false)) { TextBuffer.Status.ThisIsUnambiguous(this, operations[operations.Count - 1]); from = TextBuffer.PointerNextChar; } // Set pointer back TextBuffer.PointerNextChar = from; // If only one value the return that. if (operations.Count == 0) { return(true); } // Order elements in a tree according to precedence and association rules. // set first value under a dummy parent CodeElement parent = new CodeElement(this, null); parent.Add(outElements[0]); var comments = new List <TextElement>(); int nextValueIndex = 0; while (nextValueIndex < operations.Count - 1 && operations[nextValueIndex] is CommentElement) { comments.Add(operations[nextValueIndex++]); } while (nextValueIndex < operations.Count - 1) { int opIndex = nextValueIndex++; while (nextValueIndex < operations.Count - 1 && operations[nextValueIndex] is CommentElement) { comments.Add(operations[nextValueIndex++]); } int expIndex = nextValueIndex++; while (nextValueIndex < operations.Count && operations[nextValueIndex] is CommentElement) { comments.Add(operations[nextValueIndex++]); } AddOperationToTree(parent.Codes().First(), (CodeElement)operations[opIndex], (CodeElement)operations[expIndex], comments); comments.Clear(); } _completeOperations.Insert(0, (CodeElement)parent.ChildNodes[0]); outElements[0] = parent.ChildNodes[0]; return(true); }