diff options
author | rsc <devnull@localhost> | 2005-12-30 15:56:36 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-12-30 15:56:36 +0000 |
commit | e72e360a1a5a74d85a721b8405790593b033277b (patch) | |
tree | 2d63c49926c1ae7d06622d059792152d4087e1de /src/cmd/ip | |
parent | 3f6a501b4d661acb8dba53d8a857e963aad2fe6b (diff) | |
download | plan9port-e72e360a1a5a74d85a721b8405790593b033277b.tar.gz plan9port-e72e360a1a5a74d85a721b8405790593b033277b.tar.bz2 plan9port-e72e360a1a5a74d85a721b8405790593b033277b.zip |
forgot this
Diffstat (limited to 'src/cmd/ip')
-rwxr-xr-x | src/cmd/ip/snoopy/filter.y | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/src/cmd/ip/snoopy/filter.y b/src/cmd/ip/snoopy/filter.y new file mode 100755 index 00000000..d34bfc7c --- /dev/null +++ b/src/cmd/ip/snoopy/filter.y @@ -0,0 +1,107 @@ +%{ +#include <u.h> +#include <libc.h> +#include <ctype.h> +#include "dat.h" + +char *yylp; /* next character to be lex'd */ +char *yybuffer; +char *yyend; /* end of buffer to be parsed */ +%} + +%term LOR +%term LAND +%term WORD +%right '!' +%left '|' +%left '&' +%left LOR +%left LAND +%start filter +%% + +filter : expr + { filter = $$; } + ; +expr : WORD + { $$ = $1; } + | WORD '=' WORD + { $2->l = $1; $2->r = $3; $$ = $2; } + | WORD '(' expr ')' + { $1->l = $3; free($2); free($4); $$ = $1; } + | '(' expr ')' + { free($1); free($3); $$ = $2; } + | expr LOR expr + { $2->l = $1; $2->r = $3; $$ = $2; } + | expr LAND expr + { $2->l = $1; $2->r = $3; $$ = $2; } + | '!' expr + { $1->l = $2; $$ = $1; } + ; +%% + +/* + * Initialize the parsing. Done once for each header field. + */ +void +yyinit(char *p) +{ + yylp = p; +} + +int +yylex(void) +{ + char *p; + int c; + + if(yylp == nil || *yylp == 0) + return 0; + while(isspace(*yylp)) + yylp++; + + yylval = newfilter(); + + p = strpbrk(yylp, "!|&()= "); + if(p == 0){ + yylval->op = WORD; + yylval->s = strdup(yylp); + if(yylval->s == nil) + sysfatal("parsing filter: %r"); + yylp = nil; + return WORD; + } + c = *p; + if(p != yylp){ + yylval->op = WORD; + *p = 0; + yylval->s = strdup(yylp); + if(yylval->s == nil) + sysfatal("parsing filter: %r"); + *p = c; + yylp = p; + return WORD; + } + + yylp++; + if(*yylp == c) + switch(c){ + case '&': + c = LAND; + yylp++; + break; + case '|': + c = LOR; + yylp++; + break; + } + yylval->op = c; + return c; +} + +void +yyerror(char *e) +{ + USED(e); + sysfatal("error parsing filter"); +} |