Ваша проблема в том, что у вас есть expr OP INTEGER
для каждого правила.
То, как вы это делаете, зубр анализирует как:
expr * 2 -> (4 + 5) * 2
Это заставляет приоритет идти влево, а не приоритет, определяемый вашими правилами приоритета.
Приоритет применяется только тогда, когда есть более одного способа для анализа текста, вместо того, что у вас есть, попробуйте
expr : expr '+' expr {$$ = $1 + $3;}
| expr '-' expr {$$ = $1 - $3;}
| expr '*' expr {$$ = $1 * $3;}
| INTEGER {$$ = $1;}
;
Таким образом, 5 + 4 * 2
может быть проанализирован как ((5 + 4) * 2)
или (5 + (4 * 2))
, и зубр сверится с приоритетом для определения правильного анализа.