■
昨日の続き。
NFAのdtransからdnodeへの変換は以下のようにした
void NfaClass::setTransToNode() { for (int i=0; i<ntransNum; i++) { int from = ntrans[i]->from; if (nnode[from] != NULL) { // create new Nnode, and set to next link of nnode[i]. Nnode* newNode = new Nnode(); newNode->ch = ntrans[i]->ch; newNode->to = ntrans[i]->to; newNode->next = nnode[from]; nnode[from] = newNode; } else { // create new nnode[i] nnode[from] = new Nnode(); nnode[from]->ch = ntrans[i]->ch; nnode[from]->to = ntrans[i]->to; nnode[from]->next = NULL; nnodeNum++; if (from > nnodeMaxNum) nnodeMaxNum = from; } } }
この場合だとnnodeの配列は歯抜けになる。連結リストで書けばいいのだろうけど、ちょっと混乱しそうなのでとりあえずこのまま。
後はDFAへの変換だけど、これはちょっと書いてて混乱。前回考えたアルゴリズムが不味い。dfa.hは今の所以下のような感じ
#ifndef _DFA_INCLUDE_CHECK #define _DFA_INCLUDE_CHECK #include <iostream> #include "nfa.h" #define tr_ch e.transition.ch #define tr_sib e.transition.sibling #define tr_next e.transition.next const int DFA_MAX = 128; enum dfaOp_t { e_node, e_transition } struct Dtrans { int nnode_no; Dtrans* next; }; struct Dnode { dfaOp_t op; // op_t represent the two statement as node or transition. union Entity { Dnode* sibling; // when op is "node" struct { // when op is "transition" char ch; Dnode* sibling; // If other charcter exist in this node, it is linked at sibling. Dnode* next; // } transition; } e; }; class DfaClass { Dtrans* dtrans[DFA_MAX]; Dnode* dnode[DFA_MAX]; dfaInitail(); dfaIter(NfaClass& nfa); public: DfaClass(NfaClass& nfa) { dfaInitial(); dfaIter(nfa); } ~DfaClass() {} }; #endif _DFA_INCLUDE_CHECK