| tforgot this - plan9port - [fork] Plan 9 from user space | |
| git clone git://src.adamsgaard.dk/plan9port | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| commit e72e360a1a5a74d85a721b8405790593b033277b | |
| parent 3f6a501b4d661acb8dba53d8a857e963aad2fe6b | |
| Author: rsc <devnull@localhost> | |
| Date: Fri, 30 Dec 2005 15:56:36 +0000 | |
| forgot this | |
| Diffstat: | |
| A src/cmd/ip/snoopy/filter.y | 107 +++++++++++++++++++++++++++++… | |
| 1 file changed, 107 insertions(+), 0 deletions(-) | |
| --- | |
| diff --git a/src/cmd/ip/snoopy/filter.y b/src/cmd/ip/snoopy/filter.y | |
| t@@ -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"); | |
| +} |