]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ip/snoopy/filter.y
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / cmd / ip / snoopy / filter.y
1 %{
2 #include <u.h>
3 #include <libc.h>
4 #include <ctype.h>
5 #include "dat.h"
6
7 char    *yylp;          /* next character to be lex'd */
8 char    *yybuffer;
9 char    *yyend;         /* end of buffer to be parsed */
10 %}
11
12 %term LOR
13 %term LAND
14 %term WORD
15 %term NE
16 %right '!'
17 %left '|'
18 %left '&'
19 %left LOR
20 %left LAND
21 %start filter
22 %%
23
24 filter          : expr
25                         { filter = $$; }
26                 ;
27 expr            : WORD
28                         { $$ = $1; }
29                 | WORD '=' WORD
30                         { $2->l = $1; $2->r = $3; $$ = $2; }
31                 | WORD NE WORD
32                         { $2->l = newfilter();
33                           $2->l->op = '=';
34                           $2->l->l = $1;
35                           $2->l->r = $3;
36                           $2->op = '!';
37                           $$ = $2;
38                         }
39                 | WORD '(' expr ')'
40                         { $1->l = $3; free($2); free($4); $$ = $1; }
41                 | '(' expr ')'
42                         { free($1); free($3); $$ = $2; }
43                 | expr LOR expr
44                         { $2->l = $1; $2->r = $3; $$ = $2; }
45                 | expr LAND expr
46                         { $2->l = $1; $2->r = $3; $$ = $2; }
47                 | '!' expr
48                         { $1->l = $2; $$ = $1; }
49                 ;
50 %%
51
52 /*
53  *  Initialize the parsing.  Done once for each header field.
54  */
55 void
56 yyinit(char *p)
57 {
58         yylp = p;
59 }
60
61 int
62 yylex(void)
63 {
64         char *p;
65         int c;
66
67         if(yylp == nil)
68                 return 0;
69         while(isspace(*yylp))
70                 yylp++;
71         if(*yylp == 0)
72                 return 0;
73
74         yylval = newfilter();
75
76         p = strpbrk(yylp, "!|&()= ");
77         if(p == 0){
78                 yylval->op = WORD;
79                 yylval->s = strdup(yylp);
80                 if(yylval->s == nil)
81                         sysfatal("parsing filter: %r");
82                 yylp = nil;
83                 return WORD;
84         }
85         c = *p;
86         if(p != yylp){
87                 yylval->op = WORD;
88                 *p = 0;
89                 yylval->s = strdup(yylp);
90                 if(yylval->s == nil)
91                         sysfatal("parsing filter: %r");
92                 *p = c;
93                 yylp = p;
94                 return WORD;
95         }
96
97         yylp++;
98         if(c == '!' && *yylp == '='){
99                 c = NE;
100                 yylp++;
101         }
102         else if(c == '&' && *yylp == '&'){
103                 c = LAND;
104                 yylp++;
105         }
106         else if(c == '|' && *yylp == '|'){
107                 c = LOR;
108                 yylp++;
109         }
110         yylval->op = c;
111         return c;
112 }
113
114 void
115 yyerror(char*)
116 {
117         sysfatal("error parsing filter");
118 }