filter.y 1.7 KB

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