For example, consider the filter:
event=* AND
NOT event=foo AND
NOT event=bar AND
NOT event=baz
The "NOT" operator is supposed to be bound to the comparisons to the
immediate right. That is, it supposed to be equivalent to:
event=* AND
(NOT event=foo) AND
(NOT event=bar) AND
(NOT event=baz)
Both of these should produce the following parse tree:
AND
AND
AND
EQ EVENT '*'
NOT
EQ EVENT 'foo'
NOT
EQ EVENT 'bar'
NOT
EQ EVENT 'baz'
Instead, before this commit, the NOTs were getting bound to the entire
sub-expression to the right. Therefore, the original filter expression
was being parsed as if it were:
event=* AND
NOT (event=foo AND
NOT (event=bar AND
NOT event=baz))
Which produced the following parse tree:
AND
EQ EVENT '*'
NOT
AND
EQ EVENT 'foo'
NOT
AND
EQ EVENT 'bar'
NOT
EQ EVENT 'baz'
%type <op> op
%type <node> expr key_value
-%precedence NOT
%left AND OR
+%right NOT
%%
filter : expr { state->output = $1; }