gperf для структур, которые имеют взаимозависимые внешние ключи - PullRequest
0 голосов
/ 18 февраля 2019

Возможно, у меня много статических данных, включая внешние ключи к другим статическим данным, которые необходимо разрешить.Я хочу, чтобы файлы данных были скомпилированы как константы в мою программу.Я написал простой генератор кода C, который принимает в качестве входных данных информацию о типе

Animal
string key
text description
~
Creature
string name
Animal animal
~

И данные

X
Neil
~
Animal
Bear
A bear is eating all the food.
.
Animal
Ostrich
An Ostrich is chilling.
.
Creature
Steve
Bear
Creature
Sam
Ostrich
Creature
Alice
Bear

И создает файл .h из типаинформация,

/** Auto-generated from ./ by Loader. */

#include <stddef.h> /* size_t */

/* These are datatypes that are loaded from ./. */

struct AutoAnimal;
struct AutoCreature;

struct AutoAnimal {
    const char *const key; /* key */
    const char *const description;
};

struct AutoCreature {
    const char *const name; /* key */
    const struct AutoAnimal *animal;
};

/* Search. */
struct AutoAnimal *AutoAnimalSearch(const char *const animal);
struct AutoCreature *AutoCreatureSearch(const char *const creature);

и .c из комбинированного типа информации и данных.Например, это разрешает внешний ключ для Alice как &auto_animal[0], который является Bear.

/** Auto-generated from ./ by Loader. */

#include <stdlib.h> /* bsearch */
#include <string.h> /* strcmp */
#include "x.h"

/*
 ./X.lore: "X" by Neil
*/

/* forward reference */
const struct AutoAnimal auto_animal[];
const struct AutoCreature auto_creature[];

/* loaded 5 lores */

const struct AutoAnimal auto_animal[] = {
    { "Bear", "A bear is eating all the food." },
    { "Ostrich", "An Ostrich is chilling." }
};
const int max_auto_animal = sizeof auto_animal / sizeof *auto_animal;

const struct AutoCreature auto_creature[] = {
    { "Alice", &auto_animal[0]/*Bear*/ },
    { "Sam", &auto_animal[1]/*Ostrich*/ },
    { "Steve", &auto_animal[0]/*Bear*/ }
};
const int max_auto_creature = sizeof auto_creature / sizeof *auto_creature;

static int animal_comp(const void *key, const void *elem) {
    const char *const k = key;
    const char *const e = ((const struct AutoAnimal *)elem)->key;
    return strcmp(k, e);
}

struct AutoAnimal *AutoAnimalSearch(const char *const key) {
    return bsearch(&key, auto_animal, max_auto_animal, sizeof *auto_animal, &animal_comp);
}

static int creature_comp(const char *const *key_ptr, const struct AutoCreature *elem) {
    const char *const k = *key_ptr;
    const char *const e = elem->name;
    return strcmp(k, e);
}

struct AutoCreature *AutoCreatureSearch(const char *const key) {
    return bsearch(&key, auto_creature, max_auto_creature, sizeof(struct AutoCreature), (int (*)(const void *, const void *))&creature_comp);
}

Выход отсортирован, так что я могу запустить bsearch на нем.Если я свяжу программу с автоматически сгенерированным источником,

#include <stdlib.h>
#include <stdio.h>
#include "x.h"

int main(void) {
    const struct AutoCreature *creatures[] = {
        AutoCreatureSearch("Sam"),
        AutoCreatureSearch("Alice"),
        AutoCreatureSearch("Eve")
    }, **ac, **ac_end, *c;
    const size_t creatures_size = sizeof creatures / sizeof *creatures;
    for(ac = creatures, ac_end = creatures + creatures_size; ac < ac_end; ac++){
        if(!(c = *ac)) { printf("Creature is not on record.\n"); continue; }
        printf("Creature %s is a(n) %s. %s\n", c->name, c->animal->key,
            c->animal->description);
    }
    return EXIT_SUCCESS;
}

Это даст,

Creature Sam is a(n) Ostrich. An Ostrich is chilling.
Creature Alice is a(n) Bear. A bear is eating all the food.
Creature is not on record.

Однако мне не нужно искать.Я хотел бы запустить gperf для всей «базы данных» и получить результаты в O(1).gperf и мой загрузчик вывели код завершения C, но я не могу разрешить внешние ключи, не зная позиций в другой таблице.Есть ли способ автоматизировать закрытие внешних ключей и идеальные хеш-таблицы, которые не требуют написания полноценного парсера для C?

...