public void Bind(Atomic right, Atomic left = null) { // Unary if (left == null) { if (Term == NTerm.Binomial) { throw new InvalidOperationException(); } RightAtomic = right; } // Binomial else { if (Term == NTerm.Unary) { throw new InvalidOperationException(); } RightAtomic = right; LeftAtomic = left; } IsBinded = true; }
public void Parse() { var copied = atomicList.ToList(); while (atomicList.Count > 1) { var max = -1; var ind = 0; var maxInd = 0; OperatorAtomic atomic = null; var bLeftInd = 0; var bRightInd = 0; var atom = atomicList.FirstOrDefault(x => { if (x is BracketAtomic braAtom) { return(true); } bLeftInd++; return(false); }) as BracketAtomic; if (atom != null) { var right = atomicList.FirstOrDefault(x => { if (x is BracketAtomic rightItem && rightItem.BracketType == BracketType.Right && atom.BracketLevel == rightItem.BracketLevel) { return(true); } bRightInd++; return(false); }); if (atom.BracketType == BracketType.Left && right != null) { var parsed = BracketParse(bLeftInd + 1, bRightInd - 1); atomicList.RemoveRange(bLeftInd, bRightInd - bLeftInd + 1); atomicList.Insert(bLeftInd, parsed); continue; } else { throw new InvalidOperationException("invalid bracket"); } } foreach (var item in atomicList) { if (item is OperatorAtomic opeatom) { int priority = (int)opeatom.OpType; if (opeatom.IsBinded) { priority = -1; } if (max < priority) { max = priority; maxInd = ind; atomic = opeatom; } } ind++; } if (atomic != null) { try { var rightInd = maxInd + 1; if (atomic.Term == NTerm.Binomial) { var leftInd = maxInd - 1; atomic.Bind(atomicList[rightInd], atomicList[leftInd]); atomicList.RemoveAt(rightInd); atomicList.RemoveAt(leftInd); } else if (atomic.Term == NTerm.Unary) { atomic.Bind(atomicList[rightInd]); atomicList.RemoveAt(rightInd); } } catch (IndexOutOfRangeException) { throw new InvalidOperationException("invalid expression"); } } } ParsedAtomic = atomicList.First(); atomicList = copied; }