1 #ifndef _FLAG_DIACRITICS_H_
2 #define _FLAG_DIACRITICS_H_
16 enum FdOperator {Pop, Nop, Rop, Dop, Cop, Uop};
18 typedef unsigned short FdFeature;
19 typedef short FdValue;
30 (FdOperator op, FdFeature feat, FdValue val,
const std::string& str):
31 op(op), feature(feat), value(val), name(str) {}
33 FdOperator Operator(
void)
const {
return op; }
34 FdFeature Feature(
void)
const {
return feature; }
35 FdValue Value(
void)
const {
return value; }
36 std::string Name(
void)
const {
return name; }
38 static FdOperator char_to_operator(
char c)
52 static bool is_diacritic(
const std::string& diacritic_str);
53 static std::string::size_type find_diacritic
54 (
const std::string& diacritic_str,
55 std::string::size_type& length);
57 static std::string get_operator(
const std::string& diacritic);
58 static std::string get_feature(
const std::string& diacritic);
59 static std::string get_value(
const std::string& diacritic);
60 static bool has_value(
const std::string& diacritic);
63 template<
class T>
class FdState;
73 std::map<std::string, FdFeature> feature_map;
74 std::map<std::string, FdValue> value_map;
76 std::map<T, FdOperation> operations;
77 std::map<std::string, T> symbol_map;
79 FdTable(): feature_map(), value_map()
80 { value_map[std::string()] = 0; }
82 void define_diacritic(T symbol,
const std::string& str)
84 if(!FdOperation::is_diacritic(str))
87 FdOperator op = FdOperation::char_to_operator(str.at(1));
92 size_t first_full_stop_pos = 2;
94 size_t second_full_stop_pos = str.find(
'.',first_full_stop_pos+1);
95 size_t last_char_pos = str.size() - 1;
96 if(second_full_stop_pos == std::string::npos)
98 assert(op == Cop || op == Dop || op == Rop);
99 feat = str.substr(first_full_stop_pos+1,
100 last_char_pos-first_full_stop_pos-1);
104 feat = str.substr(first_full_stop_pos+1,
105 second_full_stop_pos-first_full_stop_pos-1);
106 val = str.substr(second_full_stop_pos+1,
107 last_char_pos-second_full_stop_pos-1);
110 if(feature_map.count(feat) == 0)
112 FdFeature next = feature_map.size();
113 feature_map[feat] = next;
115 if(value_map.count(val) == 0)
117 FdValue next = value_map.size()+1;
118 value_map[val] = next;
122 (std::pair<T,FdOperation>
124 FdOperation(op, feature_map[feat], value_map[val], str)));
125 symbol_map.insert(std::pair<std::string,T>(str, symbol));
128 FdFeature num_features()
const {
return feature_map.size(); }
129 bool is_diacritic(T symbol)
const
130 {
return operations.find(symbol) != operations.end(); }
132 const FdOperation* get_operation(T symbol)
const
139 return (operations.find(symbol)==operations.end()) ? NULL :
140 &(operations.find(symbol)->second);
142 const FdOperation* get_operation(
const std::string& symbol)
const
144 return (symbol_map.find(symbol)==symbol_map.end()) ? NULL :
145 get_operation(symbol_map.find(symbol)->second);
148 bool is_valid_string(
const std::vector<T>& symbols)
const
150 FdState<T> state(*
this);
152 for(
size_t i=0; i<symbols.size(); i++)
154 if(!state.apply_operation(symbols[i]))
157 return !state.fails();
160 bool is_valid_string(
const std::string& str)
const
162 FdState<T> state(*
this);
163 std::string remaining(str);
164 std::string::size_type length;
168 std::string::size_type next_diacritic_pos
169 = FdOperation::find_diacritic(remaining, length);
170 if(next_diacritic_pos == std::string::npos)
173 std::string diacritic = remaining.substr(0, length);
174 if(!state.apply_operation(diacritic))
176 remaining = remaining.substr(length);
178 return !state.fails();
189 const FdTable<T>* table;
192 typename std::vector<FdValue> values;
197 FdState(
const FdTable<T>& t):
198 table(&t), values(table->num_features()),
199 num_features(table->num_features()), error_flag(false)
203 table(NULL), values(), num_features(0), error_flag(false)
206 const FdTable<T>& get_table()
const {
return *table;}
208 const std::vector<FdValue> & get_values(
void)
const
211 void assign_values(std::vector<FdValue>
const & vals)
214 if (values.size() != num_features) {
219 bool apply_operation(T symbol)
221 const FdOperation* op = table->get_operation(symbol);
223 return apply_operation(*op);
226 bool apply_operation(
const FdOperation& op)
228 switch(op.Operator()) {
230 values[op.Feature()] = op.Value();
234 values[op.Feature()] = -1*op.Value();
239 return (values[op.Feature()] != 0);
241 return (values[op.Feature()] == op.Value());
245 return (values[op.Feature()] == 0);
247 return (values[op.Feature()] != op.Value());
250 values[op.Feature()] = 0;
254 if(values[op.Feature()] == 0 ||
255 values[op.Feature()] == op.Value() ||
258 (values[op.Feature()] < 0 &&
259 (values[op.Feature()]*(-1) != op.Value()))
265 values[op.Feature()] = op.Value();
272 bool apply_operation(
const std::string& symbol)
274 const FdOperation* op = table->get_operation(symbol);
276 return apply_operation(*op);
280 bool fails()
const {
return error_flag;}
285 values.insert(values.begin(), table->num_features(), 0);