From 3c1a8ef8f821586414879d14e8b6c45ef822007d Mon Sep 17 00:00:00 2001 From: Andrei Pelinescu-Onciul Date: Tue, 18 Sep 2001 04:56:43 +0000 Subject: [PATCH] - new config parser (not finished yet) --- cfg.lex | 252 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cfg.y | 183 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 435 insertions(+) create mode 100644 cfg.lex create mode 100644 cfg.y diff --git a/cfg.lex b/cfg.lex new file mode 100644 index 0000000000..d31c2b2c97 --- /dev/null +++ b/cfg.lex @@ -0,0 +1,252 @@ +/* + * $Id$ + * + * scanner for cfg files + */ + + +%{ + #include "cfg.tab.h" + #include + + /* states */ + #define INITIAL_S 0 + #define COMMENT_S 1 + #define COMMENT_LN_S 2 + #define STRING_S 3 + + + static int comment_nest=0; + static int state=0; + static char* str=0; + int line=0; + int column=0; + + static char* addstr(char*, char**); + static void count(); + + +%} + +/* start conditions */ +%x STRING1 STRING2 COMMENT COMMENT_LN + +/* action keywords */ +FORWARD forward +DROP drop +SEND send +LOG log +ERROR error +ROUTE route +/* condition keywords */ +METHOD method +URI uri +SRCIP src_ip +DSTIP dst_ip +/* operators */ +EQUAL = +EQUAL_T == +MATCH ~= +NOT ! +AND "and"|"&&"|"&" +OR "or"|"||"|"|" + +/* config vars. */ +DEBUG debug +FORK fork +LOGSTDERROR log_stderror +LISTEN listen +DNS dns +REV_DNS rev_dns + +/* values */ +YES "yes"|"true"|"on"|"enable" +NO "no"|"false"|"off"|"disable" + +LETTER [a-zA-Z] +DIGIT [0-9] +ALPHANUM {LETTER}|{DIGIT} +NUMBER {DIGIT}+ +ID {LETTER}{ALPHANUM}* +QUOTES \" +TICK \' +SLASH "/" +SEMICOLON ; +RPAREN \) +LPAREN \( +LBRACE \{ +RBRACE \} +LBRACK \[ +RBRACK \] +COMMA , +DOT \. +CR \n + + + +COM_LINE # +COM_START "/\*" +COM_END "\*/" + +EAT_ABLE [\ \t\b\r] + +%% + + +{EAT_ABLE} { count(); } + +{FORWARD} {count(); yylval.strval=yytext; return FORWARD; } +{DROP} { count(); yylval.strval=yytext; return DROP; } +{SEND} { count(); yylval.strval=yytext; return SEND; } +{LOG} { count(); yylval.strval=yytext; return LOG; } +{ERROR} { count(); yylval.strval=yytext; return ERROR; } +{ROUTE} { count(); yylval.strval=yytext; return ROUTE; } + +{METHOD} { count(); yylval.strval=yytext; return METHOD; } +{URI} { count(); yylval.strval=yytext; return URI; } +{SRCIP} { count(); yylval.strval=yytext; return SRCIP; } +{DSTIP} { count(); yylval.strval=yytext; return DSTIP; } + +{DEBUG} { count(); yylval.strval=yytext; return DEBUG; } +{FORK} { count(); yylval.strval=yytext; return FORK; } +{LOGSTDERROR} { yylval.strval=yytext; return LOGSTDERROR; } +{LISTEN} { count(); yylval.strval=yytext; return LISTEN; } +{DNS} { count(); yylval.strval=yytext; return DNS; } +{REV_DNS} { count(); yylval.strval=yytext; return REV_DNS; } + +{EQUAL} { count(); return EQUAL; } +{EQUAL_T} { count(); return EQUAL_T; } +{MATCH} { count(); return MATCH; } +{NOT} { count(); return NOT; } +{AND} { count(); return AND; } +{OR} { count(); return OR; } + +{NUMBER} { count(); yylval.intval=atoi(yytext); + return NUMBER; } +{YES} { count(); yylval.intval=1; return NUMBER; } +{NO} { count(); yylval.intval=0; return NUMBER; } + +{COMMA} { count(); return COMMA; } +{SEMICOLON} { count(); return SEMICOLON; } +{RPAREN} { count(); return RPAREN; } +{LPAREN} { count(); return LPAREN; } +{LBRACE} { count(); return LBRACE; } +{RBRACE} { count(); return RBRACE; } +{LBRACK} { count(); return LBRACK; } +{RBRACK} { count(); return RBRACK; } +{SLASH} { count(); return SLASH; } +{DOT} { count(); return DOT; } +\\{CR} {count(); } /* eat the escaped CR */ +{CR} { count(); return CR; } + + +{QUOTES} { count(); state=STRING_S; BEGIN(STRING1); } +{TICK} { count(); state=STRING_S; BEGIN(STRING2); } + + +{QUOTES} { count(); state=INITIAL_S; BEGIN(INITIAL); + yytext[yyleng-1]=0; yyleng--; + 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; + } +{TICK} { count(); state=INITIAL_S; BEGIN(INITIAL); + yytext[yyleng-1]=0; yyleng--; + printf("Found string1 <%s>\n", yytext); + yylval.strval=yytext; return STRING; + } +.|{EAT_ABLE}|{CR} { yymore(); } + +\\n { count(); yytext[yyleng-2]='\n';yytext[yyleng-1]=0; + yyleng--; addstr(yytext, &str); } +\\t { count(); yytext[yyleng-2]='\t';yytext[yyleng-1]=0; + yyleng--; addstr(yytext, &str); } +\\\\ { count(); yytext[yyleng-2]='\\';yytext[yyleng-1]=0; + yyleng--; addstr(yytext, &str); } +.|{EAT_ABLE}|{CR} { yymore(); } + + +{COM_START} { count(); comment_nest++; state=COMMENT_S; + BEGIN(COMMENT); } +{COM_END} { count(); comment_nest--; + if (comment_nest==0){ + state=INITIAL_S; + BEGIN(INITIAL); + } + } +.|{EAT_ABLE}|{CR} { count(); }; + +{COM_LINE}.*{CR} { count(); } + +{ID} { count(); yylval.strval=yytext; return ID; } + + +<> { + switch(state){ + case STRING_S: + printf("Unexpected EOF: closed string\n"); + if (str) {free(str); str=0;} + break; + case COMMENT_S: + printf("Unexpected EOF:%d comments open\n", comment_nest); + break; + case COMMENT_LN_S: + printf("Unexpected EOF: comment line open\n"); + break; + } + return 0; + } + +%% + +static char* addstr(char * src, char ** dest) +{ + char *tmp; + int len1, len2; + + if (*dest==0){ + *dest=strdup(src); + }else{ + len1=strlen(*dest); + len2=strlen(src); + tmp=malloc(len1+len2+1); + if (tmp==0) goto error; + memcpy(tmp, *dest, len1); + memcpy(tmp+len1, src, len2); + tmp[len1+len2]=0; + free(*dest); + *dest=tmp; + } + return *dest; +error: + fprintf(stderr, "lex:addstr: memory allocation error\n"); + return 0; +} + + + +static void count() +{ + int i; + + for (i=0; i <>\n");} + | statement {printf("got a statement<>\n"); } + ; + +statement: assign_stm CR + | 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 + ; + + +ipv4: NUMBER DOT NUMBER DOT NUMBER DOT NUMBER + ; + +route_stm: ROUTE LBRACE rules RBRACE | + ROUTE LBRACK NUMBER RBRACK LBRACE rules RBRACE + ; + +rules: rules rule | + rule + ; + +rule: condition actions CR + | CR /* null rule */ + ; + +condition: exp_elem | + LPAREN exp RPAREN + ; + +exp: exp AND condition | + exp OR condition | + NOT condition | + condition + ; + +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 + ; + +net4: ipv4 SLASH ipv4 | + ipv4 SLASH NUMBER | + ipv4 + ; + +host: ID | + host DOT ID + ; + + +actions: actions action | + action + ; + +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 + ; + + +%% + +extern int line; +extern int column; +yyerror(char* s) +{ + fprintf(stderr, "parse error (%d,%d): %s\n", line, column, s); +} + +int main(int argc, char ** argv) +{ + if (yyparse()!=0) + fprintf(stderr, "parsing error\n"); +} -- 2.20.1