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 yylex(void)62yylex(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 yyerror(char *)115yyerror(char*) 116 { 117 sysfatal("error parsing filter"); 118 } 119