mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 17:51:53 +00:00
Conf: Improve handling of keywords
For whatever reason, parser allocated a symbol for every parsed keyword in each scope. That wasted time and memory. The effect is worsened with recent changes allowing local scopes, so keywords often promote soft scopes (with no symbols) to real scopes. Do not allocate a symbol for a keyword. Take care of keywords that could be promoted to symbols (kw_sym) and do it explicitly.
This commit is contained in:
parent
9b471e72d7
commit
a8a64ca0fe
@ -601,6 +601,10 @@ cf_new_symbol(const byte *c)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct symbol *
|
||||||
|
cf_symbol_from_keyword(const struct keyword *kw)
|
||||||
|
{ return cf_new_symbol(kw->name); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cf_find_local_symbol - find a symbol by name
|
* cf_find_local_symbol - find a symbol by name
|
||||||
* @cfg: specificed config
|
* @cfg: specificed config
|
||||||
@ -692,18 +696,23 @@ static enum yytokentype
|
|||||||
cf_lex_symbol(const char *data)
|
cf_lex_symbol(const char *data)
|
||||||
{
|
{
|
||||||
/* Have we defined such a symbol? */
|
/* Have we defined such a symbol? */
|
||||||
struct symbol *sym = cf_get_symbol(data);
|
struct symbol *sym = cf_find_local_symbol(new_config, conf_this_scope, data);
|
||||||
cf_lval.s = sym;
|
|
||||||
|
|
||||||
if (sym->class != SYM_VOID)
|
if (sym && (sym->class != SYM_VOID))
|
||||||
|
{
|
||||||
|
cf_lval.s = sym;
|
||||||
return CF_SYM_KNOWN;
|
return CF_SYM_KNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
/* Is it a keyword? */
|
/* Is it a keyword? */
|
||||||
struct keyword *k = HASH_FIND(kw_hash, KW, data);
|
struct keyword *k = HASH_FIND(kw_hash, KW, data);
|
||||||
if (k)
|
if (k)
|
||||||
{
|
{
|
||||||
if (k->value > 0)
|
if (k->value > 0)
|
||||||
|
{
|
||||||
|
cf_lval.kw = k;
|
||||||
return k->value;
|
return k->value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cf_lval.i = -k->value;
|
cf_lval.i = -k->value;
|
||||||
@ -712,7 +721,7 @@ cf_lex_symbol(const char *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* OK, undefined symbol */
|
/* OK, undefined symbol */
|
||||||
cf_lval.s = sym;
|
cf_lval.s = cf_new_symbol(data);
|
||||||
return CF_SYM_UNDEFINED;
|
return CF_SYM_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,6 +191,9 @@ struct symbol *cf_find_local_symbol(const struct config *cfg, const struct sym_s
|
|||||||
static inline struct symbol *cf_find_symbol(const struct config *cfg, const byte *c)
|
static inline struct symbol *cf_find_symbol(const struct config *cfg, const byte *c)
|
||||||
{ return cf_find_local_symbol(cfg, cfg->root_scope, c); }
|
{ return cf_find_local_symbol(cfg, cfg->root_scope, c); }
|
||||||
|
|
||||||
|
struct keyword;
|
||||||
|
struct symbol *cf_symbol_from_keyword(const struct keyword *kw);
|
||||||
|
|
||||||
struct symbol *cf_get_symbol(const byte *c);
|
struct symbol *cf_get_symbol(const byte *c);
|
||||||
struct symbol *cf_default_name(char *template, int *counter);
|
struct symbol *cf_default_name(char *template, int *counter);
|
||||||
struct symbol *cf_localize_symbol(struct symbol *sym);
|
struct symbol *cf_localize_symbol(struct symbol *sym);
|
||||||
|
@ -61,6 +61,7 @@ CF_DECLS
|
|||||||
net_addr net;
|
net_addr net;
|
||||||
net_addr *net_ptr;
|
net_addr *net_ptr;
|
||||||
struct symbol *s;
|
struct symbol *s;
|
||||||
|
struct keyword *kw;
|
||||||
const char *t;
|
const char *t;
|
||||||
struct rtable_config *r;
|
struct rtable_config *r;
|
||||||
struct channel_config *cc;
|
struct channel_config *cc;
|
||||||
@ -117,6 +118,7 @@ CF_DECLS
|
|||||||
|
|
||||||
%type <t> text opttext
|
%type <t> text opttext
|
||||||
%type <s> symbol
|
%type <s> symbol
|
||||||
|
%type <kw> kw_sym
|
||||||
|
|
||||||
%nonassoc PREFIX_DUMMY
|
%nonassoc PREFIX_DUMMY
|
||||||
%left AND OR
|
%left AND OR
|
||||||
@ -172,7 +174,7 @@ expr_us:
|
|||||||
| expr US { $$ = $1 US_; }
|
| expr US { $$ = $1 US_; }
|
||||||
;
|
;
|
||||||
|
|
||||||
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN ;
|
symbol: CF_SYM_UNDEFINED | CF_SYM_KNOWN | kw_sym { $$ = cf_symbol_from_keyword($1); } ;
|
||||||
|
|
||||||
/* Switches */
|
/* Switches */
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ m4_define(CF_END, `m4_divert(-1)')
|
|||||||
m4_define(CF_itera, `m4_ifelse($#, 1, [[CF_iter($1)]], [[CF_iter($1)[[]]CF_itera(m4_shift($@))]])')
|
m4_define(CF_itera, `m4_ifelse($#, 1, [[CF_iter($1)]], [[CF_iter($1)[[]]CF_itera(m4_shift($@))]])')
|
||||||
m4_define(CF_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)')
|
m4_define(CF_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)')
|
||||||
|
|
||||||
# Keywords act as untyped %token
|
# Keywords act as %token<kw>
|
||||||
m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)m4_define([[CF_toks]],CF_toks $1)]])')
|
m4_define(CF_keywd, `m4_ifdef([[CF_tok_$1]],,[[m4_define([[CF_tok_$1]],1)m4_define([[CF_toks]],CF_toks $1)]])')
|
||||||
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<s>[[]]CF_toks
|
m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token<kw>[[]]CF_toks
|
||||||
)DNL')
|
)DNL')
|
||||||
|
|
||||||
# CLI commands
|
# CLI commands
|
||||||
|
@ -154,6 +154,8 @@ CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6)
|
|||||||
|
|
||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
|
kw_sym: MIN MAX ;
|
||||||
|
|
||||||
/* Setting of router ID */
|
/* Setting of router ID */
|
||||||
|
|
||||||
conf: rtrid ;
|
conf: rtrid ;
|
||||||
|
@ -46,7 +46,7 @@ CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER,
|
|||||||
CF_GRAMMAR
|
CF_GRAMMAR
|
||||||
|
|
||||||
/* Workaround for collisions between keywords and symbols */
|
/* Workaround for collisions between keywords and symbols */
|
||||||
symbol: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
|
kw_sym: ROLE | PEER | PROVIDER | CUSTOMER | RS_SERVER | RS_CLIENT ;
|
||||||
|
|
||||||
proto: bgp_proto '}' ;
|
proto: bgp_proto '}' ;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user