00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef ASTL_STREAM_H
00023 #define ASTL_STREAM_H
00024
00025 #include <astl.h>
00026 #include <iostream>
00027 #include <set>
00028 #include <map>
00029 #include <stack>
00030 #include <utility>
00031
00032 using namespace std;
00033
00034 #if (__GNUG__ && __GNUG__ > 2)
00035 using namespace rel_ops;
00036 #endif
00037
00038 namespace astl {
00039
00040 template <typename Tag = empty>
00041 class DFA_stream
00042 {
00043 public:
00044 typedef Tag tag_type;
00045 typedef int state_type;
00046 typedef state_type State;
00047 struct bool_reference;
00048 friend struct bool_reference;
00049
00050 protected:
00051 ostream &out;
00052 set<state_type> F;
00053 state_type count;
00054 map<state_type, tag_type> T;
00055
00056 public:
00057 static const state_type null_state = 0;
00058
00059 DFA_stream(ostream &output)
00060 : out(output), count(0)
00061 { }
00062
00063 state_type new_state() { return ++count; }
00064
00065 tag_type& tag(state_type q) { return tag_(q, tag_type()); }
00066
00067 struct bool_reference
00068 {
00069 state_type q;
00070 DFA_stream &dfa;
00071
00072 bool_reference(state_type p, DFA_stream &a)
00073 : q(p), dfa(a)
00074 { }
00075
00076 bool_reference& operator=(bool b) {
00077 if (b == true) dfa.F.insert(q);
00078 else dfa.F.erase(q);
00079 return *this;
00080 }
00081 };
00082
00083 bool_reference final(state_type q) {
00084 return bool_reference(q, *this);
00085 }
00086
00087 template <typename Alphabet>
00088 void set_trans(state_type q, const Alphabet &a, state_type p) {
00089 write_state(q);
00090 out << '\t' << a << '\t';
00091 write_state(p);
00092 write_tag(q);
00093 write_tag(p);
00094 out << endl;
00095 }
00096
00097 void set_trans(state_type q, const char& a, state_type p) {
00098 set_trans(q, (int) a, p);
00099 }
00100
00101 void set_trans(state_type q, const unsigned char& a, state_type p) {
00102 set_trans(q, (int) a, p);
00103 }
00104
00105 void set_trans(state_type q, const string& a, state_type p) {
00106 write_state(q);
00107 out << "\t\"" << a << "\"\t";
00108 write_state(p);
00109 write_tag(q);
00110 write_tag(p);
00111 out << endl;
00112 }
00113
00114 protected:
00115 template <typename TagType>
00116 tag_type& tag_(state_type q, const TagType&) {
00117 return T[q];
00118 }
00119
00120 tag_type& tag_(state_type, const empty&) {
00121 static tag_type bogus;
00122 return bogus;
00123 }
00124
00125 void write_state(state_type q) {
00126
00127 out << (F.find(q) != F.end() ? -q : q);
00128 }
00129
00130 void write_tag(state_type q) {
00131 write_tag(q, tag_type());
00132 }
00133
00134 template <typename TagType>
00135 void write_tag(state_type q, const TagType&)
00136 {
00137
00138 typename map<state_type, tag_type>::iterator i = T.find(q);
00139 if (i != T.end()) {
00140 out << '\t' << i->second;
00141 T.erase(i);
00142 }
00143 }
00144
00145 void write_tag(state_type q, const string&)
00146 {
00147
00148 typename map<state_type, tag_type>::iterator i = T.find(q);
00149 if (i != T.end()) {
00150 out << "\t\"" << i->second << '"';
00151 T.erase(i);
00152 }
00153 }
00154
00155
00156 void write_tag(state_type, const empty&)
00157 { }
00158 };
00159
00160 template <typename Tag>
00161 const typename DFA_stream<Tag>::state_type DFA_stream<Tag>::null_state;
00162
00163 template <typename DFirstC>
00164 inline
00165 ostream& dump(ostream &out, DFirstC first, DFirstC last = DFirstC())
00166 {
00167 DFA_stream<> output(out);
00168 clone(output, first);
00169 return out;
00170 }
00171
00172 template <typename DFirstCursor>
00173 inline
00174 ostream& full_dump(ostream &out, DFirstCursor first, DFirstCursor last = DFirstCursor())
00175 {
00176 DFA_stream<typename DFirstCursor::tag_type> output(out);
00177 clone(output, first);
00178 return out;
00179 }
00180
00181 template <typename CharType>
00182 struct read_char : public binary_function<istream, CharType, void>
00183 {
00184 void operator()(istream &in, CharType& x) const {
00185 in >> x;
00186 }
00187 };
00188
00189 template < >
00190 struct read_char<unsigned char>
00191 : public binary_function<istream, unsigned char, void>
00192 {
00193 void operator()(istream &in, unsigned char& x) const {
00194 int tmp;
00195 in >> tmp;
00196 x = (unsigned char) tmp;
00197 }
00198 };
00199
00200 template < >
00201 struct read_char<char>
00202 : public binary_function<istream, char, void>
00203 {
00204 void operator()(istream &in, char& x) const {
00205 int tmp;
00206 in >> tmp;
00207 x = (char) tmp;
00208 }
00209 };
00210
00211 template < >
00212 struct read_char<string>
00213 : public binary_function<istream, string, void>
00214 {
00215 void operator()(istream &in, string& x) const {
00216 x.erase(x.begin(), x.end());
00217 char c;
00218 for(c = '\0'; c != '"'; in.get(c));
00219 for(in.get(c); c != '"'; in.get(c))
00220 x += c;
00221 }
00222 };
00223
00224 template <typename FA>
00225 class istream_cursor : public dfirst_cursor_concept
00226 {
00227 public:
00228 typedef typename FA::char_traits char_traits;
00229 typedef typename char_traits::char_type char_type;
00230 typedef int state_type;
00231 typedef typename FA::tag_type tag_type;
00232 typedef istream_cursor<FA> self;
00233
00234 istream_cursor()
00235 : in(cin)
00236 { }
00237
00238 istream_cursor(istream &input)
00239 : in(input), has_poped(false) {
00240 forward();
00241 }
00242
00243 state_type src() const { return s.top().q; }
00244 state_type aim() const { return s.top().p; }
00245
00246 bool operator==(const self &x) const {
00247 return s == x.s;
00248 }
00249
00250 bool operator!= (const self &x) const { return !(*this == x); }
00251
00252 bool src_final() const { return s.top().q < 0; }
00253 bool aim_final() const { return s.top().p < 0; }
00254
00255 char_type letter() const { return s.top().a; }
00256
00257 bool forward()
00258 {
00259 if (in.eof()) {
00260 if (!s.empty()) s.pop();
00261 return s.empty();
00262 }
00263
00264 if (has_poped) {
00265 if (s.top().q == t.q) {
00266 s.top() = t;
00267 has_poped = false;
00268 }
00269 else
00270 s.pop();
00271 }
00272 else {
00273 in >> t.q;
00274 #if defined(__GNUG__) && __GNUG__ >= 3
00275 if (in.eof())
00276 return false;
00277 #endif
00278 read_char<char_type>()(in, t.a);
00279 in >> t.p;
00280 if (s.empty() || s.top().p == t.q) {
00281 read_tag(t.q, tag_type());
00282 read_tag(t.p, tag_type());
00283 s.push(t);
00284 }
00285 else
00286 has_poped = true;
00287 }
00288 return !has_poped;
00289 }
00290
00291 tag_type src_tag() { return T[s.top().q]; }
00292 tag_type aim_tag() { return T[s.top().p]; }
00293
00294 protected:
00295 struct transition
00296 {
00297 state_type q, p;
00298 char_type a;
00299 bool operator==(const transition &x) const {
00300 return q == x.q && p == x.p && a == x.a;
00301 }
00302 };
00303
00304 istream ∈
00305 stack<transition> s;
00306 transition t;
00307 bool has_poped;
00308 mutable map<state_type, tag_type> T;
00309
00310 template <typename TagType>
00311 void read_tag(state_type q, const TagType&) {
00312 if (T.find(q) == T.end()) {
00313 tag_type tmp;
00314 read_char<tag_type>()(in, tmp);
00315 T.insert(make_pair(q, tmp));
00316 }
00317 }
00318
00319 void read_tag(state_type, const empty&)
00320 { }
00321 };
00322
00323 template <typename FA>
00324 inline
00325 istream_cursor<FA> istreamc(istream &in, const FA&)
00326 {
00327 return istream_cursor<FA>(in);
00328 }
00329
00330 template <typename DFA>
00331 inline
00332 void restore(DFA &a, istream &in)
00333 {
00334 a.initial(clone(a, istreamc(in, a)));
00335 }
00336
00479 }
00480
00481 #endif // ASTL_STREAM_ALGORITHMS