URI: 
       tforgot this - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit e72e360a1a5a74d85a721b8405790593b033277b
   DIR parent 3f6a501b4d661acb8dba53d8a857e963aad2fe6b
  HTML 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(-)
       ---
   DIR 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");
       +}