public static void Next(IEditEnumerator <Token> itr) { // Is the next thing a minus sign? if (itr.MoveNext() && IsString(itr.Current, "-")) { // Move off the negative sign (to the thing after) itr.MoveNext(); // Delete the negative sign itr.Remove(-1); // Negate the value after Operand next = (Operand)Math.MathReader.Parser.ParseOperand(itr).Value; next.Multiply(-1); // Replace with the negated value itr.Add(0, new Token.Operand <Operand>(next)); } }
public TOutput Parse(IEditEnumerable <TInput> input) { string parsing = "parsing |"; foreach (TInput s in input) { parsing += s + "|"; } Print.Log(parsing); Stack <Evaluator> quantities = new Stack <Evaluator>(); IEditEnumerator <TInput> itr = input.GetEnumerator(); quantities.Push(new Evaluator(new Parse.Collections.Generic.LinkedList <object>(), new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count])); while (true) { Evaluator quantity = quantities.Peek(); bool done = !itr.MoveNext(); if (done || Closing.Contains(itr.Current)) { Evaluator e = quantities.Pop(); Print.Log("close", e.Input.Count); LinkedListNode <object> a = e.Input.First; while (a != null) { Print.Log(a.Value, a.Value?.GetType()); a = a.Next; } Print.Log("\n"); TOutput answer = Close(e); if (quantities.Count == 0) { if (done) { return(answer); } else { Parse.Collections.Generic.LinkedList <object> front = new Parse.Collections.Generic.LinkedList <object>(); front.AddFirst(answer); quantities.Push(new Evaluator(front, new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count])); } } else { quantities.Peek().Input.AddLast(answer); } } else if (Opening.Contains(itr.Current)) { Print.Log("open"); quantities.Push(new Evaluator(new Parse.Collections.Generic.LinkedList <object>(), new LinkedList <LinkedListNode <object> > [Count], new LinkedList <Operator <TOutput> > [Count])); } else { Operator <TOutput> operation; if (Operations.TryGetValue(itr.Current, out operation)) { Print.Log("found operator", itr.Current); int index = IndexOf(itr.Current); // Put the operator in the linked list as a node LinkedListNode <object> node = new LinkedListNode <object>(itr.Current); // Get the list of all of this type of operator (e.g. all instances of "+") if (quantity.Operations[index] == null) { quantity.Operations[index] = new LinkedList <LinkedListNode <object> >(); quantity.Operators[index] = new LinkedList <Operator <TOutput> >(); } if (operation.Order == ProcessingOrder.RightToLeft) { quantity.Operations[index].AddFirst(node); quantity.Operators[index].AddFirst(operation); } else { quantity.Operations[index].AddLast(node); quantity.Operators[index].AddLast(operation); } quantity.Input.AddLast(node); } else { Print.Log("found operand", itr.Current); foreach (TOutput o in ParseOperand(itr.Current)) { Print.Log("\t" + o); quantity.Input.AddLast(o); } } } } }
private T Parse(IEditEnumerator <T> start, ProcessingOrder direction = ProcessingOrder.LeftToRight) { SortedDictionary <int, ProcessingOrder> order = new SortedDictionary <int, ProcessingOrder>(); IEditEnumerator <T> end = start.Copy(); int count = 0; #if DEBUG string parsing = ""; while (end.Move((int)direction)) { if (direction == ProcessingOrder.LeftToRight) { parsing += end.Current + "|"; } else { parsing = end.Current + "|" + parsing; } } Print.Log("parsing section |" + parsing); Print.Log("start is " + start.Current + " and end is " + end.Current); end = start.Copy(); #endif // Initial pass over the input to figure out: // Where the beginning and end are (match parentheses) // What operators we should look for (so we can skip iterating empty tiers) // Also delete anything that's supposed to be ignored while (end.Move((int)direction)) { if (!(end.Current is T)) { continue; } T current = (T)end.Current; Member member = Classify(current); // This is the "close" bracket for the direction we're moving if ((int)direction == (int)member) { // This is the end of the expression we're working on if (count == 0) { break; } else { count--; } } // This is the "open" bracket for the direction we're moving else if ((int)direction == -(int)member) { count++; } else if (Ignore.Contains(current)) { end.Move(-1); end.Remove(1); } // Keep track of what operators we find so we can skip them later else if (member == Member.Operator) { Tuple <Operator <T>, int> temp = Operations[current]; order[temp.Item2] = temp.Item1.Order; } } foreach (KeyValuePair <int, ProcessingOrder> kvp in order) { IEditEnumerator <T> itr = kvp.Value == ProcessingOrder.LeftToRight ^ direction == ProcessingOrder.LeftToRight ? end.Copy() : start.Copy(); while (itr.Move((int)kvp.Value) && !itr.Equals(start) && !itr.Equals(end)) { if (!(itr.Current is T)) { continue; } Tuple <Operator <T>, int> tuple; if (Operations.TryGetValue((T)itr.Current, out tuple) && kvp.Key == tuple.Item2) { Print.Log("doing operation", itr.Current); Operator <T> operation = tuple.Item1; IEditEnumerator <T>[] operandItrs = new IEditEnumerator <T> [operation.Targets.Length]; for (int j = 0; j < operation.Targets.Length; j++) { //operation.Targets[j](operandItrs[j] = itr.Copy()); } T[] operands = new T[operandItrs.Length]; for (int j = 0; j < operandItrs.Length; j++) { Print.Log("\t" + operandItrs[j].Current); operands[j] = ParseOperand(operandItrs[j]); operandItrs[j].Remove(0); } itr.Add(0, operation.Operate(operands)); } } } #if DEBUG Print.Log("done"); IEditEnumerator <T> printer = start.Copy(); while (printer.MoveNext()) { Print.Log("\t" + printer.Current); } #endif IEditEnumerator <T> juxtapose = start.Copy(); T result = Juxtapose(CollectOperands(juxtapose, direction)); juxtapose.Remove(0); return(result); }