summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>1998-11-27 22:32:45 +0100
committerMartin Mares <mj@ucw.cz>1998-11-27 22:32:45 +0100
commit0b62c3a7c7548cd447b4f18e0346cc9e74862ab3 (patch)
treeb74b1a9ffa4f59b7d86765eac906c67827e83a12
parentc74c0e3cdf008988a8873d3f76c0d71b29ab8673 (diff)
downloadbird-0b62c3a7c7548cd447b4f18e0346cc9e74862ab3.tar
bird-0b62c3a7c7548cd447b4f18e0346cc9e74862ab3.zip
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 :-)
-rw-r--r--TODO6
-rw-r--r--bird.conf4
-rw-r--r--conf/cf-lex.l3
-rw-r--r--conf/conf.h2
-rw-r--r--conf/confbase.Y31
-rw-r--r--nest/config.Y3
6 files changed, 42 insertions, 7 deletions
diff --git a/TODO b/TODO
index 37adde9..ba760b8 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 57df7ec..ea7edf8 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 f653bca..66f3038 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 0853ae8..6a0a328 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 b20986a..db6d021 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -30,8 +30,17 @@ CF_DECLS
%token <s> SYM
%token <t> TEXT
+%type <i> 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 1de0446..697d43e 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);
}
;