Beispiel #1
0
/**
 * insert_list() -
 * p points to a list of dict_nodes connected by their left pointers.
 * l is the length of this list (the last ptr may not be NULL).
 * It inserts the list into the dictionary.
 * It does the middle one first, then the left half, then the right.
 *
 * Note: I think this insert middle, then left, then right, has
 * its origins as a lame attempt to hack around the fact that the 
 * resulting binary tree is rather badly unbalanced. This has been 
 * fixed by using the DSW rebalancing algo. Now, that would seem
 * to render this crazy bisected-insertion algo obsoloete, but ..
 * oddly enough, it seems to make the DSW balancing go really fast!
 * Faster than a simple insertion. Go figure. I think this has
 * something to do with the fact that the dictionaries are in
 * alphabetical order! This subdivision helps randomize a bit.
 */
static void insert_list(Dictionary dict, Dict_node * p, int l)
{
	Dict_node * dn, *dn_head, *dn_second_half;
	int k, i; /* length of first half */

	if (l == 0) return;

	k = (l-1)/2;
	dn = p;
	for (i = 0; i < k; i++)
	{
		dn = dn->left;
	}

	/* dn now points to the middle element */
	dn_second_half = dn->left;
	dn->left = dn->right = NULL;

	if (contains_underbar(dn->string))
	{
		insert_idiom(dict, dn);
	}
	else if (is_idiom_word(dn->string))
	{
		err_ctxt ec;
		ec.sent = NULL;
		err_msg(&ec, Warn, "Warning: Word \"%s\" found near line %d.\n"
		        "\tWords ending \".Ix\" (x a number) are reserved for idioms.\n"
		        "\tThis word will be ignored.\n",
		        dn->string, dict->line_number);
		free_dict_node(dn);
	}
	else if ((dn_head = abridged_lookup_list(dict, dn->string)) != NULL)
	{
		Dict_node *dnx;
		err_ctxt ec;
		ec.sent = NULL;
		err_msg(&ec, Warn, "Warning: The word \"%s\" "
		          "found near line %d of %s matches the following words:\n",
	             dn->string, dict->line_number, dict->name);
		for (dnx = dn_head; dnx != NULL; dnx = dnx->right) {
			fprintf(stderr, "\t%s", dnx->string);
		}
		fprintf(stderr, "\n\tThis word will be ignored.\n");
		free_lookup_list(dn_head);
		free_dict_node(dn);
	}
	else
	{
		dict->root = insert_dict(dict, dict->root, dn);
		dict->num_entries++;
	}

	insert_list(dict, p, k);
	insert_list(dict, dn_second_half, l-k-1);
}
Beispiel #2
0
/**
 * Insert the new node into the dictionary below node n.
 * Give error message if the new element's string is already there.
 * Assumes that the "n" field of new is already set, and the left
 * and right fields of it are NULL.
 *
 * The resulting tree is highly unbalanced. It needs to be rebalanced
 * before used.
 */
Dict_node * insert_dict(Dictionary dict, Dict_node * n, Dict_node * newnode)
{
	int comp;

	if (NULL == n) return newnode;

	comp = dict_order(newnode->string, n->string);
	if (comp < 0)
	{
		if (NULL == n->left)
		{
			n->left = newnode;
			return n;
		} 
		n->left = insert_dict(dict, n->left, newnode);
		return n;
		/* return rebalance(n); Uncomment to get an AVL tree */
	}
	else if (comp > 0)
	{
		if (NULL == n->right)
		{
			n->right = newnode;
			return n;
		}
		n->right = insert_dict(dict, n->right, newnode);
		return n;
		/* return rebalance(n); Uncomment to get an AVL tree */
	}
	else
	{
		char t[256];
		snprintf(t, 256, "The word \"%s\" has been multiply defined\n", newnode->string);
		dict_error(dict, t);
		return NULL;
	}
}
Beispiel #3
0
/**
 * Takes as input a pointer to a Dict_node.
 * The string of this Dict_node is an idiom string.
 * This string is torn apart, and its components are inserted into the
 * dictionary as special idiom words (ending in .I*, where * is a number).
 * The expression of this Dict_node (its node field) has already been
 * read and constructed.  This will be used to construct the special idiom
 * expressions.
 * The given dict node is freed.  The string is also freed.
 */
void insert_idiom(Dictionary dict, Dict_node * dn)
{
	Exp * nc, * no, * n1;
	E_list *ell, *elr;
	const char * s;
	int s_length;
	Dict_node * dn_list, * xdn, * start_dn_list;

	no = dn->exp;
	s = dn->string;
	s_length = strlen(s);

	if (!is_idiom_string(s))
	{
		prt_error("Warning: Word \"%s\" on line %d "
		          "is not a correctly formed idiom string.\n"
		          "\tThis word will be ignored\n",
		          s, dict->line_number);

		xfree((char *)dn, sizeof (Dict_node));
		return;
	}

	dn_list = start_dn_list = make_idiom_Dict_nodes(dict, s);
	xfree((char *)dn, sizeof (Dict_node));

	if (dn_list->right == NULL) {
	  prt_error("Fatal Error: Idiom string with only one connector -- should have been caught");
		exit(1);
	}

	/* first make the nodes for the base word of the idiom (last word) */
	/* note that the last word of the idiom is first in our list */

	/* ----- this code just sets up the node fields of the dn_list ----*/
	nc = Exp_create(dict);
	nc->u.string = generate_id_connector(dict);
	nc->dir = '-';
	nc->multi = FALSE;
	nc->type = CONNECTOR_type;
	nc->cost = 0;

	n1 = Exp_create(dict);
	n1->u.l = ell = (E_list *) xalloc(sizeof(E_list));
	ell->next = elr = (E_list *) xalloc(sizeof(E_list));
	elr->next = NULL;
	ell->e = nc;
	elr->e = no;
	n1->type = AND_type;
	n1->cost = 0;

	dn_list->exp = n1;

	dn_list = dn_list->right;

	while(dn_list->right != NULL) {
		/* generate the expression for a middle idiom word */

		n1 = Exp_create(dict);
		n1->u.string = NULL;
		n1->type = AND_type;
		n1->cost = 0;
		n1->u.l = ell = (E_list *) xalloc(sizeof(E_list));
		ell->next = elr = (E_list *) xalloc(sizeof(E_list));
		elr->next = NULL;

		nc = Exp_create(dict);
		nc->u.string = generate_id_connector(dict);
		nc->dir = '+';
		nc->multi = FALSE;
		nc->type = CONNECTOR_type;
		nc->cost = 0;
		elr->e = nc;

		increment_current_name();

		nc = Exp_create(dict);
		nc->u.string = generate_id_connector(dict);
		nc->dir = '-';
		nc->multi = FALSE;
		nc->type = CONNECTOR_type;
		nc->cost = 0;

		ell->e = nc;

		dn_list->exp = n1;

		dn_list = dn_list->right;
	}
	/* now generate the last one */

	nc = Exp_create(dict);
	nc->u.string = generate_id_connector(dict);
	nc->dir = '+';
	nc->multi = FALSE;
	nc->type = CONNECTOR_type;
	nc->cost = 0;

	dn_list->exp = nc;

	increment_current_name();

	/* ---- end of the code alluded to above ---- */

	/* now its time to insert them into the dictionary */

	dn_list = start_dn_list;

	while (dn_list != NULL) {
		xdn = dn_list->right;
		dn_list->left = dn_list->right = NULL;
		dn_list->string = build_idiom_word_name(dict, dn_list->string);
		dict->root = insert_dict(dict, dict->root, dn_list);
		dict->num_entries++;
		dn_list = xdn;
	}
	/* xfree((char *)s, s_length+1); strings are handled by string_set */
}
Beispiel #4
0
void insert_idiom(Dictionary dict, Dict_node * dn) {
    /* Takes as input a pointer to a Dict_node.
       The string of this Dict_node is an idiom string.
       This string is torn apart, and its components are inserted into the
       dictionary as special idiom words (ending in .I*, where * is a number).
       The expression of this Dict_node (its node field) has already been
       read and constructed.  This will be used to construct the special idiom
       expressions.
       The given dict node is freed.  The string is also freed.
       */
    Exp * nc, * no, * n1;
    E_list *ell, *elr;
    wchar_t * s;
    int s_length;
    Dict_node * dn_list, * xdn, * start_dn_list;
    
    no = dn->exp;
    s = dn->string;
    s_length = wcslen(s);
    
    if (!is_idiom_string(s)) {
	wprintf_s(L"*** Word \"%s\" on line %d is not",s, dict->line_number);
	wprintf_s(L" a correctly formed idiom string.\n");
	wprintf_s(L"    This word will be ignored\n");
	/* xfree((wchar_t *)s, s_length+1);  strings are handled now by string_set */
	xfree((wchar_t *)dn, sizeof (Dict_node));
	return;
    }
    
    dn_list = start_dn_list = make_idiom_Dict_nodes(dict, s);
    xfree((wchar_t *)dn, sizeof (Dict_node));
    
    if (dn_list->right == NULL) {
      error(L"Idiom string with only one connector -- should have been caught");
    }
    
    /* first make the nodes for the base word of the idiom (last word) */
    /* note that the last word of the idiom is first in our list */
    
    /* ----- this code just sets up the node fields of the dn_list ----*/
    nc = Exp_create(dict);
    nc->u.string = generate_id_connector(dict);
    nc->dir = L'-';
    nc->multi = FALSE;
    nc->type = CONNECTOR_type;
    nc->cost = 0;
    
    n1 = Exp_create(dict);
    n1->u.l = ell = (E_list *) xalloc(sizeof(E_list));
    ell->next = elr = (E_list *) xalloc(sizeof(E_list));
    elr->next = NULL;
    ell->e = nc;
    elr->e = no;
    n1->type = AND_type;
    n1->cost = 0;

    dn_list->exp = n1;
    
    dn_list = dn_list->right;
    
    while(dn_list->right != NULL) {
	/* generate the expression for a middle idiom word */
	
	n1 = Exp_create(dict);
	n1->u.string = NULL;
	n1->type = AND_type;
	n1->cost = 0;
	n1->u.l = ell = (E_list *) xalloc(sizeof(E_list));
	ell->next = elr = (E_list *) xalloc(sizeof(E_list));
	elr->next = NULL;
	
	nc = Exp_create(dict);
	nc->u.string = generate_id_connector(dict);
	nc->dir = L'+';
	nc->multi = FALSE;
	nc->type = CONNECTOR_type;
	nc->cost = 0;
	elr->e = nc;
	
	increment_current_name();
	
	nc = Exp_create(dict);
	nc->u.string = generate_id_connector(dict);
	nc->dir = L'-';
	nc->multi = FALSE;
	nc->type = CONNECTOR_type;
	nc->cost = 0;

	ell->e = nc;
	
	dn_list->exp = n1;
	
	dn_list = dn_list->right;
    }
    /* now generate the last one */
    
    nc = Exp_create(dict);
    nc->u.string = generate_id_connector(dict);
    nc->dir = L'+';
    nc->multi = FALSE;
    nc->type = CONNECTOR_type; 
    nc->cost = 0;
    
    dn_list->exp = nc;
    
    increment_current_name();
    
    /* ---- end of the code alluded to above ---- */
    
    /* now its time to insert them into the dictionary */
    
    dn_list = start_dn_list;
    
    while (dn_list != NULL) {
	xdn = dn_list->right;
	dn_list->left = dn_list->right = NULL;
        dn_list->string = build_idiom_word_name(dict, dn_list->string);
	dict->root = insert_dict(dict, dict->root, dn_list);
	dict->num_entries++;
	dn_list = xdn;
    }
    /* xfree((wchar_t *)s, s_length+1); strings are handled by string_set */
}