Beispiel #1
0
/**
 * rdictionary_lookup() -- recursive dictionary lookup
 * Walk binary tree, given by 'dn', looking for the string 's'.
 * For every node in the tree where 's' matches (including wildcards)
 * make a copy of that node, and append it to llist.
 */
static Dict_node * rdictionary_lookup(Dict_node *llist,
                                      Dict_node * dn, const char * s, int match_idiom)
{
	/* see comment in dictionary_lookup below */
	int m;
	Dict_node * dn_new;
	if (dn == NULL) return llist;
	m = dict_order_wild(s, dn->string);
	if (m >= 0)
	{
		llist = rdictionary_lookup(llist, dn->right, s, match_idiom);
	}
	if ((m == 0) && (match_idiom || !is_idiom_word(dn->string)))
	{
		dn_new = dict_node_new();
		*dn_new = *dn;
		dn_new->right = llist;
		llist = dn_new;
	}
	if (m <= 0)
	{
		llist = rdictionary_lookup(llist, dn->left, s, match_idiom);
	}
	return llist;
}
Beispiel #2
0
/* Resize and rehash dict. */
int
dict_resize(struct dict *dict)
{
    assert(dict != NULL && dict->idx <= dict_idx_max);

    size_t new_idx = dict->idx + 1;

    if (new_idx > dict_idx_max)
        return DICT_ENOMEM;

    size_t new_table_size = dict_table_sizes[new_idx];
    struct dict_node **new_table = malloc(
            new_table_size * sizeof(struct dict_node *));

    /* init table to all NULL */
    size_t index;
    for (index = 0; index < new_table_size; index++)
        new_table[index] = NULL;

    size_t table_size = dict_table_sizes[dict->idx];

    for (index = 0; index < table_size; index++) {
        struct dict_node *node = (dict->table)[index];

        while (node != NULL) {
            struct dict_node *new_node = dict_node_new(
                    node->key, node->len, node->val);

            if (new_node == NULL)
                return DICT_ENOMEM;

            size_t new_index = dict_table_idx(
                    new_idx, new_node->key, new_node->len);
            struct dict_node *cursor = new_table[new_index];

            if (cursor == NULL) {
                /* set as head node */
                new_table[new_index] = new_node;
            } else {
                while (cursor->next != NULL)
                    cursor = cursor->next;
                /* set as last node */
                cursor->next = new_node;
            }
            /* shift next */
            struct dict_node *next = node->next;
            dict_node_free(node);
            node = next;
        }
    }

    free(dict->table);
    dict->table = new_table;
    dict->idx = new_idx;
    return DICT_OK;
}
Beispiel #3
0
/* Set a key into dict. */
int
dict_iset(struct dict *dict, char *key, size_t len, void *val)
{
    assert(dict != NULL);

    if ((dict_table_sizes[dict->idx] * DICT_LOAD_LIMIT < dict->len + 1) &&
            dict_resize(dict) != DICT_OK)
        return DICT_ENOMEM;

    size_t index = dict_table_idx(dict->idx, key, len);
    struct dict_node *node = (dict->table)[index];

    /* try to find this key. */
    while (node != NULL) {
        if (dict_key_equals(node->key, node->len, key, len)) {
            node->key = key;
            node->len = len;
            node->val = val;
            return DICT_OK;
        }
        node = node->next;
    }

    /* create node if not found */
    struct dict_node *new_node = dict_node_new(key, len, val);

    if (new_node == NULL)
        return DICT_ENOMEM;

    /* rewind to list head */
    node = (dict->table)[index];

    if (node == NULL) {
        /* if list is empty, set as head node */
        (dict->table)[index] = new_node;
    } else {
        /* else append as tail node */
        while (node->next != NULL)
            node = node->next;
        node->next = new_node;
    }

    dict->len += 1;
    return DICT_OK;
}
Beispiel #4
0
/**
 * read_entry() -- read one dictionary entry
 * Starting with the current token, parse one dictionary entry.
 * A single dictionary entry must have one and only one colon in it,
 * and is terminated by a semi-colon.
 * Add these words to the dictionary.
 */
static int read_entry(Dictionary dict)
{
	Exp *n;
	int i;

	Dict_node *dn_new, *dnx, *dn = NULL;

	/* Reset multi-byte shift state every line. */
	memset(&dict->mbss, 0, sizeof(dict->mbss));

	while (!is_equal(dict, ':'))
	{
		if (dict->is_special)
		{
			dict_error(dict, "I expected a word but didn\'t get it.");
			return 0;
		}

		/* If it's a word-file name */
		/* However, be careful to reject "/.v" which is the division symbol
		 * used in equations (.v means verb-like) */
		if ((dict->token[0] == '/') && (dict->token[1] != '.'))
		{
			dn = read_word_file(dict, dn, dict->token);
			if (dn == NULL)
			{
				err_ctxt ec;
				ec.sent = NULL;
				err_msg(&ec, Error, "Error opening word file %s\n", dict->token);
				return 0;
			}
		}
		else
		{
			dn_new = dict_node_new();
			dn_new->left = dn;
			dn = dn_new;
			dn->file = NULL;
			dn->string = string_set_add(dict->token, dict->string_set);
		}

		/* Advance to next entry, unless error */
		if (0 == link_advance(dict)) goto syntax_error;
	}

	/* pass the : */
	if (!link_advance(dict))
	{
		goto syntax_error;
	}

	n = expression(dict);
	if (n == NULL)
	{
		goto syntax_error;
	}

	if (!is_equal(dict, ';'))
	{
		dict_error(dict, "Expecting \";\" at the end of an entry.");
		goto syntax_error;
	}

	/* pass the ; */
	if (!link_advance(dict))
	{
		goto syntax_error;
	}

	/* At this point, dn points to a list of Dict_nodes connected by
	 * their left pointers. These are to be inserted into the dictionary */
	i = 0;
	for (dnx = dn; dnx != NULL; dnx = dnx->left)
	{
		dnx->exp = n;
		i++;
	}
	insert_list(dict, dn, i);
	return 1;

syntax_error:
	free_lookup_list(dn);
	return 0;
}