Esempio n. 1
0
 private void AddToEndStateNodes(NFAStateNode node)
 {
     if (!endStateNodes.Contains(node))
     {
         endStateNodes.Add(node);
     }
 }
Esempio n. 2
0
        /// <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);
        }
Esempio n. 3
0
        /// <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));
        }
Esempio n. 4
0
        /// <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));
        }
Esempio n. 5
0
        /// <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));
        }
Esempio n. 6
0
 /// <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));
 }
Esempio n. 7
0
 private List <NFAStateNode> NullClosure(NFAStateNode node)
 {
     return(node.NullClosure());
 }
Esempio n. 8
0
        /// <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);
        }
Esempio n. 9
0
 public StartEndPair(NFAStateNode startStateNode, NFAStateNode endStateNode)
 {
     this.startStateNode = startStateNode;
     this.endStateNode   = endStateNode;
 }