private void AddToEndStateNodes(NFAStateNode node) { if (!endStateNodes.Contains(node)) { endStateNodes.Add(node); } }
/// <summary> /// 计算当前状态节点的epsilon闭包 /// </summary> /// <returns></returns> public List <NFAStateNode> NullClosure() { List <NFAStateNode> destNodes = new List <NFAStateNode>(); Stack <NFAStateNode> stack = new Stack <NFAStateNode>(); // epsilon闭包总是包含该状态本身 destNodes.Add(this); stack.Push(this); while (stack.Count != 0) { foreach (Edge <NFAStateNode> edge in stack.Pop().EdgeList) { if (edge.Route == NFA.NULL_CHAR) { NFAStateNode destNode = edge.EndStateNode; if (!destNodes.Contains(destNode)) { destNodes.Add(destNode); stack.Push(destNode); } } } } destNodes.Sort(); return(destNodes); }
/// <summary> /// 单个字符创建NFA /// </summary> /// <returns></returns> private StartEndPair SingleCharCreate(char c) { NFAStateNode startStateNode = new NFAStateNode(); NFAStateNode endStateNode = new NFAStateNode(); startStateNode.Connect(endStateNode, c); allStateNodes.Add(startStateNode); allStateNodes.Add(endStateNode); return(new StartEndPair(startStateNode, endStateNode)); }
/// <summary> /// 或操作,创建NFA /// </summary> /// <returns></returns> private StartEndPair OrCreate(StartEndPair a, StartEndPair b) { NFAStateNode newStartStateNode = new NFAStateNode(); NFAStateNode newEndStateNode = new NFAStateNode(); allStateNodes.Add(newStartStateNode); allStateNodes.Add(newEndStateNode); newStartStateNode.Connect(a.StartStateNode, NULL_CHAR); newStartStateNode.Connect(b.StartStateNode, NULL_CHAR); a.EndStateNode.Connect(newEndStateNode, NULL_CHAR); b.EndStateNode.Connect(newEndStateNode, NULL_CHAR); return(new StartEndPair(newStartStateNode, newEndStateNode)); }
/// <summary> /// 闭包创建NFA /// </summary> /// <param name="startEndPair"></param> /// <returns></returns> private StartEndPair ClosureCreate(StartEndPair startEndPair) { NFAStateNode newStartStateNode = new NFAStateNode(); NFAStateNode newEndStateNode = new NFAStateNode(); allStateNodes.Add(newStartStateNode); allStateNodes.Add(newEndStateNode); newStartStateNode.Connect(startEndPair.StartStateNode, NULL_CHAR); newStartStateNode.Connect(newEndStateNode, NULL_CHAR); startEndPair.EndStateNode.Connect(startEndPair.StartStateNode, NULL_CHAR); startEndPair.EndStateNode.Connect(newEndStateNode, NULL_CHAR); return(new StartEndPair(newStartStateNode, newEndStateNode)); }
/// <summary> /// 将当前节点与另一个节点连接 /// </summary> /// <param name="endStateNode">结束状态节点</param> /// <param name="route">连接路径</param> public void Connect(NFAStateNode endStateNode, char route) { edgeList.Add(new Edge <NFAStateNode>(this, endStateNode, route)); }
private List <NFAStateNode> NullClosure(NFAStateNode node) { return(node.NullClosure()); }
/// <summary> /// 用正则表达式构造NFA,注意压栈的时候压入的是一个开始/结束状态节点对 /// </summary> /// <param name="expression">正则表达式</param> private void CreateNFA(RegularExpression regex) { Stack <StartEndPair> operandStack = new Stack <StartEndPair>(); Stack <Char> operatorStack = new Stack <Char>(); operatorStack.Push(RegularExpression.END_OF_REGEX); char[] regexSplited = regex.Regex.ToCharArray(); int curIndex = 0; while (curIndex < regexSplited.Length && ((regexSplited[curIndex] != RegularExpression.END_OF_REGEX) || (operatorStack.Peek() != RegularExpression.END_OF_REGEX))) { if (RegularExpression.IsOperand(regexSplited[curIndex])) { operandStack.Push(SingleCharCreate(regexSplited[curIndex])); AddToAlphabet(regexSplited[curIndex]); curIndex++; } switch (RegularExpression.GetPriority(operatorStack.Peek(), regexSplited[curIndex])) { case '<': operatorStack.Push(regexSplited[curIndex]); curIndex++; break; case '=': operatorStack.Pop(); curIndex++; break; case '>': switch (operatorStack.Peek()) { case '*': StartEndPair target = operandStack.Pop(); operatorStack.Pop(); operandStack.Push(ClosureCreate(target)); break; case '|': StartEndPair b1 = operandStack.Pop(); StartEndPair a1 = operandStack.Pop(); operatorStack.Pop(); operandStack.Push(OrCreate(a1, b1)); break; case '.': StartEndPair b2 = operandStack.Pop(); StartEndPair a2 = operandStack.Pop(); operatorStack.Pop(); operandStack.Push(AndCreate(a2, b2)); break; } break; } } startStateNode = operandStack.Peek().StartStateNode; AddToEndStateNodes(operandStack.Peek().EndStateNode); }
public StartEndPair(NFAStateNode startStateNode, NFAStateNode endStateNode) { this.startStateNode = startStateNode; this.endStateNode = endStateNode; }