Extrem-Speedup für den token-parser. Kleine Änderungen

This commit is contained in:
Enno Rehling 2001-02-15 02:41:47 +00:00
parent 68d2dea1e2
commit 2b5b9f446f
10 changed files with 146 additions and 111 deletions

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: building.c,v 1.6 2001/02/09 13:53:51 corwin Exp $
* $Id: building.c,v 1.7 2001/02/15 02:41:46 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -747,8 +747,7 @@ findbuildingtype(const char * name, const locale * lang)
}
bnames = bn;
}
i = findtoken(&bn->names, name);
if (i==E_TOK_NOMATCH) return NULL;
if (findtoken(&bn->names, name, &i)==E_TOK_NOMATCH) return NULL;
return (const building_type*)i;
}

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: curse.c,v 1.4 2001/02/03 13:45:32 enno Exp $
* $Id: curse.c,v 1.5 2001/02/15 02:41:46 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -166,7 +166,8 @@ ct_find(const char *c)
/* TODO: findet nur curse_types, die auch in curse_data sind.
* da fehlt noch ene registrierung wie für attrib_type
*/
int i = (int)findtoken(&cursenames, c);
int i;
if (findtoken(&cursenames, c, (void**)&i)==E_TOK_NOMATCH) return NULL;
if (i == -1 || cursedaten[i].name[0] == 0) {
cursetype_list * ctl = cursetypes;
while (ctl) {

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: eressea.c,v 1.14 2001/02/13 02:58:51 enno Exp $
* $Id: eressea.c,v 1.15 2001/02/15 02:41:46 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -1109,16 +1109,20 @@ struct tnode cursenames;
skill_t
findskill(const char *s)
{
return (skill_t)findtoken(&tokens[UT_SKILL], s)-1;
int i;
if (findtoken(&tokens[UT_SKILL], s, (void**)&i)==E_TOK_NOMATCH) return NOSKILL;
return (skill_t)i;
}
keyword_t
findkeyword(const char *s)
{
int i;
#ifdef AT_PERSISTENT
if(*s == '@') s++;
#endif
return (keyword_t) findtoken(&tokens[UT_KEYWORD], s)-1;
if (findtoken(&tokens[UT_KEYWORD], s, (void**)&i)==E_TOK_NOMATCH) return NOKEYWORD;
return (keyword_t) i;
}
keyword_t
@ -1136,13 +1140,15 @@ getkeyword (void)
param_t
findparam(const char *s)
{
int p;
const building_type * btype;
p = (int)findtoken(&tokens[UT_PARAM], s)-1;
if (p>=0) return (param_t)p;
btype = findbuildingtype(s, NULL);
if (btype!=NULL) return (param_t) P_BUILDING;
return NOPARAM;
int i;
if (findtoken(&tokens[UT_PARAM], s, (void**)&i)==E_TOK_NOMATCH) {
btype = findbuildingtype(s, NULL);
if (btype!=NULL) return (param_t) P_BUILDING;
return NOPARAM;
}
return (param_t)i;
}
param_t
@ -1749,7 +1755,7 @@ use_birthdayamulet(region * r, unit * magician, strlist * cmdstrings)
typedef struct t_umlaut {
const char *txt;
unsigned char id;
int id;
int typ;
} t_umlaut;
@ -1801,17 +1807,17 @@ init_tokens(void)
{
int i;
for (i=0;i!=MAXPARAMS;++i)
addtoken(&tokens[UT_PARAM], parameters[i], (void*)(i+1));
addtoken(&tokens[UT_PARAM], parameters[i], (void*)i);
for (i=0;i!=MAXSKILLS;++i)
addtoken(&tokens[UT_SKILL], skillnames[i], (void*)(i+1));
addtoken(&tokens[UT_SKILL], skillnames[i], (void*)i);
for (i=0;i!=MAXKEYWORDS;++i)
addtoken(&tokens[UT_KEYWORD], keywords[i], (void*)(i+1));
addtoken(&tokens[UT_KEYWORD], keywords[i], (void*)i);
for (i=0;umlaut[i].txt;++i)
addtoken(&tokens[umlaut[i].typ], umlaut[i].txt, (void*)(umlaut[i].id+1));
addtoken(&tokens[umlaut[i].typ], umlaut[i].txt, (void*)umlaut[i].id);
for (i=0; spelldaten[i].id != SPL_NOSPELL; i++)
addtoken(&spellnames, spelldaten[i].name, (void*)(i+1));
addtoken(&spellnames, spelldaten[i].name, (void*)i);
for (i=0; i!=MAXCURSE; i++){
addtoken(&cursenames, cursedaten[i].name, (void*)(i+1));
addtoken(&cursenames, cursedaten[i].name, (void*)i);
}
}
@ -2096,44 +2102,46 @@ resolve2(void)
#endif
static void
init_directions(tnode * root)
{
/* mit dieser routine kann man mehrere namen für eine direction geben,
* das ist für die hexes ideal. */
const struct {
const char* name;
int direction;
} dirs [] = {
{ "no", D_NORTHEAST},
{ "nw", D_NORTHWEST},
{ "nordosten", D_NORTHEAST},
{ "nordwesten", D_NORTHWEST},
{ "so", D_SOUTHEAST},
{ "sw", D_SOUTHWEST},
{ "südosten", D_SOUTHEAST},
{ "südwesten", D_SOUTHWEST},
{ "osten", D_EAST },
{ "westen",D_WEST },
{ NULL, NODIRECTION}
};
int i;
for (i=0; dirs[i].direction!=NODIRECTION;++i) {
addtoken(root, dirs[i].name, (void*)dirs[i].direction);
}
}
direction_t
finddirection(const char *s)
{
#define MAXDIRNAMES 12
static const char* dirs[MAXDIRNAMES] = {
"no",
"nw",
"nordosten",
"nordwesten",
"so",
"sw",
"suedosten",
"südosten",
"suedwesten",
"südwesten",
"osten",
"westen"
/* mit dieser routine kann man mehrere namen für eine direction geben,
* das ist für die hexes ideal. */
};
static const direction_t dir_xref[MAXDIRNAMES] = {
D_NORTHEAST,
D_NORTHWEST,
D_NORTHEAST,
D_NORTHWEST,
D_SOUTHEAST,
D_SOUTHWEST,
D_SOUTHEAST,
D_SOUTHEAST,
D_SOUTHWEST,
D_SOUTHWEST,
D_EAST,
D_WEST
};
int uc = findstr(dirs, s, MAXDIRNAMES);
static boolean init = false;
static tnode dirnames;
int dir;
if (uc == -1) return NODIRECTION;
return dir_xref[uc];
if (!init) init_directions(&dirnames);
if (findtoken(&dirnames, s, (void**)&dir)==E_TOK_SUCCESS) {
return (direction_t)dir;
}
return NODIRECTION;
}
unit *

View File

@ -1105,7 +1105,7 @@ extern void guard(struct unit * u, unsigned int mask);
typedef struct local_names {
struct local_names * next;
const struct locale * lang;
tnode names;
struct tnode names;
} local_names;
extern int maxworkingpeasants(const struct region * r);

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: item.c,v 1.11 2001/02/14 07:44:57 enno Exp $
* $Id: item.c,v 1.12 2001/02/15 02:41:46 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -2031,8 +2031,8 @@ findresourcetype(const char * name, const locale * lang)
}
rnames = rn;
}
i = findtoken(&rn->names, name);
if (i==E_TOK_NOMATCH) return NULL;
if (findtoken(&rn->names, name, &i)==E_TOK_NOMATCH) return NULL;
return (const resource_type*)i;
}
@ -2073,8 +2073,7 @@ finditemtype(const char * name, const locale * lang)
}
inames = in;
}
i = findtoken(&in->names, name);
if (i==E_TOK_NOMATCH) return NULL;
if (findtoken(&in->names, name, &i)==E_TOK_NOMATCH) return NULL;
return (const item_type*)i;
}

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: magic.c,v 1.7 2001/02/12 22:39:56 enno Exp $
* $Id: magic.c,v 1.8 2001/02/15 02:41:46 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -567,8 +567,8 @@ find_spellbyname(unit *u, char *s)
spell *sp;
int i;
m = get_mage(u);
if (!m) {
m = get_mage(u);
if (!m) {
return (spell *) NULL;
}
@ -579,8 +579,7 @@ find_spellbyname(unit *u, char *s)
}
}
i = (int)findtoken(&spellnames, s)-1;
if (i>=0 && getspell(u, spelldaten[i].id)) return &spelldaten[i];
if (findtoken(&spellnames, s, (void**)&i) && getspell(u, spelldaten[i].id)) return &spelldaten[i];
return (spell *) NULL;
}

View File

@ -169,8 +169,7 @@ gm_command(const char * cmd, struct unit * u)
i = min(16, c-cmd);
strncpy(zText, cmd, i);
zText[i]=0;
cm = (command*)findtoken(&g_keys, zText);
if (cm && cm->perform) cm->perform(++c, u);
if (findtoken(&g_keys, zText, (void**)&cm) && cm->perform) cm->perform(++c, u);
}
void

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: shock.c,v 1.2 2001/01/26 16:19:41 enno Exp $
* $Id: shock.c,v 1.3 2001/02/15 02:41:47 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -49,18 +49,13 @@ static void
shock_write(const trigger * t, FILE * F)
{
unit * u = (unit*)t->data.v;
fprintf(F, "%s ", itoa36(u->no));
write_unit_reference(u, F);
}
static int
shock_read(trigger * t, FILE * F)
{
char zId[10];
int i;
fscanf(F, "%s", zId);
i = atoi36(zId);
t->data.v = findunit(i);
if (t->data.v==NULL) ur_add((void*)i, &t->data.v, resolve_unit);
read_unit_reference((unit**)&t->data.v, F);
return 1;
}

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: umlaut.c,v 1.4 2001/02/13 02:58:51 enno Exp $
* $Id: umlaut.c,v 1.5 2001/02/15 02:41:47 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -27,6 +27,15 @@
#include <string.h>
#include <assert.h>
typedef struct tref {
struct tref * nexthash;
char c;
struct tnode * node;
} tref;
#define LEAF 1 /* leaf node for a word. always matches */
#define SHARED 2 /* at least two words share the node */
void
addtoken(tnode * root, const char* str, void * id)
{
@ -44,28 +53,43 @@ addtoken(tnode * root, const char* str, void * id)
{'ß', "ss"},
{ 0, 0 }
};
assert(id!=E_TOK_NOMATCH);
if (root->id!=E_TOK_NOMATCH && root->id!=id && !root->leaf) root->id=E_TOK_NOMATCH;
if (!*str) {
root->id = id;
root->leaf=1;
root->flags |= LEAF;
} else {
tnode * tk;
tref * next;
int index, i = 0;
char c = *str;
if (c<'a' || c>'z') c = (char)tolower((unsigned char)c);
index = ((unsigned char)c) % 32;
tk = root->next[index];
if (root->id==E_TOK_NOMATCH) root->id = id;
while (tk && tk->c != c) tk = tk->nexthash;
if (!tk) {
tk = calloc(1, sizeof(tnode));
tk->id = E_TOK_NOMATCH;
tk->c = c;
tk->nexthash=root->next[index];
root->next[index] = tk;
next = root->next[index];
if (!root->flags) root->id = id;
while (next && next->c != c) next = next->nexthash;
if (!next) {
tref * ref;
char u = (char)toupper((unsigned char)c);
tnode * node = calloc(1, sizeof(tnode));
ref = malloc(sizeof(tref));
ref->c = c;
ref->node = node;
ref->nexthash=root->next[index];
root->next[index] = ref;
if (u!=c) {
index = ((unsigned char)u) % 32;
ref = malloc(sizeof(tref));
ref->c = u;
ref->node = node;
ref->nexthash = root->next[index];
root->next[index] = ref;
}
next=ref;
} else {
next->node->flags |= SHARED;
if (next->node->flags & LEAF == 0) next->node->id = NULL;
}
addtoken(tk, str+1, id);
addtoken(next->node, str+1, id);
while (replace[i].str) {
if (*str==replace[i].c) {
strcat(strcpy(zText, replace[i].str), str+1);
@ -77,22 +101,32 @@ addtoken(tnode * root, const char* str, void * id)
}
}
void *
findtoken(tnode * tk, const char * str)
int
findtoken(tnode * tk, const char * str, void **result)
{
if(*str == 0) return E_TOK_NOMATCH;
if (*str == 0) return E_TOK_NOMATCH;
while (*str) {
int index;
tref * ref;
char c = *str;
if (c<'a' || c>'z') c = (char)tolower((unsigned char)c);
/* if (c<'a' || c>'z') c = (char)tolower((unsigned char)c); */
index = ((unsigned char)c) % 32;
tk = tk->next[index];
while (tk && tk->c!=c) tk = tk->nexthash;
ref = tk->next[index];
while (ref && ref->c!=c) ref = ref->nexthash;
++str;
if (!tk) return E_TOK_NOMATCH;
if (!ref) return E_TOK_NOMATCH;
tk = ref->node;
if (tk && !(tk->flags & SHARED)) {
*result = tk->id;
return E_TOK_SUCCESS;
}
}
return tk->id;
if (tk && (tk->flags & LEAF)) {
*result = tk->id;
return E_TOK_SUCCESS;
}
return E_TOK_NOMATCH;
}

View File

@ -1,6 +1,6 @@
/* vi: set ts=2:
*
* $Id: umlaut.h,v 1.2 2001/01/26 16:19:41 enno Exp $
* $Id: umlaut.h,v 1.3 2001/02/15 02:41:47 enno Exp $
* Eressea PB(E)M host Copyright (C) 1998-2000
* Christian Schlittchen (corwin@amber.kn-bremen.de)
* Katja Zedel (katze@felidae.kn-bremen.de)
@ -14,18 +14,19 @@
#ifndef _UMLAUT_H
#define _UMLAUT_H
typedef struct tnode tnode;
struct tnode {
struct tnode * nexthash;
struct tnode * next[32];
#define E_TOK_NOMATCH (-1)
#define E_TOK_SUCCESS 0
struct tref;
typedef struct tnode {
struct tref * next[32];
unsigned char flags;
void * id;
char c;
unsigned char leaf;
};
} tnode;
#define E_TOK_NOMATCH NULL
void * findtoken(struct tnode * tk, const char * str);
int findtoken(struct tnode * tk, const char * str, void** result);
void addtoken(struct tnode * root, const char* str, void * id);
#endif