public override bool Matches(ContentNode other) { // This recurrsive search figures out whether something like (A|(B|C)) matches (B|(A|C)) // by visiting all the members of the right hand side, then searching to see if the // left hand side "contains" that choice. So it will also return true if "this" has // more choices than "other", which is what we want. So (A|B) matches (A|B|C). if (other is TerminalNode) { return Contains(this.LeftChild, other as TerminalNode) || Contains(this.RightChild, other as TerminalNode); } else if (other is NopNode) { return this.Matches(((NopNode)other).Child); } if (other is ChoiceNode) { ChoiceNode choice = other as ChoiceNode; Literal e = new Literal("", choice.TypeNode); ErrorHandler eh = new ErrorHandler(new ErrorNodeList()); TypeSystem ts = new TypeSystem(eh); return (ts.ExplicitCoercion(e, this.TypeNode) != null); //return this.Matches(choice.LeftChild) && this.Matches(choice.RightChild); } return false; }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { if (commingFrom == Parent) { if (LeftChild.CanAccept(node, isTerminal, namedTerminals)) { return LeftChild.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else if (LeftChild.IsNullable) { commingFrom = LeftChild; } else { return null; // no match } } if (commingFrom == LeftChild) { if (RightChild.CanAccept(node, isTerminal, namedTerminals)) { return RightChild.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else if (RightChild.IsNullable) { commingFrom = RightChild; } else { return null; // no match } } Debug.Assert(commingFrom == RightChild); if (Parent != null) { return Parent.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else { return null; } }
public override bool Matches(ContentNode other) { InternalNode inNode = other as InternalNode; if (inNode != null) { if (RightChild == null) { return inNode.RightChild == null && LeftChild.Matches(inNode.LeftChild); } else { return inNode.RightChild != null && LeftChild.Matches(inNode.LeftChild) && RightChild.Matches(inNode.RightChild); } } return false; }
public void HandleError(ContentNode root, Node offendingNode, Error error, params string[] messageParameters) { this.ErrorHandler.HandleError(offendingNode, error, messageParameters); HasErrors = true; #if DEBUGCONTENTMODEL if (root != null) { StringBuilder sb = new StringBuilder(); root.Dump(sb); this.ErrorHandler.HandleError(offendingNode, Error.DebugContentModel, sb.ToString()); } #endif }
private void Closure(InternalNode node) { if (stack.Count > 0) { ContentNode topNode = (ContentNode)stack.Pop(); if (isPartial && !topNode.IsTerminal) { // need to reach in and wrap _pRight hand side of element. // and n remains the same. InternalNode inNode = (InternalNode)topNode; node.LeftChild = inNode.RightChild; node.Parent = inNode; if (inNode.RightChild != null) { inNode.RightChild.Parent = node; } inNode.RightChild = node; } else { // wrap terminal or any node if (topNode != null) topNode.Parent = node; node.LeftChild = topNode; topNode = node; } stack.Push(topNode); } else { // wrap whole content node.LeftChild = contentNode; contentNode.Parent = node; contentNode = node; } }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { if (LeftChild.CanAccept(node, isTerminal, namedTerminals)) { return LeftChild.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else { Debug.Assert(Parent != null); return Parent.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { int counter = (commingFrom == Parent) ? 0 : (int)rangeNodeCounters[this] + 1; if ((counter <= max) && LeftChild.CanAccept(node, isTerminal, namedTerminals)) { rangeNodeCounters[this] = counter; return LeftChild.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else if (min <= counter) { Debug.Assert(Parent != null); return Parent.Accept(node, this, isTerminal, namedTerminals, rangeNodeCounters); } else { return null; } }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { Debug.Assert(wildcard.Allows(node)); return this; }
public override bool Matches(ContentNode other) { //todo: should allow a lot more than this? return (other is TerminalNode) && base.Matches(other); }
public virtual bool Matches(ContentNode other) { return this.type == other.type; }
public override bool Matches(ContentNode other) { if (other is NamedNode) { // todo: should we check names? //NamedNode n = other as NamedNode; //(this.name.UniqueKey == n.name.UniqueKey && return base.Matches(other); } else if (other is WildcardNode) { // then just check the types and allow coercion to add the missing name. WildcardNode n = other as WildcardNode; return base.Matches(other); } return false; }
public abstract TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters);
private void AddExpectedElements(ArrayList list, ContentNode node) { if (node is SequenceNode) { AddExpectedElements(list, ((SequenceNode)node).LeftChild); } else if (node is ChoiceNode) { ChoiceNode choice = (ChoiceNode)node; AddExpectedElements(list, choice.LeftChild); AddExpectedElements(list, choice.RightChild); } else if (node is StarNode) { StarNode star = (StarNode)node; AddExpectedElements(list, star.LeftChild); } else if (node is NopNode) { NopNode nop = (NopNode)node; AddExpectedElements(list, nop.Child); } else if (node is PlusNode) { PlusNode plus = (PlusNode)node; AddExpectedElements(list, plus.LeftChild); } else if (node is QmarkNode) { QmarkNode qmark = (QmarkNode)node; AddExpectedElements(list, qmark.LeftChild); } else if (node is TerminalNode) { list.Add(node); } }
void AdvanceState(ContentNode node, ValidationState context) { if (node is NamedNode) { this.ValidateElement(((NamedNode)node).Name, context); } else if (node is NopNode) { AdvanceState(((NopNode)node).Child, context); } else if (node is InternalNode) { InternalNode inode = (InternalNode)node; AdvanceState(inode.LeftChild, context); if (inode.RightChild != null) AdvanceState(inode.RightChild, context); } }
public bool Contains(ContentNode group, TerminalNode node) { if (group == null) return false; if (group is TerminalNode) { return node.Matches(group); } else if (group is NopNode) { return Contains(((NopNode)group).Child, node); } else if (group is ChoiceNode) { ChoiceNode choice = group as ChoiceNode; return Contains(choice.LeftChild, node) || Contains(choice.RightChild, node); } return false; }
internal NopNode(ContentNode child, Member mem, TypeNode type) : base(mem, type) { this.child = child;}
public override bool Matches(ContentNode other) { // Here we want to know that "other" contains zero or one of this content model. // So it allows anything other than StarNode or PlusNode. For example: // (A,B) should match (A,B)?. But (A,B)* should not match. if (other is TerminalNode) { return LeftChild.Matches(other); } else if (other is SequenceNode) { return this.LeftChild.Matches(other); } else if (other is ChoiceNode) { return this.LeftChild.Matches(other); } else if (other is NopNode) { return this.Matches(((NopNode)other).Child); } if (other is QmarkNode) { QmarkNode qmark = other as QmarkNode; return this.LeftChild.Matches(qmark.LeftChild); } return false; }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { return child.Accept(node, commingFrom, isTerminal, namedTerminals, rangeNodeCounters); }
public override bool Matches(ContentNode other) { // Here we want to know that "other" contains zero or more of this content model. // So it allows StarNode, PlusNode and QmarkNode. For example: // (A,B) and (A,B)+ and (A,B)? and (A,B)* should all match (A,B)*. if (other is TerminalNode) { return LeftChild.Matches(other); } else if (other is SequenceNode) { return this.LeftChild.Matches(other); } else if (other is ChoiceNode) { return this.LeftChild.Matches(other); } else if (other is NopNode) { return this.Matches(((NopNode)other).Child); } if (other is StarNode) { StarNode star = other as StarNode; return this.LeftChild.Matches(star.LeftChild); } else if (other is PlusNode) { PlusNode plus = other as PlusNode; return this.LeftChild.Matches(plus.LeftChild); } else if (other is QmarkNode) { QmarkNode qmark = other as QmarkNode; return this.LeftChild.Matches(qmark.LeftChild); } return false; }
public override bool Matches(ContentNode other) { if (other is NopNode) other = ((NopNode)other).child; return child.Matches(other); }
public override bool Matches(ContentNode other) { // Here we have to check the range is inclusive. So (A,B) should match (A,B)[0,1] // but not (A,B)[2,5] since the minimum requirement is 2. // Similarly (A,B)[0,5] should not match (A,B)[0,2] since the max is violated. if (other is TerminalNode) { // Then we only have one. return min <= 1 && LeftChild.Matches(other); } else if (other is SequenceNode) { return min <= 1 && this.LeftChild.Matches(other); } else if (other is ChoiceNode) { return min <= 1 && this.LeftChild.Matches(other); } // We know that max is never Int32.MaxValue so StarNode and PlusNode automatically fail. if (other is RangeNode) { RangeNode r = other as RangeNode; return (min <= r.min && max >= r.max) && this.LeftChild.Matches(r.LeftChild); } else if (other is QmarkNode) { QmarkNode qmark = other as QmarkNode; return (min == 0) && this.LeftChild.Matches(qmark.LeftChild); } return false; }
public override TerminalNode Accept(NamedNode node, ContentNode commingFrom, bool isTerminal, NamedNode[] namedTerminals, Hashtable rangeNodeCounters) { Debug.Assert(false); return null; }
public bool CloseGroup() { ContentNode node = (ContentNode)stack.Pop(); if (node == null) { return false; } if (stack.Count == 0) { contentNode = node; isPartial = false; } else { if (stack.Peek() == null) { stack.Pop(); contentNode = node; isPartial = false; } else { isPartial = true; // we are extending an existing content model (probably via subclassing, // so we simply add the node to the existing model as a new child particle). ContentNode parentModel = (ContentNode)stack.Pop(); if (parentModel is InternalNode) { InternalNode pc = (InternalNode)parentModel; if (pc.RightChild == null) { pc.RightChild = node; node.Parent = pc; } else { InternalNode nc = pc.Clone(); nc.LeftChild = pc; nc.RightChild = node; node.Parent = pc.Parent = nc; pc = nc; } node = pc; } else { SequenceNode nc = new SequenceNode(null, null); nc.LeftChild = parentModel; nc.RightChild = node; parentModel.Parent = node.Parent = nc; node = nc; } } stack.Push(node); } return true; }
public void AddTerminal(ContentNode node) { if (stack.Count > 0) { InternalNode inNode = (InternalNode)stack.Pop(); if (inNode != null) { inNode.RightChild = node; node.Parent = inNode; node = inNode; } } stack.Push( node ); isPartial = true; }