我可能有很多静态数据,包括指向其他需要解析的静态数据的外键。我希望将数据文件作为常量编译到我的程序中。我编写了一个简单的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
编写成熟的解析器?