当指定的NFA节点是1的时候,如果要获取 使用一个条件a 可以到达的节点的集合,肉眼的答案是node2和node3;但是要怎么样使用代码实现?
节点的性质
- 每个节点至多可以拥有两个子节点,允许只拥有一个子节点或者根本不拥有节点;
epsilon链接的个数不受限制,但是其他的链接个数只能出现1次,例如指定节点1和条件a,得到的结果集合中,将只有节点2,3,6,但是不会出现节点4和节点7;
查找逻辑
实际上可以把NFA图理解成一个二叉树,不同的是这个二叉树可能会存在环,不过实际上并不影响其使用;NFA中存在一种特殊的链接,epsilon链接,这种链接纯粹是为了方便生成NFA链接而存在的…如果节点1与节点2之间存在一个epsilon链接,那么从节点1出发,即使没有输入也能够到达节点2;所以如果两个节点之间存在epsilon链接,就可以将这两个节点理解为一个节点;
再来说搜索,如果给定一个节点和一个条件,查找从给定节点出发,能够通过条件到达的目标节点;
如果将NFA图看作一个二叉树的话,可以使用深度优先搜索进行…可以很方便的便利分叉;递归
void GetNextNFANodes(struct DFANODE *currentDFA,struct NFANODE * currentNFA,int conditionCode){/*if(currentNFA->edge1 != NIL){if(currentNFA->edge1==EPSILON_MATCH_DEGE){//check duplicationif(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next1)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next1);//recursion callGetNextNFANodes(currentDFA,currentNFA->next1,conditionCode);//check stateif(currentNFA->position == ENDPOSITION)currentDFA->position = ENDCOLLECTION;}return;}if(currentNFA->matchArray == conditionCode || conditionCode==currentNFA->edge1){//check duplicaitonif(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next1)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next1);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}return;}}if(currentNFA->edge2 != NIL){if(currentNFA->edge2 == EPSILON_MATCH_DEGE){//ckeck duplicationif(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next2)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next2);//recusrion callGetNextNFANodes(currentDFA,currentNFA->next2,conditionCode);//check stateif(currentNFA->position == ENDPOSITION)currentDFA->position = ENDCOLLECTION;}return;}if(currentNFA->matchArray == conditionCode || conditionCode==currentNFA->edge2){//check duplicationif(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next2)==0){PushNFANodeToDFANode(currentDFA,currentNFA);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}return;}return;}if(currentNFA->edge1 == NIL && currentNFA->edge2 == NIL)return;*/if(currentNFA->edge1 != NIL){if(currentNFA->edge1 == EPSILON_MATCH_DEGE){GetNextNFANodes(currentDFA,currentNFA->next1,conditionCode);}else{if(currentNFA->edge1 == conditionCode)//char collection{if(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next1)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next1);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}}else//single char matching condition{if(currentNFA->matchArray == conditionCode){if(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next1)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next1);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}}}}}if(currentNFA->edge2 != NIL){if(currentNFA->edge2 == EPSILON_MATCH_DEGE){GetNextNFANodes(currentDFA,currentNFA->next2,conditionCode);}else{if(currentNFA->edge2 == conditionCode)//char collection{if(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next2)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next2);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}}else//single char matching condition{if(currentNFA->matchArray == conditionCode){if(CheckRepeatOfNFANode(currentDFA->NFACollection,currentNFA->next2)==0){PushNFANodeToDFANode(currentDFA,currentNFA->next2);currentDFA->matchArray = currentDFA->matchArray | currentNFA->matchArray;}}}}}return;}
特殊应用场景
在NFA构建过程中,会出现如下场景:
这种图形的主要是由于重复匹配引起的(在digitMap规则中,由”.”引起,在正则表达式中则由”*”引起);这种存在环的路线,也可以使用递归;
