00001
00002 #include <algorithm>
00003
00004 #include "fsm.h"
00005 #include "ntostr.h"
00006
00007 #include "mkdfa.h"
00008
00009 DfaMaker::DfaMaker(const Fsm& fsm, ostream* debug): fsm_(fsm), debug_(debug) {
00010 }
00011
00012 Fsm::STATES&
00013 DfaMaker::closure(Fsm::STATES& s) const {
00014
00015
00016
00017
00018 int n_added(0);
00019
00020
00021
00022 do {
00023
00024 unsigned int old_size = s.size();
00025
00026 for (Fsm::STATES::const_iterator q = s.begin(); q != s.end(); ++q ) {
00027
00028 const Fsm::STATES& target = fsm_.delta(*q, Fsm::epsilon() );
00029 s.insert(target.begin(), target.end());
00030 }
00031
00032
00033
00034 n_added = ( s.size() - old_size );
00035 }
00036 while (n_added);
00037
00038 return s;
00039 }
00040
00041 Fsm::STATES&
00042 DfaMaker::delta(const Fsm::STATES& Q, const Fsm::Symbol& a, Fsm::STATES& R) {
00043
00044 R.clear();
00045 for (Fsm::STATES::const_iterator q = Q.begin(); q != Q.end(); ++q ) {
00046 const Fsm::STATES& r(fsm_.delta(*q,a));
00047 R.insert(r.begin(),r.end());
00048 }
00049 return R;
00050 }
00051
00052 bool
00053 DfaMaker::is_final(const Fsm::STATES& Q) const {
00054
00055
00056 for (Fsm::STATES::const_iterator q = Q.begin(); q != Q.end(); ++q )
00057 if (fsm_.is_final(*q))
00058 return true;
00059 return false;
00060 }
00061
00062 Fsm::State
00063 DfaMaker::mkstate(int i) {
00064
00065 static const string q("q");
00066 return q + ntostr(i);
00067 }
00068
00069 ref<Fsm>
00070 DfaMaker::mkdfa() {
00071
00072
00073
00074 typedef vector<Fsm::STATES> CLOSURES;
00075
00076
00077
00078
00079
00080
00081
00082 CLOSURES closures_;
00083
00084
00085
00086
00087 Fsm::STATES initial_state;
00088 initial_state.insert(fsm_.initial_state());
00089 closures_.push_back(closure(initial_state));
00090
00091
00092
00093 ref<Fsm> dfsm = Fsm::create(mkstate(0));
00094
00095 Fsm::STATES R;
00096
00097
00098
00099
00100 for (unsigned int i=0; i < closures_.size(); ++i)
00101
00102
00103
00104 for (Fsm::SYMBOLS::const_iterator a = fsm_.abegin(); a != fsm_.aend(); ++a )
00105 if (*a != Fsm::epsilon()) {
00106
00107 delta(closures_[i], *a, R);
00108 closure(R);
00109
00110
00111 CLOSURES::const_iterator r(find(closures_.begin(), closures_.end(), R));
00112
00113 int j;
00114
00115 if (r == closures_.end()) {
00116 closures_.push_back(R);
00117 j = closures_.size() -1;
00118 }
00119 else
00120 j = r - closures_.begin();
00121
00122
00123 dfsm->add_transition(mkstate(i), *a, mkstate(j) );
00124 }
00125
00126
00127 for (unsigned int i=0; i < closures_.size(); ++i)
00128 if (is_final(closures_[i]))
00129 dfsm->add_final_state(mkstate(i));
00130
00131 if (debug_)
00132 for (unsigned int i=0; i < closures_.size(); ++i)
00133 *debug_ << mkstate(i) << " = " << closures_[i] << "\n";
00134
00135 return dfsm;
00136 }
00137