void WordTag::find_matches(int w, const char* C, char dir, std::vector<PositionConnector*>& matches) { // cout << "Look connection on: ." << _word << ". ." << w << ". " << C << dir << endl; Connector search_cntr; init_connector(&search_cntr); search_cntr.label = NORMAL_LABEL; search_cntr.priority = THIN_priority; search_cntr.string = C; set_connector_length_limit(&search_cntr); std::vector<PositionConnector>* connectors; switch(dir) { case '+': connectors = &_left_connectors; break; case '-': connectors = &_right_connectors; break; default: throw std::string("Unknown connector direction: ") + dir; } bool conjunction = sentence_contains_conjunction(_sent); std::vector<PositionConnector>::iterator i; for (i = connectors->begin(); i != connectors->end(); i++) { if (WordTag::match(w, search_cntr, dir, (*i).word, *((*i).connector), conjunction)) { matches.push_back(&(*i)); } } }
int main (int argc, char *argv[]) { client_shutdown = 0; init_friend_name_addr();//must be init first,load friend name reflects to address from file init_connector(&connectors); init_socket(); init_show(); init_file_trans_control(); while(!client_shutdown){ input(); } shutdown(listen_socket_fd, SHUT_RDWR); close(listen_socket_fd); destroy_friend_name_addr(&name_address); close_all_connector(&connectors);//talk_thread can't be closed by themself because recv is blocking while (connector_length(&connectors)){//wait for thread free usleep(50); } destroy_connector(&connectors); destroy_file_trans_control(file_trans_control); destroy_show_tty(); sleep(1);//wait for other thread exit,not necssary but that can make it easy for valbrind check memory leak (include still reachable) return 0; }//end main-function
/** * Mark as dead all of the dir-pointing connectors * in e that are not matched by anything in the current set. * Returns the number of connectors so marked. */ static int mark_dead_connectors(connector_table *ct, Exp * e, char dir) { int count; count = 0; if (e->type == CONNECTOR_type) { if (e->dir == dir) { Connector dummy; init_connector(&dummy); dummy.string = e->u.string; if (!matches_S(ct, &dummy)) { e->u.string = NULL; count++; } } } else { E_list *l; for (l = e->u.l; l != NULL; l = l->next) { count += mark_dead_connectors(ct, l->e, dir); } } return count; }
static Disjunct * glom_comma_connector(Disjunct * d) { /* In this case the connector is to connect to the comma to the left of an "and" or an "or". Only gets added next to a fat link */ Disjunct * d_list, * d1, * d2; Connector * c, * c1; d_list = NULL; for (d1 = d; d1!=NULL; d1=d1->next) { if (d1->left == NULL) continue; for (c = d1->left; c->next != NULL; c = c->next) ; if (c->label < 0) continue; /* last one must be a fat link */ d2 = copy_disjunct(d1); d2->next = d_list; d_list = d2; c1 = init_connector((Connector *)xalloc(sizeof(Connector))); c1->string=L""; c1->label = COMMA_LABEL; c1->priority = THIN_priority; c1->multi=FALSE; c1->next = NULL; c->next = c1; } return catenate_disjuncts(d, d_list); }
static Disjunct * special_disjunct(int label, int dir, wchar_t *cs, wchar_t * ds) { /* Builds a new disjunct with one connector pointing in direction dir (which is '+' or '-'). The label and string of the connector are specified, as well as the string of the disjunct. The next pointer of the new disjunct set to NULL, so it can be regarded as a list. */ Disjunct * d1; Connector * c; d1 = (Disjunct *) xalloc(sizeof(Disjunct)); d1->cost = 0; d1->string = ds; d1->next = NULL; c = init_connector((Connector *)xalloc(sizeof(Connector))); c->string= cs; c->label = label; c->priority = THIN_priority; c->multi=FALSE; c->next = NULL; if (dir == L'+') { d1->left = NULL; d1->right = c; } else { d1->right = NULL; d1->left = c; } return d1; }
Connector * copy_connectors(Connector * c) { /* This builds a new copy of the connector list pointed to by c. Strings, as usual, are not copied. */ Connector *c1; if (c == NULL) return NULL; c1 = init_connector((Connector *) xalloc(sizeof(Connector))); *c1 = *c; c1->next = copy_connectors(c->next); return c1; }
Connector * excopy_connectors(Connector * c) { Connector *c1; if (c == NULL) return NULL; c1 = init_connector((Connector *) exalloc(sizeof(Connector))); *c1 = *c; c1->string = (char *) exalloc(sizeof(char)*(strlen(c->string)+1)); strcpy(c1->string, c->string); c1->next = excopy_connectors(c->next); return c1; }
void build_connector_set_from_expression(Connector_set * conset, Exp * e) { E_list * l; Connector * c; int h; if (e->type == CONNECTOR_type) { c = init_connector((Connector *) xalloc(sizeof(Connector))); c->string = e->u.string; c->label = NORMAL_LABEL; /* so we can use match() */ c->priority = THIN_priority; c->word = e->dir; /* just use the word field to give the dir */ h = connector_set_hash(conset, c->string, c->word); c->next = conset->hash_table[h]; conset->hash_table[h] = c; } else { for (l=e->u.l; l!=NULL; l=l->next) { build_connector_set_from_expression(conset, l->e); } } }
static Disjunct * glom_aux_connector(Disjunct * d, int label, int necessary) { /* In this case the connector is to connect to the "either", "neither", "not", or some auxilliary d to the current which is a conjunction. Only gets added next to a fat link, but before it (not after it) In the case of "nor", we don't create new disjuncts, we merely modify existing ones. This forces the fat link uses of "nor" to use a neither. (Not the case with "or".) If necessary=FALSE, then duplication is done, otherwise it isn't */ Disjunct * d_list, * d1, * d2; Connector * c, * c1, *c2; d_list = NULL; for (d1 = d; d1!=NULL; d1=d1->next) { if (d1->left == NULL) continue; for (c = d1->left; c->next != NULL; c = c->next) ; if (c->label < 0) continue; /* last one must be a fat link */ if (!necessary) { d2 = copy_disjunct(d1); d2->next = d_list; d_list = d2; } c1 = init_connector((Connector *)xalloc(sizeof(Connector))); c1->string=L""; c1->label = label; c1->priority = THIN_priority; c1->multi=FALSE; c1->next = c; if (d1->left == c) { d1->left = c1; } else { for (c2 = d1->left; c2->next != c; c2 = c2->next) ; c2->next = c1; } } return catenate_disjuncts(d, d_list); }
static Disjunct * add_one_connector(int label, int dir, wchar_t *cs, Disjunct * d) { /* This adds one connector onto the beginning of the left (or right) connector list of d. The label and string of the connector are specified */ Connector * c; c = init_connector((Connector *)xalloc(sizeof(Connector))); c->string= cs; c->label = label; c->priority = THIN_priority; c->multi=FALSE; c->next = NULL; if (dir == L'+') { c->next = d->right; d->right = c; } else { c->next = d->left; d->left = c; } return d; }
void WordTag::insert_connectors(Exp* exp, int& dfs_position, bool& leading_right, bool& leading_left, std::vector<int>& eps_right, std::vector<int>& eps_left, char* var, bool root, int parrent_cost) { int cost = parrent_cost + exp->cost; if (exp->type == CONNECTOR_type) { dfs_position++; const char* name = exp->u.string; Connector* connector = (Connector*)xalloc(sizeof(Connector)); init_connector(connector); connector->label = NORMAL_LABEL; connector->priority = THIN_priority; connector->multi = exp->multi; connector->string = name; set_connector_length_limit(connector); switch(exp->dir) { case '+': _position.push_back(_right_connectors.size()); _dir.push_back('+'); _right_connectors.push_back(PositionConnector(connector, '+', _word, dfs_position, exp->cost, cost, leading_right, false, eps_right, eps_left)); leading_right = false; break; case '-': _position.push_back(_left_connectors.size()); _dir.push_back('-'); _left_connectors.push_back(PositionConnector(connector, '-', _word, dfs_position, exp->cost, cost, false, leading_left, eps_right, eps_left)); leading_left = false; break; default: throw std::string("Unknown connector direction: ") + exp->dir; } } else if (exp->type == AND_type) { if (exp->u.l == NULL) { /* zeroary and */ } else if (exp->u.l != NULL && exp->u.l->next == NULL) { /* unary and - skip */ insert_connectors(exp->u.l->e, dfs_position, leading_right, leading_left, eps_right, eps_left, var, root, cost); } else { int i; E_list* l; char new_var[MAX_VARIABLE_NAME]; char* last_new_var = new_var; char* last_var = var; while(*last_new_var = *last_var) { last_new_var++; last_var++; } for (i = 0, l = exp->u.l; l != NULL; l = l->next, i++) { char* s = last_new_var; *s++ = 'c'; fast_sprintf(s, i); insert_connectors(l->e, dfs_position, leading_right, leading_left, eps_right, eps_left, new_var, false, cost); if (leading_right && var != NULL) { eps_right.push_back(_variables->epsilon(new_var, '+')); } if (leading_left && var != NULL) { eps_left.push_back(_variables->epsilon(new_var, '-')); } } } } else if (exp->type == OR_type) { if (exp->u.l != NULL && exp->u.l->next == NULL) { /* unary or - skip */ insert_connectors(exp->u.l->e, dfs_position, leading_right, leading_left, eps_right, eps_left, var, root, cost); } else { int i; E_list* l; bool ll_true = false; bool lr_true = false; char new_var[MAX_VARIABLE_NAME]; char* last_new_var = new_var; char* last_var = var; while(*last_new_var = *last_var) { last_new_var++; last_var++; } for (i = 0, l = exp->u.l; l != NULL; l = l->next, i++) { bool lr = leading_right, ll = leading_left; std::vector<int> er = eps_right, el = eps_left; char* s = last_new_var; *s++ = 'd'; fast_sprintf(s, i); insert_connectors(l->e, dfs_position, lr, ll, er, el, new_var, false, cost); if (lr) lr_true = true; if (ll) ll_true = true; } leading_right = lr_true; leading_left = ll_true; } } }
DLL_IMPLEMENTS void __stdcall DLLOnLoad() { init_connector(); }