]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Conf: Improve handling of keywords
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Apr 2023 16:20:49 +0000 (18:20 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Apr 2023 16:41:01 +0000 (18:41 +0200)
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.

conf/cf-lex.l
conf/conf.h
conf/confbase.Y
conf/gen_parser.m4
nest/config.Y
proto/bgp/config.Y

index 0a02dd73675f91351cfe6796bc932407001a637a..9555949d430546bce549ec436d86928f7d07905d 100644 (file)
@@ -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;
 }
 
index cb47e7d0fa83a214aa763c920ab8071d6152742e..d40f955eb903904c8f6a8923044a337a3a18a0b5 100644 (file)
@@ -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);
index 1d5738ff06d1f917cc79c93cf73cec5fe2e4c45a..3e8f580744e0f120a9c9b21cc87a85b276c4091a 100644 (file)
@@ -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 <t> text opttext
 %type <s> symbol
+%type <kw> 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 */
 
index af4b14554c71b26b9a557f32ae6134139a5de0b0..7a2a9de445c9fb86b84b1ee5dee1538189c6b30f 100644 (file)
@@ -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<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_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')
 
 # CLI commands
index e78350caabcf1f53b2b2410e7b1f3dd8ae276885..c83c715b9e0ca0c897bb59f356cb4d68224eeb80 100644 (file)
@@ -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 ;
index 013d14af71b425daaa9fee7aee0f56b3be4d1b43..218e0d04803246d069373eb46aaa72218479f5d3 100644 (file)
@@ -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 '}'  ;