瀏覽代碼

- started to build the expresion & acion tree/list

Andrei Pelinescu-Onciul 24 年之前
父節點
當前提交
c07508e2e1
共有 4 個文件被更改,包括 426 次插入67 次删除
  1. 6 6
      cfg.lex
  2. 153 61
      cfg.y
  3. 210 0
      route_struct.c
  4. 57 0
      route_struct.h

+ 6 - 6
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(); }
 

+ 153 - 61
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"); }
 	;
 
 

+ 210 - 0
route_struct.c

@@ -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("); ");
+	}
+}
+			
+	
+
+	
+	
+

+ 57 - 0
route_struct.h

@@ -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
+