filter.y (1774B)
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 || *yylp == 0) 68 return 0; 69 while(isspace(*yylp)) 70 yylp++; 71 72 yylval = newfilter(); 73 74 p = strpbrk(yylp, "!|&()= "); 75 if(p == 0){ 76 yylval->op = WORD; 77 yylval->s = strdup(yylp); 78 if(yylval->s == nil) 79 sysfatal("parsing filter: %r"); 80 yylp = nil; 81 return WORD; 82 } 83 c = *p; 84 if(p != yylp){ 85 yylval->op = WORD; 86 *p = 0; 87 yylval->s = strdup(yylp); 88 if(yylval->s == nil) 89 sysfatal("parsing filter: %r"); 90 *p = c; 91 yylp = p; 92 return WORD; 93 } 94 95 yylp++; 96 if(c == '!' && *yylp == '='){ 97 c = NE; 98 yylp++; 99 } 100 else if(c == '&' && *yylp == '&'){ 101 c = LAND; 102 yylp++; 103 } 104 else if(c == '|' && *yylp == '|'){ 105 c = LOR; 106 yylp++; 107 } 108 yylval->op = c; 109 return c; 110 } 111 112 void 113 yyerror(char *e) 114 { 115 USED(e); 116 // longjmp(errjmp, 1); 117 sysfatal("error parsing filter"); 118 }