#ifndef PHRASETABLE_H #define PHRASETABLE_H struct PgfConcrLin; struct PgfConcrLincat; struct PGF_INTERNAL_DECL PgfTextSpot { size_t pos; // position in Unicode characters size_t byte_pos; // position in number of bytes }; struct PGF_INTERNAL_DECL PgfItem { PgfMetaId res; struct { size_t &operator[](int i) { PgfItem *item = containerof(PgfItem,vars,this); return ((size_t*) (((PgfMetaId*) (item+1))+item->rule->args.size()))[i]; } size_t size() { PgfItem *item = containerof(PgfItem,vars,this); return (item->rule->ranges != 0) ? item->rule->ranges.size() : 0; } } vars; struct { PgfMetaId &operator[](int i) { PgfItem *item = containerof(PgfItem,args,this); return ((PgfMetaId*) (item+1))[i]; } size_t size() { PgfItem *item = containerof(PgfItem,args,this); return item->rule->args.size(); } } args; static void release(ref item) { size_t ex_size = sizeof(PgfMetaId) * item->args.size() + sizeof(size_t) * item->vars.size(); PgfDB::free(item, ex_size); } uint16_t pre_alt; uint16_t pre_dot; uint16_t dot; ref rule; }; struct PGF_INTERNAL_DECL PgfCCat { ref lincat; PgfMetaId prev_fid, fid; interval_t value, lin_idx; prob_t viterbi_prob; // Here n_items tells us how many actual items there are in // the vector items. On the other hand, items.size() tells us // how big buffer we have allocated. size_t n_items; vector> items; }; template struct PGF_INTERNAL_DECL PgfPhrasetableValue { ref key; // Here n_items tells us how many actual items there are in // the vector items. On the other hand, items.size() tells us // how big buffer we have allocated. size_t n_items; vector> items; }; template using PgfPhrasetable = ref>>; template PGF_INTERNAL_DECL PgfPhrasetable phrasetable_insert(PgfPhrasetable table, ref key, ref item); template PGF_INTERNAL_DECL vector> phrasetable_lookup(PgfPhrasetable phrasetable, ref key, size_t *n_items); class PGF_INTERNAL_DECL PgfPhraseScanner { public: virtual void space(PgfTextSpot *start, PgfTextSpot *end, PgfExn* err)=0; virtual void start_matches(PgfTextSpot *spot, PgfExn* err)=0; virtual void match(ref lin, size_t lin_idx, PgfExn* err)=0; virtual void end_matches(PgfTextSpot *spot, PgfExn* err)=0; }; PGF_INTERNAL_DECL void phrasetable_lookup(PgfPhrasetable phrasetable, PgfText *sentence, bool case_sensitive, PgfPhraseScanner *scanner, PgfExn* err); PGF_INTERNAL_DECL void phrasetable_lookup_cohorts(PgfPhrasetable phrasetable, PgfText *sentence, bool case_sensitive, PgfPhraseScanner *scanner, PgfExn* err); template void phrasetable_release(PgfPhrasetable table) { if (table == 0) return; phrasetable_release(table->left); phrasetable_release(table->right); for (size_t i = 0; i < table->value.n_items; i++) { PgfItem::release(table->value.items[i]); } vector>::release(table->value.items); Node>::release(table); } typedef ref> PgfEpsilontable; // Creates a new epsilon category with its first item. // The new category is mutable within the current transaction PGF_INTERNAL_DECL PgfEpsilontable epsilontable_insert(PgfEpsilontable table, ref lincat, PgfMetaId prev_fid, interval_t value, interval_t lin_idx, PgfMetaId fid, prob_t viterbi_prob, ref item, ref *pepsilon); // Adds a new item to an existing epsilon category. The category // must have been created by epsilontable_insert in the current transaction. PGF_INTERNAL_DECL void epsilontable_add(ref epsilon, ref item); PGF_INTERNAL_DECL ref epsilontable_get(PgfEpsilontable table, PgfText *name, PgfMetaId fid); PGF_INTERNAL void epsilontable_iter(PgfEpsilontable table, ref lincat, PgfMetaId prev_fid, std::function arg)> &f); PGF_INTERNAL_DECL void epsilontable_release(PgfEpsilontable table); #endif