Transducer.h
2.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*******************************************************************/
/* */
/* File: Transducer.h */
/* Author: Helmut Schmid */
/* */
/*******************************************************************/
#include <stdio.h>
#include <vector>
class Transition {
public:
char lower;
char upper;
int target;
Transition( char l, char u, size_t t ) { lower = l; upper = u; target = t; };
};
class State {
public:
bool final;
vector<Transition> transition;
State() { final = false; };
};
class Transducer {
private:
vector<State> state;
void analyze1( int sn, const char *s, vector<char> &ana,
vector<vector<char> > &analyses )
{
if (*s == 0 && state[sn].final)
analyses.push_back( ana );
vector<Transition> &t=state[sn].transition;
for( size_t i=0; i<t.size(); i++ ) {
if (t[i].upper == 0) {
ana.push_back(t[i].lower);
analyze1( t[i].target, s, ana, analyses);
ana.pop_back();
}
else if (t[i].upper == *s) {
ana.push_back(t[i].lower);
analyze1( t[i].target, s+1, ana, analyses);
ana.pop_back();
}
}
}
public:
Transducer( FILE *file ) {
char buffer[1000];
for( unsigned int line=0; (fgets(buffer, 1000, file)); line++ ) {
int s, t;
char u, l;
if (sscanf( buffer, "final: %d", &s) == 1) {
if (s >= (int)state.size())
state.resize( s+1 );
state[s].final = true;
}
else if (sscanf( buffer, "%d %c:<> %d", &s, &l, &t) == 3) {
if (s >= (int)state.size())
state.resize( s+1 );
state[s].transition.push_back(Transition(l, 0, t));
}
else if (sscanf( buffer, "%d <>:%c %d", &s, &u, &t) == 3) {
if (s >= (int)state.size())
state.resize( s+1 );
state[s].transition.push_back(Transition(0, u, t));
}
else if (sscanf( buffer, "%d %c:%c %d", &s, &l, &u, &t) == 4) {
if (s >= (int)state.size())
state.resize( s+1 );
state[s].transition.push_back(Transition(l, u, t));
}
else if (sscanf( buffer, "%d %c %d", &s, &l, &t) == 3) {
if (s >= (int)state.size())
state.resize( s+1 );
state[s].transition.push_back(Transition(l, l, t));
}
else {
fprintf(stderr,"Error: in line %u of transducer file at: %s\n",
line, buffer);
exit(1);
}
}
}
void analyze( const char *s, vector<vector<char> > &analyses ) {
vector<char> ana;
analyze1( 0, s, ana, analyses );
}
};