aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/ip
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-12-30 15:56:36 +0000
committerrsc <devnull@localhost>2005-12-30 15:56:36 +0000
commite72e360a1a5a74d85a721b8405790593b033277b (patch)
tree2d63c49926c1ae7d06622d059792152d4087e1de /src/cmd/ip
parent3f6a501b4d661acb8dba53d8a857e963aad2fe6b (diff)
downloadplan9port-e72e360a1a5a74d85a721b8405790593b033277b.tar.gz
plan9port-e72e360a1a5a74d85a721b8405790593b033277b.tar.bz2
plan9port-e72e360a1a5a74d85a721b8405790593b033277b.zip
forgot this
Diffstat (limited to 'src/cmd/ip')
-rwxr-xr-xsrc/cmd/ip/snoopy/filter.y107
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");
+}