filter.y 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  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)
  62. return 0;
  63. while(isspace(*yylp))
  64. yylp++;
  65. if(*yylp == 0)
  66. return 0;
  67. yylval = newfilter();
  68. p = strpbrk(yylp, "!|&()= ");
  69. if(p == 0){
  70. yylval->op = WORD;
  71. yylval->s = strdup(yylp);
  72. if(yylval->s == nil)
  73. sysfatal("parsing filter: %r");
  74. yylp = nil;
  75. return WORD;
  76. }
  77. c = *p;
  78. if(p != yylp){
  79. yylval->op = WORD;
  80. *p = 0;
  81. yylval->s = strdup(yylp);
  82. if(yylval->s == nil)
  83. sysfatal("parsing filter: %r");
  84. *p = c;
  85. yylp = p;
  86. return WORD;
  87. }
  88. yylp++;
  89. if(c == '!' && *yylp == '='){
  90. c = NE;
  91. yylp++;
  92. }
  93. else if(c == '&' && *yylp == '&'){
  94. c = LAND;
  95. yylp++;
  96. }
  97. else if(c == '|' && *yylp == '|'){
  98. c = LOR;
  99. yylp++;
  100. }
  101. yylval->op = c;
  102. return c;
  103. }
  104. void
  105. yyerror(char*)
  106. {
  107. sysfatal("error parsing filter");
  108. }