From 0b62c3a7c7548cd447b4f18e0346cc9e74862ab3 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Fri, 27 Nov 1998 21:32:45 +0000 Subject: [PATCH] Trivial 15-line bison excercise: Implemented expressions including user-defined numeric symbols. Whenever possible, use `expr' instead of `NUM' to get full express ion power :-) --- TODO | 6 ++---- bird.conf | 4 +++- conf/cf-lex.l | 3 ++- conf/conf.h | 2 ++ conf/confbase.Y | 31 +++++++++++++++++++++++++++++++ nest/config.Y | 3 ++- 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 37adde9c..ba760b88 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,14 @@ Core ~~~~ * right usage of DBG vs. debug +* cleanup debugging calls! - TOS not supported by kernel -> automatically drop routes with TOS<>0 - use -freg-struct-return ? - fake multipath? +- replace all NUM's by expr's - config file: symbolic constants? - counters (according to SNMP MIB?) - generation of subnet mask ICMP's for v6? @@ -14,7 +16,6 @@ Core - ifdef out some debugging code? - better memory allocators - default preferences of protocols: prefer BGP over OSPF/RIP external routes? -- all internal tables are in host order - secondary addresses -> subinterfaces - check if all protocols set proper packet priorities and TTL's. @@ -37,8 +38,6 @@ Core - Check incoming packets and log errors!! -- implement snprintf etc. and clean up debugging and logging functions - RIP ~~~ @@ -51,7 +50,6 @@ RIP OSPF ~~~~ - - Dijkstra: use Fibonacci heaps? - point-to-point interface with address: advertise as stub network - static routes: stub networks? - modes: PtP, PtP-unnumbered, Broadcast, NBMA, point-to-multipoint diff --git a/bird.conf b/bird.conf index 57df7ec7..ea7edf8d 100644 --- a/bird.conf +++ b/bird.conf @@ -6,6 +6,8 @@ router id 62.168.0.1 +define xyzzy = 120+10; + protocol rip MyRIP_test { - preference 130 + preference xyzzy; } diff --git a/conf/cf-lex.l b/conf/cf-lex.l index f653bcad..66f30382 100644 --- a/conf/cf-lex.l +++ b/conf/cf-lex.l @@ -101,7 +101,7 @@ WHITE [ \t] return SYM; } -[{}:;,] { +[={}:;,()+*/%-] { return yytext[0]; } @@ -177,6 +177,7 @@ cf_find_sym(byte *c, unsigned int h0) sym_hash[h] = s; s->class = SYM_VOID; s->def = NULL; + s->aux = 0; strcpy(s->name, c); return s; } diff --git a/conf/conf.h b/conf/conf.h index 0853ae8e..6a0a328d 100644 --- a/conf/conf.h +++ b/conf/conf.h @@ -21,12 +21,14 @@ extern int (*cf_read_hook)(byte *buf, unsigned int max); struct symbol { struct symbol *next; int class; + int aux; void *def; char name[1]; }; #define SYM_VOID 0 #define SYM_PROTO 1 +#define SYM_NUMBER 2 void cf_lex_init_tables(void); int cf_lex(void); diff --git a/conf/confbase.Y b/conf/confbase.Y index b20986ae..db6d0214 100644 --- a/conf/confbase.Y +++ b/conf/confbase.Y @@ -30,8 +30,17 @@ CF_DECLS %token SYM %token TEXT +%type expr + +%left '+' '-' +%left '*' '/' '%' + +CF_KEYWORDS(DEFINE) + CF_GRAMMAR +/* Basic config file structure */ + config: conf_entries END { return 0; } @@ -44,6 +53,28 @@ conf_entries: CF_ADDTO(conf, /* EMPTY */) +/* Expressions */ + +expr: + NUM + | expr '+' expr { $$ = $1 + $3; } + | expr '-' expr { $$ = $1 - $3; } + | expr '*' expr { $$ = $1 * $3; } + | expr '/' expr { if ($3) $$ = $1 / $3; else cf_error("Division by zero"); } + | expr '%' expr { if ($3) $$ = $1 % $3; else cf_error("Division by zero"); } + | '(' expr ')' { $$ = $2; } + | SYM { if ($1->class != SYM_NUMBER) cf_error("Number expected"); else $$ = $1->aux; } + ; + +CF_ADDTO(conf, definition) +definition: + DEFINE SYM '=' expr { + if ($2->class != SYM_VOID) cf_error("Symbol already defined"); + $2->class = SYM_NUMBER; + $2->aux = $4; + } + ; + CF_CODE CF_END diff --git a/nest/config.Y b/nest/config.Y index 1de0446b..697d43ec 100644 --- a/nest/config.Y +++ b/nest/config.Y @@ -54,9 +54,10 @@ proto_name: proto_item: /* EMPTY */ - | PREFERENCE NUM { + | PREFERENCE expr { if ($2 < 0 || $2 > 255) cf_error("Invalid preference"); this_proto->preference = $2; +die("pref=%d", $2); } ;