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:
parent
f0474f2070
commit
c9aae7f47f
3 changed files with 40 additions and 28 deletions
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue