From: Ondrej Zajicek Date: Thu, 27 Apr 2023 16:20:49 +0000 (+0200) Subject: Conf: Improve handling of keywords X-Git-Tag: v2.14~111 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a8a64ca0fed41c78376b27880e934296bd3c3a7f;p=thirdparty%2Fbird.git 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. --- diff --git a/conf/cf-lex.l b/conf/cf-lex.l index 0a02dd736..9555949d4 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -601,6 +601,10 @@ cf_new_symbol(const byte *c) 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 * @cfg: specificed config @@ -692,18 +696,23 @@ static enum yytokentype cf_lex_symbol(const char *data) { /* Have we defined such a symbol? */ - struct symbol *sym = cf_get_symbol(data); - cf_lval.s = sym; + struct symbol *sym = cf_find_local_symbol(new_config, conf_this_scope, data); - if (sym->class != SYM_VOID) + if (sym && (sym->class != SYM_VOID)) + { + cf_lval.s = sym; return CF_SYM_KNOWN; + } /* Is it a keyword? */ struct keyword *k = HASH_FIND(kw_hash, KW, data); if (k) { if (k->value > 0) + { + cf_lval.kw = k; return k->value; + } else { cf_lval.i = -k->value; @@ -712,7 +721,7 @@ cf_lex_symbol(const char *data) } /* OK, undefined symbol */ - cf_lval.s = sym; + cf_lval.s = cf_new_symbol(data); return CF_SYM_UNDEFINED; } diff --git a/conf/conf.h b/conf/conf.h index cb47e7d0f..d40f955eb 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -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) { 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_default_name(char *template, int *counter); struct symbol *cf_localize_symbol(struct symbol *sym); diff --git a/conf/confbase.Y b/conf/confbase.Y index 1d5738ff0..3e8f58074 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -61,6 +61,7 @@ CF_DECLS net_addr net; net_addr *net_ptr; struct symbol *s; + struct keyword *kw; const char *t; struct rtable_config *r; struct channel_config *cc; @@ -117,6 +118,7 @@ CF_DECLS %type text opttext %type symbol +%type kw_sym %nonassoc PREFIX_DUMMY %left AND OR @@ -172,7 +174,7 @@ expr_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 */ diff --git a/conf/gen_parser.m4 b/conf/gen_parser.m4 index af4b14554..7a2a9de44 100644 --- a/conf/gen_parser.m4 +++ b/conf/gen_parser.m4 @@ -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_iterate, `m4_define([[CF_iter]], m4_defn([[$1]]))CF_itera($2)') -# Keywords act as untyped %token +# Keywords act as %token 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[[]]CF_toks +m4_define(CF_KEYWORDS, `m4_define([[CF_toks]],[[]])CF_iterate([[CF_keywd]], [[$@]])m4_ifelse(CF_toks,,,%token[[]]CF_toks )DNL') # CLI commands diff --git a/nest/config.Y b/nest/config.Y index e78350caa..c83c715b9 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -154,6 +154,8 @@ CF_ENUM_PX(T_ENUM_AF, AF_, AFI_, IPV4, IPV6) CF_GRAMMAR +kw_sym: MIN MAX ; + /* Setting of router ID */ conf: rtrid ; diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 013d14af7..218e0d048 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -46,7 +46,7 @@ CF_KEYWORDS(CEASE, PREFIX, LIMIT, HIT, ADMINISTRATIVE, SHUTDOWN, RESET, PEER, CF_GRAMMAR /* 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 '}' ;