46 #include "EST_cutils.h"
49 static LISP find_rewrites(LISP rules, LISP terms, LISP nonterms);
50 static LISP rg_find_nt_ts(LISP rules,LISP sets);
51 static LISP prod_join(LISP n, LISP p);
52 static int production_index(LISP state,
56 void rgcompile(LISP rg,
EST_WFST &all_wfst)
59 LISP nt_ts,nonterms,terms,rewrites;
60 LISP sets=siod_nth(2,rg);
61 LISP rules=siod_nth(3,rg);
63 nt_ts = rg_find_nt_ts(rules,sets);
64 nonterms = car(nt_ts);
67 rewrites = find_rewrites(rules,terms,nonterms);
72 all_wfst.build_from_rg(terms,terms,
79 static LISP find_rewrites(LISP rules, LISP terms, LISP nonterms)
88 for (nt=nonterms; nt != NIL; nt=cdr(nt))
91 for (r=rules; r != NIL; r=cdr(r))
92 if (car(car(r)) == car(nt))
93 nn = cons(cdr(cdr(car(r))),nn);
94 rewrites = cons(cons(car(nt),nn),rewrites);
100 static LISP rg_find_nt_ts(LISP rules,LISP sets)
103 LISP terms=NIL,nonterms=NIL,r,s,
set,t;
105 for (r=rules; r != NIL; r=cdr(r))
106 if (!siod_member_str(get_c_string(car(car(r))),nonterms))
107 nonterms = cons(car(car(r)),nonterms);
109 for (r=rules; r != NIL; r=cdr(r))
110 for (s=cdr(cdr(car(r))); s != NIL; s=cdr(s))
111 if ((!siod_member_str(get_c_string(car(s)),terms)) &&
112 (!siod_member_str(get_c_string(car(s)),nonterms)) &&
113 (!siod_assoc_str(get_c_string(car(s)),sets)))
114 terms = cons(car(s),terms);
115 else if ((
set=siod_assoc_str(get_c_string(car(s)),sets)))
117 for (t=cdr(
set); t != 0; t=cdr(t))
118 if (!siod_member_str(get_c_string(car(t)),terms))
119 terms = cons(car(t),terms);
122 return cons(nonterms,terms);
126 void EST_WFST::build_from_rg(LISP inalpha, LISP outalpha,
127 LISP distinguished, LISP rewrites,
128 LISP sets, LISP terms,
134 LISP current, start_state, remainder,
set, new_prod;
135 int ns, current_state;
136 const char *current_sym;
143 init(inalpha,outalpha);
148 p_start_state =
add_state(wfst_nonfinal);
149 start_state = cons(flocons((
double)p_start_state),
150 cons(distinguished,NIL));
152 production_index(start_state,index,p_start_state);
154 agenda = cons(start_state,agenda);
156 while (agenda != NIL)
158 current = car(agenda);
159 agenda = cdr(agenda);
160 current_state = get_c_int(car(current));
161 current_sym = get_c_string(car(cdr(current)));
162 remainder = cdr(cdr(current));
164 cout << summary() <<
" Agenda " << siod_llength(agenda) << endl;
167 if ((
set=siod_assoc_str(current_sym,sets)))
169 ns = production_index(remainder,index,p_num_states);
171 for (LISP s=cdr(
set); s != NIL; s=cdr(s))
172 p_states[current_state]
173 ->add_transition(0.0,
175 p_in_symbols.
name(get_c_string(car(s))),
176 p_out_symbols.
name(get_c_string(car(s))));
177 if (remainder == NIL)
179 else if (ns == p_num_states)
182 agenda = cons(cons(flocons(ns),remainder),agenda);
185 else if (siod_member_str(current_sym,terms))
187 ns = production_index(remainder,index,p_num_states);
189 p_states[current_state]
190 ->add_transition(0.0,
192 p_in_symbols.
name(current_sym),
193 p_out_symbols.
name(current_sym));
194 if (remainder == NIL)
196 else if (ns == p_num_states)
199 agenda = cons(cons(flocons(ns),remainder),agenda);
204 for (LISP p=cdr(siod_assoc_str(current_sym,rewrites));
208 new_prod = prod_join(car(p),remainder);
209 ns = production_index(new_prod,index,p_num_states);
210 p_states[current_state]
211 ->add_transition(0.0,
212 ns,i_epsilon,o_epsilon);
213 if (ns == p_num_states)
220 agenda = cons(cons(flocons(ns),new_prod),agenda);
228 static int production_index(LISP state,
239 for (p=state; p != NIL; p = cdr(p))
240 istring +=
EST_String(get_c_string(car(p))) +
" ";
244 for (p=state; p != NIL; p = cdr(p))
245 istring +=
EST_String(get_c_string(car(p))) +
" ";
247 ns = index.
val(istring,found);
258 static LISP prod_join(LISP n, LISP p)
263 return cons(car(n),prod_join(cdr(n),p));