- started to build the expresion & acion tree/list
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 19 Sep 2001 02:19:09 +0000 (02:19 +0000)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 19 Sep 2001 02:19:09 +0000 (02:19 +0000)
cfg.lex
cfg.y
route_struct.c [new file with mode: 0644]
route_struct.h [new file with mode: 0644]

diff --git a/cfg.lex b/cfg.lex
index d31c2b2..6581c69 100644 (file)
--- a/cfg.lex
+++ b/cfg.lex
@@ -149,19 +149,19 @@ EAT_ABLE  [\ \t\b\r]
                                                addstr(yytext, &str);
                                                if (str){
                                                        printf("Found string1 <%s>\n", str);
-                                                       yyleng=strlen(str)+1;
-                                                       memcpy(yytext, str, yyleng);
-                                                       free(str);
-                                                       str=0;
                                                }else{
                                                        printf("WARNING: empty string\n");
                                                }
-                                               yylval.strval=yytext; return STRING;
+                                               yylval.strval=str; str=0;
+                                               return STRING;
                                        }
 <STRING2>{TICK}  { count(); state=INITIAL_S; BEGIN(INITIAL); 
                                                yytext[yyleng-1]=0; yyleng--;
                                                printf("Found string1 <%s>\n", yytext);
-                                               yylval.strval=yytext; return STRING;
+                                               addstr(yytext, &str);
+                                               yylval.strval=str;
+                                               str=0;
+                                               return STRING;
                                        }
 <STRING2>.|{EAT_ABLE}|{CR}     { yymore(); }
 
diff --git a/cfg.y b/cfg.y
index 05e7ccb..73ad635 100644 (file)
--- a/cfg.y
+++ b/cfg.y
@@ -6,11 +6,15 @@
 
 %{
 
+#include "route_struct.h"
+
 %}
 
 %union {
        int intval;
        char* strval;
+       struct expr* expr;
+       struct action* action;
 }
 
 /* terminals */
@@ -46,9 +50,9 @@
 %left OR
 
 /* values */
-%token NUMBER
-%token ID
-%token STRING
+%token <intval> NUMBER
+%token <strval> ID
+%token <strval> STRING
 
 /* other */
 %token COMMA
@@ -65,6 +69,8 @@
 
 
 /*non-terminals */
+%type <expr> exp, condition,  exp_elem
+%type <action> action, actions, cmd
 
 
 
@@ -75,95 +81,181 @@ cfg:       statements
        ;
 
 statements:    statements statement {printf("got <> <>\n");}
-                       | statement {printf("got a statement<>\n"); }
+               | statement {printf("got a statement<>\n"); }
+               | statements error { yyerror(""); }
        ;
 
 statement:     assign_stm CR
-                       | route_stm CR
-                       | CR    /* null statement*/
+               | route_stm CR
+               | CR    /* null statement*/
        ;
 
-assign_stm:    DEBUG EQUAL NUMBER |
-                       FORK  EQUAL NUMBER |
-                       LOGSTDERROR EQUAL NUMBER |
-                       DNS EQUAL NUMBER |
-                       REV_DNS EQUAL NUMBER |
-                       LISTEN EQUAL ipv4 |
-                       LISTEN EQUAL ID |
-                       LISTEN EQUAL STRING 
+assign_stm:    DEBUG EQUAL NUMBER 
+               | DEBUG EQUAL error  { yyerror("number  expected"); }
+               | FORK  EQUAL NUMBER
+               | FORK  EQUAL error  { yyerror("boolean value expected"); }
+               | LOGSTDERROR EQUAL NUMBER 
+               | LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
+               | DNS EQUAL NUMBER
+               | DNS EQUAL error { yyerror("boolean value expected"); }
+               | REV_DNS EQUAL NUMBER 
+               | REV_DNS EQUAL error { yyerror("boolean value expected"); }
+               | LISTEN EQUAL ipv4 
+               | LISTEN EQUAL ID 
+               | LISTEN EQUAL STRING
+               | LISTEN EQUAL  error { yyerror("ip address or hostname"
+                                               "expected"); }
+               | error EQUAL { yyerror("unknown config variable"); }
        ;
 
 
 ipv4:  NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
        ;
 
-route_stm:     ROUTE LBRACE rules RBRACE |
-                       ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE
+route_stm:     ROUTE LBRACE rules RBRACE 
+               | ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE
+               | ROUTE error { yyerror("invalid  route  statement"); }
        ;
 
-rules: rules rule |
-               rule
+rules: rules rule
+       | rule
+       | rules error { yyerror("invalid rule"); }
         ;
 
 rule:  condition       actions CR
-               | CR  /* null rule */
+       | CR  /* null rule */
+       | condition error { yyerror("bad actions in rule"); }
        ;
 
-condition:     exp_elem |
-                       LPAREN exp RPAREN
+condition:     exp
        ;
 
-exp:   exp AND condition |
-               exp OR  condition |
-               NOT condition |
-               condition
+exp:   exp AND exp 
+       | exp OR  exp 
+       | NOT exp 
+       | LPAREN exp RPAREN
+       | exp_elem
        ;
 
-exp_elem:      METHOD EQUAL_T STRING |
-                       METHOD EQUAL_T ID |
-                       METHOD MATCH STRING |
-                       METHOD MATCH ID |
-                       URI EQUAL_T STRING |
-                       URI EQUAL_T ID |
-                       URI MATCH STRING |
-                       URI MATCH ID |
-                       SRCIP EQUAL_T net4 |
-                       SRCIP EQUAL_T STRING |
-                       SRCIP EQUAL_T host |
-                       SRCIP MATCH STRING 
-                       DSTIP EQUAL_T net4 |
-                       DSTIP EQUAL_T STRING |
-                       DSTIP MATCH STRING
+exp_elem:      METHOD EQUAL_T STRING   {$$= mk_elem(   EQUAL_OP,
+                                                       STRING_ST, 
+                                                       METHOD_O,
+                                                       $3);
+                                       }
+               | METHOD EQUAL_T ID     {$$ = mk_elem(  EQUAL_OP,
+                                                       STRING_ST,
+                                                       METHOD_O,
+                                                       $3); 
+                                       }
+               | METHOD EQUAL_T error { $$=0; yyerror("string expected"); }
+               | METHOD MATCH STRING   {$$ = mk_elem(  MATCH_OP,
+                                                       STRING_ST,
+                                                       METHOD_O,
+                                                       $3); 
+                                       }
+               | METHOD MATCH ID       {$$ = mk_elem(  MATCH_OP,
+                                                       STRING_ST,
+                                                       METHOD_O,
+                                                       $3); 
+                                       }
+               | METHOD MATCH error { $$=0; yyerror("string expected"); }
+               | METHOD error  { $$=0; 
+                                 yyerror("invalid operator,"
+                                               "== or ~= expected");
+                               }
+               | URI EQUAL_T STRING    {$$ = mk_elem(  EQUAL_OP,
+                                                       STRING_ST,
+                                                       URI_O,
+                                                       $3); 
+                                       }
+               | URI EQUAL_T ID        {$$ = mk_elem(  EQUAL_OP,
+                                                       STRING_ST,
+                                                       URI_O,
+                                                       $3); 
+                                       }
+               | URI EQUAL_T error { $$=0; yyerror("string expected"); }
+               | URI MATCH STRING 
+               | URI MATCH ID
+               | URI MATCH error {  $$=0; yyerror("string expected"); }
+               | URI error     { $$=0; 
+                                 yyerror("invalid operator,"
+                                               " == or ~= expected");
+                               }
+               | SRCIP EQUAL_T net4 
+               | SRCIP EQUAL_T STRING 
+               | SRCIP EQUAL_T host
+               | SRCIP EQUAL_T error { yyerror( "ip address or hostname"
+                                                "expected" ); }
+               | SRCIP MATCH STRING
+               | SRCIP MATCH ID
+               | SRCIP MATCH error  { yyerror( "hostname expected"); }
+               | SRCIP error  {yyerror("invalid operator, == or ~= expected");}
+               | DSTIP EQUAL_T net4 
+               | DSTIP EQUAL_T STRING
+               | DSTIP EQUAL_T host
+               | DSTIP EQUAL_T error { yyerror( "ip address or hostname"
+                                                "expected" ); }
+               | DSTIP MATCH STRING
+               | DSTIP MATCH ID
+               | DSTIP MATCH error  { yyerror ( "hostname  expected" ); }
+               | DSTIP error {yyerror("invalid operator, == or ~= expected");}
        ;
 
-net4:  ipv4 SLASH ipv4 |
-               ipv4 SLASH NUMBER |
-               ipv4
+net4:  ipv4 SLASH ipv4 
+       | ipv4 SLASH NUMBER 
+       | ipv4
+       | ipv4 SLASH error {yyerror("netmask (eg:255.0.0.0 or 8) expected");}
        ;
 
-host:  ID |
-               host DOT ID
+host:  ID
+       | host DOT ID
+       | host DOT error { yyerror("invalid hostname"); }
        ;
 
 
-actions:       actions action |
-                       action
+actions:       actions action 
+               | action
+               | actions error { yyerror("bad command"); }
+       ;
+
+action:                cmd SEMICOLON
+               | SEMICOLON /* null action */
+               | cmd error { yyerror("bad command: missing ';'?"); }
        ;
 
-action:                cmd SEMICOLON |
-                       SEMICOLON /* null action */
-
-cmd:           FORWARD LPAREN host RPAREN |
-                       FORWARD LPAREN STRING RPAREN |
-                       FORWARD LPAREN ipv4 RPAREN |
-                       SEND LPAREN host RPAREN |
-                       SEND LPAREN STRING RPAREN |
-                       SEND LPAREN ipv4 RPAREN |
-                       DROP LPAREN RPAREN |
-                       DROP |
-                       LOG LPAREN STRING RPAREN |
-                       ERROR LPAREN STRING COMMA STRING RPAREN |
-                       ROUTE LPAREN NUMBER RPAREN
+cmd:           FORWARD LPAREN host RPAREN 
+               | FORWARD LPAREN STRING RPAREN 
+               | FORWARD LPAREN ipv4 RPAREN 
+               | FORWARD LPAREN host COMMA NUMBER RPAREN
+               | FORWARD LPAREN STRING COMMA NUMBER RPAREN
+               | FORWARD LPAREN ipv4 COMMA NUMBER RPAREN
+               | FORWARD error { yyerror("missing '(' or ')' ?"); }
+               | FORWARD LPAREN error RPAREN { yyerror("bad forward"
+                                               "argument"); }
+               | SEND LPAREN host RPAREN 
+               | SEND LPAREN STRING RPAREN 
+               | SEND LPAREN ipv4 RPAREN
+               | SEND LPAREN host COMMA NUMBER RPAREN
+               | SEND LPAREN STRING COMMA NUMBER RPAREN
+               | SEND LPAREN ipv4 COMMA NUMBER RPAREN
+               | SEND error { yyerror("missing '(' or ')' ?"); }
+               | SEND LPAREN error RPAREN { yyerror("bad send"
+                                               "argument"); }
+               | DROP LPAREN RPAREN 
+               | DROP 
+               | LOG LPAREN STRING RPAREN
+               | LOG LPAREN NUMBER COMMA STRING RPAREN
+               | LOG error { yyerror("missing '(' or ')' ?"); }
+               | LOG LPAREN error RPAREN { yyerror("bad log"
+                                               "argument"); }
+               | ERROR LPAREN STRING COMMA STRING RPAREN 
+               | ERROR error { yyerror("missing '(' or ')' ?"); }
+               | ERROR LPAREN error RPAREN { yyerror("bad error"
+                                               "argument"); }
+               | ROUTE LPAREN NUMBER RPAREN
+               | ROUTE error { yyerror("missing '(' or ')' ?"); }
+               | ROUTE LPAREN error RPAREN { yyerror("bad route"
+                                               "argument"); }
        ;
 
 
diff --git a/route_struct.c b/route_struct.c
new file mode 100644 (file)
index 0000000..07c1758
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * $Id$
+ *
+ * route structures helping functions
+ */
+
+
+#include  "route_struct.h"
+
+#include <stdio.h>
+
+struct expr* mk_exp(int op, struct expr* left, struct expr* right)
+{
+       struct expr * e;
+       e=(struct expr*)malloc(sizeof (struct expr));
+       if (e==0) goto error;
+       e->type=EXP_T;
+       e->op=op;
+       e->l.expr=left;
+       e->r.expr=right;
+       return e;
+error:
+       fprintf(stderr, "ERROR: mk_exp: memory allocation failure\n");
+       return 0;
+}
+
+
+struct expr* mk_elem(int op, int subtype, int operand, void* param)
+{
+       struct expr * e;
+       e=(struct expr*)malloc(sizeof (struct expr));
+       if (e==0) goto error;
+       e->type=ELEM_T;
+       e->op=op;
+       e->subtype=subtype;
+       e->l.operand=operand;
+       e->r.param=param;
+       return e;
+error:
+       fprintf(stderr, "ERROR: mk_elem: memory allocation failure\n");
+       return 0;
+}
+
+
+
+struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2)
+{
+       struct action* a;
+       a=(struct action*)malloc(sizeof(struct action));
+       if (a==0) goto  error;
+       a->type=type;
+       a->p1_type=p1_type;
+       a->p2_type=p2_type;
+       a->p1.string=(char*) p1;
+       a->p2.string=(char*) p2;
+       a->next=0;
+       return a;
+       
+error:
+       fprintf(stderr, "ERROR: mk_action: memory allocation failure\n");
+       return 0;
+
+}
+
+
+struct action* append_action(struct action* a, struct action* b)
+{
+       struct action *t;
+       if (b==0) return a;
+       if (a==0) return b;
+       
+       for(t=a;t->next;t=t->next);
+       t->next=b;
+       return a;
+}
+
+       
+       
+void print_expr(struct expr* exp)
+{
+       if (exp==0){
+               fprintf(stderr, "ERROR: print_expr: null expression!\n");
+               return;
+       }
+       if (exp->type==ELEM_T){
+               switch(exp->l.operand){
+                       case METHOD_O:
+                               printf("method");
+                               break;
+                       case URI_O:
+                               printf("uri");
+                               break;
+                       case SRCIP_O:
+                               printf("srcip");
+                               break;
+                       case DSTIP_O:
+                               printf("dstip");
+                               break;
+                       default:
+                               printf("UNKNOWN");
+               }
+               switch(exp->op){
+                       case EQUAL_OP:
+                               printf("==");
+                               break;
+                       case MATCH_OP:
+                               printf("~=");
+                       default:
+                               priint("<UNKNOWN>");
+               }
+               switch(exp->subtype){
+                       case NOSUBTYPE: 
+                                       printf("N/A");
+                                       break;
+                       case STRING_ST:
+                                       printf("\"%s\"", (char*)exp->r.param);
+                                       break;
+                       case NET_ST:
+                                       printf("");
+                                       break;
+                       default:
+                                       prinf("UNKNOWN");
+               }
+       }else if (exp->type==EXP_T){
+               switch(exp->op){
+                       case AND_OP:
+                                       printf("AND( ");
+                                       print_expr(exp->l.expr);
+                                       printf(", ");
+                                       print_expr(exp->r.expr);
+                                       printf(" )");
+                                       break;
+                       case OR_OP:
+                                       printf("OR( ");
+                                       print_expr(exp->l.expr);
+                                       printf(", ");
+                                       print_expr(exp->r.expr);
+                                       printf(" )");
+                                       break;
+                       case NOT_OP:    
+                                       printf("NOT( ");
+                                       print_expr(exp->l.expr);
+                                       printf(" )");
+                                       break;
+                       default:
+                                       printf("UNKNOWN_EXP ");
+               }
+                                       
+       }else{
+               printf("ERROR:print_expr: unknown type\n");
+       }
+}
+                                       
+
+                                       
+
+void print_action(struct action* a)
+{
+       struct action* t;
+       for(t=a; t!=0;t=t->next){
+               switch(t->type){
+                       case FORWARD_T:
+                                       printf("forward(");
+                                       break;
+                       case SEND_T:
+                                       printf("send(");
+                                       break;
+                       case DROP_T:
+                                       printf("drop(");
+                                       break;
+                       case LOG_T:
+                                       printf("log(");
+                                       break;
+                       case ERROR_T:
+                                       printf("error(");
+                                       break;
+                       default:
+                                       printf("UNKNOWN(");
+               }
+               switch(t->p1_type){
+                       case STRING_ST:
+                                       printf("\"%s\"", t->p1.string);
+                                       break;
+                       case NUMBER_ST:
+                                       printf("%d",t->p1.number);
+                                       break;
+                       default:
+                                       printf("type<%d>", t->p1_type);
+               }
+               switch(t->p2_type){
+                       case NOSUBTYPE:
+                                       break;
+                       case STRING_ST:
+                                       printf(", \"%s\"", t->p2.string);
+                                       break;
+                       case NUMBER_ST:
+                                       printf(", %d",t->p2.number);
+                                       break;
+                       default:
+                                       printf(", type<%d>", t->p2_type);
+               }
+               printf("); ");
+       }
+}
+                       
+       
+
+       
+       
+
diff --git a/route_struct.h b/route_struct.h
new file mode 100644 (file)
index 0000000..1e93596
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ */
+
+#ifndef route_struct_h
+#define route_struct_h
+
+enum { EXP_T=1, ELEM_T };
+enum { AND_OP=1, OR_OP, NOT_OP };
+enum { EQUAL_OP=10, MATCH_OP };
+enum { METHOD_O=1, URI_O, SRCIP_O, DSTIP_O };
+
+enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T};
+enum { NOSUBTYPE=0, STRING_ST, NET_ST, NUMBER_ST, IP_ST };
+
+       
+struct expr{
+       int type; /* exp, exp_elem */
+       int op; /* and, or, not | ==,  ~= */
+       int  subtype;
+       union {
+               struct expr* expr;
+               int operand;
+       }l;
+       union {
+               struct expr* expr;
+               void* param;
+       }r;
+};
+
+
+struct action{
+       int type;  /* forward, drop, log, send ...*/
+       int p1_type;
+       int p2_type;
+       union {
+               int number;
+               char* string;
+               void* data;
+       }p1, p2;
+       struct action* next;
+};
+
+struct expr* mk_exp(int op, struct expr* left, struct expr* right);
+struct expr* mk_elem(int op, int subtype, int operand, void* param);
+struct action* mk_action(int type, int p1_type, int p2_type, void* p1, void* p2);
+
+void print_action(struct action* a);
+void print_expr(struct expr* exp);
+
+
+
+
+
+#endif
+