Edinburgh Speech Tools 2.4-release
EST_features_io.cc
1/*************************************************************************/
2/* */
3/* Centre for Speech Technology Research */
4/* University of Edinburgh, UK */
5/* Copyright (c) 1998 */
6/* All Rights Reserved. */
7/* */
8/* Permission is hereby granted, free of charge, to use and distribute */
9/* this software and its documentation without restriction, including */
10/* without limitation the rights to use, copy, modify, merge, publish, */
11/* distribute, sublicense, and/or sell copies of this work, and to */
12/* permit persons to whom this work is furnished to do so, subject to */
13/* the following conditions: */
14/* 1. The code must retain the above copyright notice, this list of */
15/* conditions and the following disclaimer. */
16/* 2. Any modifications must be clearly marked as such. */
17/* 3. Original authors' names are not deleted. */
18/* 4. The authors' names are not used to endorse or promote products */
19/* derived from this software without specific prior written */
20/* permission. */
21/* */
22/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30/* THIS SOFTWARE. */
31/* */
32/*************************************************************************/
33/* Author : Alan W Black */
34/* Date : March 1998 */
35/*-----------------------------------------------------------------------*/
36/* Features i/o */
37/* This is kept separate from EST_Features to help reduce dependencies */
38/*=======================================================================*/
39#include <cstdlib>
40#include "EST_Features.h"
41#include "ling_class/EST_Item.h"
42#include "EST_error.h"
43#include "EST_String.h"
44#include "EST_Token.h"
45
47 const EST_String &funcname)
48{
49 EST_Item_featfunc f = get_featfunc(funcname,1);
50
51 set_path(name, est_val(f));
52}
53
54void EST_Features::save_fpair(ostream &outf,
55 const EST_String &fname,
56 const EST_Val &fvalue) const
57{
58 /* Feature valued features themselves (so can't denot empty ones) */
59 if (fvalue.type() == val_type_feats)
60 {
61 EST_Features *f = feats(fvalue);
62 if (f->features->list.head() == 0)
63 {
64 // An empty feature set
65 outf << fname << " () ; ";
66 }
67 else
68 for (EST_Litem *q=f->features->list.head();
69 q != 0; q=q->next() )
70 save_fpair(outf,
71 fname+"."+f->features->list(q).k,
72 f->features->list(q).v);
73 return;
74 }
75 /* a non feature valued one */
76 // in case someone has () in their feature names (ought to be shot)
77 if (fname.contains("(") ||
78 fname.contains(")") ||
79 fname.contains(" ") || // bang, bang
80 fname.contains("\t") || // what smoking gun ?
81 fname.contains(";") ||
82 (fname == ""))
83 outf << quote_string(fname,"\"","\\",1) << " ";
84 else
85 outf << fname << " ";
86 if (fvalue == ";")
87 outf << "\";\"";
88 else if ((fvalue.type() == val_string) &&
89 ((fvalue.string().matches(RXint)) ||
90 (fvalue.string().matches(RXdouble)) ||
91 (fvalue.string().contains("(")) ||
92 (fvalue.string().contains(")")) ||
93 (fvalue.string().contains(";")) ))
94 // force quoting, cause it looks like a number but isn't
95 outf << quote_string(fvalue.string(),"\"","\\",1);
96 else if (fvalue.type() == val_float)
97 {
98 char b[20];
99 sprintf(b,"%g",fvalue.Float());
100 outf << b;
101 }
102 else if (fvalue.type() == val_type_featfunc)
103 {
104 outf << "F:"<<get_featname(featfunc(fvalue));
105 }
106 else
107 outf << quote_string(fvalue.string());
108 outf << " ; ";
109}
110
111EST_write_status EST_Features::save(ostream &outf) const
112{
113 // Save features
114 if (features->list.head() == 0)
115 outf << "()";
116 else
117 for (EST_Litem *p=features->list.head(); p != 0; p=p->next() )
118 save_fpair(outf,
119 features->list(p).k,
120 features->list(p).v);
121
122 return write_ok;
123}
124
125EST_write_status EST_Features::save_sexpr(ostream &outf) const
126{
127 // Save features as an sexpression
128 outf << "(";
129 for (EST_Litem *p=features->list.head(); p != 0; p=p->next() )
130 {
131 const EST_String &fname = features->list(p).k;
132 const EST_Val &fvalue = features->list(p).v;
133 outf << "(";
134 // in case someone has () in their feature names (ought to be shot)
135 if (fname.contains("(") ||
136 fname.contains(")") ||
137 fname.contains(" ") ||
138 fname.contains("\t") ||
139 fname.contains(";"))
140 outf << quote_string(fname,"\"","\\",1);
141 else
142 outf << fname;
143 outf << " ";
144 if (fvalue == ";")
145 outf << "\";\"";
146 else if ((fvalue.type() == val_string) &&
147 ((fvalue.string().matches(RXint)) ||
148 (fvalue.string().matches(RXdouble)) ||
149 (fvalue.string().contains("(")) ||
150 (fvalue.string().contains(")"))))
151 // force quoting, cause it looks like a number but isn't
152 // or contains a paren
153 outf << quote_string(fvalue.string(),"\"","\\",1);
154 else if (fvalue.type() == val_float)
155 {
156 char b[20];
157 sprintf(b,"%g",fvalue.Float());
158 outf << b;
159 }
160 else if (fvalue.type() == val_type_featfunc)
161 {
162 outf << "F:"<<get_featname(featfunc(fvalue));
163 }
164 else if (fvalue.type() == val_type_feats)
165 {
166 feats(fvalue)->save_sexpr(outf);
167 }
168 else
169 outf << quote_string(fvalue.string());
170 outf << ")";
171 if (p->next())
172 outf << " ";
173 }
174 outf << ")";
175
176 return write_ok;
177}
178
180{
181 /* Load in feature structure from sexpression */
182
183 if (ts.peek() != "(")
184 {
185 cerr << "load_features: no sexpression found\n";
186 return misc_read_error;
187 }
188 else
189 {
191 EST_Token v;
192 ts.get(); /* skip opening paren */
193 for (; ts.peek() != ")"; )
194 {
195 if (ts.peek() != "(")
196 {
197 cerr << "load_features: no sexpression found\n";
198 return misc_read_error;
199 }
200 ts.get();
201 f = ts.get().string(); /* feature name */
202 if ((ts.peek() == "(") && (ts.peek().quoted() == FALSE))
203 {
204 EST_Features fv;
205 set(f,fv);
206 A(f).load_sexpr(ts);
207 }
208 else
209 {
210 v = ts.get();
211 if (v.quoted())
212 set(f,v.string());
213 else if (v.string().matches(RXint))
214 set(f,atoi(v.string()));
215 else if (v.string().matches(RXdouble))
216 set(f,atof(v.string()));
217 else if (v.string().contains("F:"))
218 {
219 EST_Item_featfunc func =
220 get_featfunc(v.string().after("F:"));
221 if (func != NULL)
222 set_val(f,est_val(func));
223 else
224 {
225 cerr << "load_features: Unknown Function '" << f <<"'\n";
226 set_val(f,feature_default_value);
227 }
228 }
229 else
230 set(f,v.string());
231
232 }
233 if (ts.get() != ")")
234 {
235 cerr << "load_features: no sexpression found\n";
236 return misc_read_error;
237 }
238 }
239 if (ts.get() != ")")
240 {
241 cerr << "load_features: no sexpression found\n";
242 return misc_read_error;
243 }
244 }
245 return format_ok;
246}
247
249{
250 // load features from here to end of line separated by semicolons
252 EST_Token v;
253 static EST_Val val0 = EST_Val(0);
254
255 while (!ts.eoln())
256 {
257 if (ts.eof())
258 {
259 cerr << "load_features: unexpected end of file\n";
260 return misc_read_error;
261 }
262 f = ts.get().string();
264 while (((ts.peek() != ";") || (ts.peek().quoted())) &&
265 (!ts.eof()) && (!ts.eoln()))
266 if (v == "")
267 v = ts.get();
268 else
269 v = v.string()
270 + ts.peek().whitespace()
271 + ts.get().string();
272 if (v.quoted() || (v.string() == ""))
273 set_path(f,EST_Val(v.string()));
274 else if (v.string() == "0") // very common cases for speed
275 set_path(f,val0);
276 else if ((strchr("0123456789-.",v.string()(0)) != NULL) &&
277 (v.string().matches(RXdouble)))
278 {
279 if (v.string().matches(RXint))
280 set_path(f, EST_Val(atoi(v.string())));
281 else
282 set_path(f, EST_Val(atof(v.string())));
283 }
284 else if (v.string().contains("F:"))
285 {
286 EST_Item_featfunc func = get_featfunc(v.string().after("F:"));
287 if (func != NULL)
288 set_path(f, est_val(func));
289 else
290 {
291 cerr << "load_features: Unknown Function '" << f <<"'\n";
292 set_path(f, feature_default_value);
293 }
294 }
295 else if (v.string() == "()")
296 { // An empty feature set
297 EST_Features *fs = new EST_Features;
298 set_path(f,est_val(fs));
299 }
300 else if (v != "<contents>") // unsupported type
301 set_path(f,EST_Val(v.string()));
302 if (ts.peek() == ";")
303 ts.get();
304 else if (!ts.eoln())
305 {
306 cerr << "load_features: " << ts.pos_description() <<
307 " missing semicolon in feature list\n";
308 return misc_read_error;
309 }
310 }
311 return format_ok;
312}
313
EST_Features & A(const EST_String &path) const
Definition: EST_Features.h:169
void set(const EST_String &name, int ival)
Definition: EST_Features.h:185
void set_path(const EST_String &name, const EST_Val &sval)
void set_function(const EST_String &name, const EST_String &f)
void set_val(const EST_String &name, const EST_Val &sval)
Definition: EST_Features.h:216
EST_read_status load(EST_TokenStream &ts)
load features from already opened EST_TokenStream
EST_read_status load_sexpr(EST_TokenStream &ts)
load features from sexpression, contained in already opened EST_TokenStream
EST_write_status save(ostream &outf) const
save features in already opened ostream
const EST_Val & f(const EST_String &path) const
Definition: EST_Features.h:114
EST_write_status save_sexpr(ostream &outf) const
save features as s-expression in already opened ostream
static const EST_String Empty
Constant empty string.
Definition: EST_String.h:111
int contains(const char *s, int pos=-1) const
Does it contain this substring?
Definition: EST_String.h:375
EST_String after(int pos, int len=1) const
Part after pos+len.
Definition: EST_String.h:318
int matches(const char *e, int pos=0) const
Exactly match this string?
Definition: EST_String.cc:652
EST_TList< EST_TKVI< K, V > > list
Linked list of key-val pairs. Don't use this as it will be made private in the future.
Definition: EST_TKVL.h:93
int eof()
end of file
Definition: EST_Token.h:356
const EST_String pos_description()
A string describing current position, suitable for error messages.
Definition: EST_Token.cc:875
int eoln()
end of line
Definition: EST_Token.cc:818
EST_Token & peek(void)
peek at next token
Definition: EST_Token.cc:830
EST_TokenStream & get(EST_Token &t)
get next token in stream
Definition: EST_Token.cc:486
int quoted() const
TRUE is token was quoted.
Definition: EST_Token.h:169
const EST_String & string(void) const
Definition: EST_Val.h:150
const val_type type(void) const
Definition: EST_Val.h:126
const float Float(void) const
Definition: EST_Val.h:138