10 #ifndef _FLAG_DIACRITICS_H_
11 #define _FLAG_DIACRITICS_H_
27 enum FdOperator {Pop, Nop, Rop, Dop, Cop, Uop};
29 typedef unsigned short FdFeature;
30 typedef short FdValue;
41 (FdOperator op, FdFeature feat, FdValue val,
const std::string& str):
42 op(op), feature(feat), value(val), name(str) {}
44 HFSTDLL FdOperator Operator(
void)
const {
return op; }
45 HFSTDLL FdFeature Feature(
void)
const {
return feature; }
46 HFSTDLL FdValue Value(
void)
const {
return value; }
47 HFSTDLL std::string Name(
void)
const {
return name; }
49 HFSTDLL
static FdOperator char_to_operator(
char c)
63 HFSTDLL
static bool is_diacritic(
const std::string& diacritic_str);
64 HFSTDLL
static std::string::size_type find_diacritic
65 (
const std::string& diacritic_str,
66 std::string::size_type& length);
68 HFSTDLL
static std::string get_operator(
const std::string& diacritic);
69 HFSTDLL
static std::string get_feature(
const std::string& diacritic);
70 HFSTDLL
static std::string get_value(
const std::string& diacritic);
71 HFSTDLL
static bool has_value(
const std::string& diacritic);
74 template<
class T>
class FdState;
84 std::map<std::string, FdFeature> feature_map;
85 std::map<std::string, FdValue> value_map;
87 std::map<T, FdOperation> operations;
88 std::map<std::string, T> symbol_map;
90 FdTable(): feature_map(), value_map()
91 { value_map[std::string()] = 0; }
93 void define_diacritic(T symbol,
const std::string& str)
95 if(!FdOperation::is_diacritic(str))
98 FdOperator op = FdOperation::char_to_operator(str.at(1));
103 size_t first_full_stop_pos = 2;
105 size_t second_full_stop_pos = str.find(
'.',first_full_stop_pos+1);
106 size_t last_char_pos = str.size() - 1;
107 if(second_full_stop_pos == std::string::npos)
109 assert(op == Cop || op == Dop || op == Rop);
110 feat = str.substr(first_full_stop_pos+1,
111 last_char_pos-first_full_stop_pos-1);
115 feat = str.substr(first_full_stop_pos+1,
116 second_full_stop_pos-first_full_stop_pos-1);
117 val = str.substr(second_full_stop_pos+1,
118 last_char_pos-second_full_stop_pos-1);
121 if(feature_map.count(feat) == 0)
123 FdFeature next = feature_map.size();
124 feature_map[feat] = next;
126 if(value_map.count(val) == 0)
128 FdValue next = value_map.size()+1;
129 value_map[val] = next;
133 (std::pair<T,FdOperation>
135 FdOperation(op, feature_map[feat], value_map[val], str)));
136 symbol_map.insert(std::pair<std::string,T>(str, symbol));
139 FdFeature num_features()
const {
return feature_map.size(); }
140 bool is_diacritic(T symbol)
const
141 {
return operations.find(symbol) != operations.end(); }
143 const FdOperation* get_operation(T symbol)
const
150 return (operations.find(symbol)==operations.end()) ? NULL :
151 &(operations.find(symbol)->second);
153 const FdOperation* get_operation(
const std::string& symbol)
const
155 return (symbol_map.find(symbol)==symbol_map.end()) ? NULL :
156 get_operation(symbol_map.find(symbol)->second);
159 bool is_valid_string(
const std::vector<T>& symbols)
const
161 FdState<T> state(*
this);
163 for(
size_t i=0; i<symbols.size(); i++)
165 if(!state.apply_operation(symbols[i]))
168 return !state.fails();
171 bool is_valid_string(
const std::string& str)
const
173 FdState<T> state(*
this);
174 std::string remaining(str);
175 std::string::size_type length;
179 std::string::size_type next_diacritic_pos
180 = FdOperation::find_diacritic(remaining, length);
181 if(next_diacritic_pos == std::string::npos)
184 std::string diacritic = remaining.substr(0, length);
185 if(!state.apply_operation(diacritic))
187 remaining = remaining.substr(length);
189 return !state.fails();
200 const FdTable<T>* table;
203 typename std::vector<FdValue> values;
208 FdState(
const FdTable<T>& t):
209 table(&t), values(table->num_features()),
210 num_features(table->num_features()), error_flag(false)
214 table(NULL), values(), num_features(0), error_flag(false)
217 const FdTable<T>& get_table()
const {
return *table;}
219 const std::vector<FdValue> & get_values(
void)
const
222 void assign_values(std::vector<FdValue>
const & vals)
225 if (values.size() != num_features) {
230 bool apply_operation(T symbol)
232 const FdOperation* op = table->get_operation(symbol);
234 return apply_operation(*op);
237 bool apply_operation(
const FdOperation& op)
239 switch(op.Operator()) {
241 values[op.Feature()] = op.Value();
245 values[op.Feature()] = -1*op.Value();
250 return (values[op.Feature()] != 0);
252 return (values[op.Feature()] == op.Value());
256 return (values[op.Feature()] == 0);
258 return (values[op.Feature()] != op.Value());
261 values[op.Feature()] = 0;
265 if(values[op.Feature()] == 0 ||
266 values[op.Feature()] == op.Value() ||
269 (values[op.Feature()] < 0 &&
270 (values[op.Feature()]*(-1) != op.Value()))
276 values[op.Feature()] = op.Value();
283 bool apply_operation(
const std::string& symbol)
285 const FdOperation* op = table->get_operation(symbol);
287 return apply_operation(*op);
291 bool fails()
const {
return error_flag;}
296 values.insert(values.begin(), table->num_features(), 0);