summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/cf-lex.l17
-rw-r--r--conf/conf.h3
-rw-r--r--conf/confbase.Y4
-rw-r--r--conf/gen_parser.m44
-rw-r--r--nest/config.Y2
-rw-r--r--proto/bgp/config.Y2
6 files changed, 24 insertions, 8 deletions
diff --git a/conf/cf-lex.l b/conf/cf-lex.l
index 0a02dd73..9555949d 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 cb47e7d0..d40f955e 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 1d5738ff..3e8f5807 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 <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 */
diff --git a/conf/gen_parser.m4 b/conf/gen_parser.m4
index af4b1455..7a2a9de4 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<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
diff --git a/nest/config.Y b/nest/config.Y
index e78350ca..c83c715b 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 013d14af..218e0d04 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 '}' ;