Lexer supports fallback symbol tables and uses them to recognize

symbols from global config when parsing CLI commands.

cf_lex_init_tables() is now called automatically inside the lexer.
This commit is contained in:
Martin Mares 1999-11-30 14:03:36 +00:00
parent f0474f2070
commit c9aae7f47f
3 changed files with 40 additions and 28 deletions

View file

@ -29,12 +29,12 @@ static struct keyword {
{ NULL, -1 } }; { NULL, -1 } };
#define KW_HASH_SIZE 64 #define KW_HASH_SIZE 64
static struct keyword *kw_hash[KW_HASH_SIZE];
static int kw_hash_inited;
#define SYM_HASH_SIZE 128 #define SYM_HASH_SIZE 128
#define SYM_MAX_LEN 32 #define SYM_MAX_LEN 32
static struct keyword *kw_hash[KW_HASH_SIZE];
static struct symbol **sym_hash;
struct sym_scope { struct sym_scope {
struct sym_scope *next; /* Next on scope stack */ struct sym_scope *next; /* Next on scope stack */
struct symbol *name; /* Name of this scope */ struct symbol *name; /* Name of this scope */
@ -192,21 +192,30 @@ static struct symbol *
cf_find_sym(byte *c, unsigned int h0) cf_find_sym(byte *c, unsigned int h0)
{ {
unsigned int h = h0 & (SYM_HASH_SIZE-1); unsigned int h = h0 & (SYM_HASH_SIZE-1);
struct symbol *s; struct symbol *s, **ht;
int l; int l;
if (!sym_hash) if (ht = new_config->sym_hash)
sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *)); {
else for(s = ht[h]; s; s=s->next)
for(s = sym_hash[h]; s; s=s->next)
if (!strcmp(s->name, c) && s->scope->active) if (!strcmp(s->name, c) && s->scope->active)
return s; return s;
}
if (new_config->sym_fallback)
{
/* We know only top-level scope is active */
for(s = new_config->sym_fallback[h]; s; s=s->next)
if (!strcmp(s->name, c) && s->scope->active)
return s;
}
if (!ht)
ht = new_config->sym_hash = cfg_allocz(SYM_HASH_SIZE * sizeof(struct keyword *));
l = strlen(c); l = strlen(c);
if (l > SYM_MAX_LEN) if (l > SYM_MAX_LEN)
cf_error("Symbol too long"); cf_error("Symbol too long");
s = cfg_alloc(sizeof(struct symbol) + l); s = cfg_alloc(sizeof(struct symbol) + l);
s->next = sym_hash[h]; s->next = ht[h];
sym_hash[h] = s; ht[h] = s;
s->scope = conf_this_scope; s->scope = conf_this_scope;
s->class = SYM_VOID; s->class = SYM_VOID;
s->def = NULL; s->def = NULL;
@ -246,22 +255,8 @@ cf_define_symbol(struct symbol *sym, int type, void *def)
sym->def = def; sym->def = def;
} }
void static void
cf_lex_init(int is_cli) cf_lex_init_kh(void)
{
sym_hash = NULL;
conf_lino = 1;
yyrestart(NULL);
if (is_cli)
BEGIN(CLI);
else
BEGIN(INITIAL);
conf_this_scope = cfg_allocz(sizeof(struct sym_scope));
conf_this_scope->active = 1;
}
void
cf_lex_init_tables(void)
{ {
struct keyword *k; struct keyword *k;
@ -271,6 +266,22 @@ cf_lex_init_tables(void)
k->next = kw_hash[h]; k->next = kw_hash[h];
kw_hash[h] = k; kw_hash[h] = k;
} }
kw_hash_inited = 1;
}
void
cf_lex_init(int is_cli)
{
if (!kw_hash_inited)
cf_lex_init_kh();
conf_lino = 1;
yyrestart(NULL);
if (is_cli)
BEGIN(CLI);
else
BEGIN(INITIAL);
conf_this_scope = cfg_allocz(sizeof(struct sym_scope));
conf_this_scope->active = 1;
} }
void void

View file

@ -45,7 +45,6 @@ config_parse(struct config *c)
if (setjmp(conf_jmpbuf)) if (setjmp(conf_jmpbuf))
return 0; return 0;
cf_lex_init(0); cf_lex_init(0);
cf_lex_init_tables();
protos_preconfig(c); protos_preconfig(c);
rt_preconfig(c); rt_preconfig(c);
cf_parse(); cf_parse();
@ -62,6 +61,7 @@ int
cli_parse(struct config *c) cli_parse(struct config *c)
{ {
new_config = c; new_config = c;
c->sym_fallback = config->sym_hash;
cfg_mem = c->mem; cfg_mem = c->mem;
if (setjmp(conf_jmpbuf)) if (setjmp(conf_jmpbuf))
return 0; return 0;

View file

@ -23,6 +23,8 @@ struct config {
char *err_msg; /* Parser error message */ char *err_msg; /* Parser error message */
int err_lino; /* Line containing error */ int err_lino; /* Line containing error */
char *file_name; /* Name of configuration file */ char *file_name; /* Name of configuration file */
struct symbol **sym_hash; /* Lexer: symbol hash table */
struct symbol **sym_fallback; /* Lexer: fallback symbol hash table */
}; };
extern struct config *config, *new_config; extern struct config *config, *new_config;
@ -69,7 +71,6 @@ struct symbol {
extern int conf_lino; extern int conf_lino;
void cf_lex_init_tables(void);
int cf_lex(void); int cf_lex(void);
void cf_lex_init(int is_cli); void cf_lex_init(int is_cli);
struct symbol *cf_find_symbol(byte *c); struct symbol *cf_find_symbol(byte *c);