Я пытаюсь разобрать грамматику в ocamlyacc (почти так же, как в обычном yacc), который поддерживает функциональное приложение без операторов (например, в Ocaml или Haskell) и обычный ассортимент бинарных и унарных операторов. Я получаю конфликт уменьшения / уменьшения с оператором '-', который можно использовать как для вычитания, так и для отрицания. Вот пример грамматики, которую я использую:
%token <int> INT
%token <string> ID
%token MINUS
%start expr
%type <expr> expr
%nonassoc INT ID
%left MINUS
%left APPLY
%%
expr: INT
{ ExprInt $1 }
| ID
{ ExprId $1 }
| expr MINUS expr
{ ExprSub($1, $3) }
| MINUS expr
{ ExprNeg $2 }
| expr expr %prec APPLY
{ ExprApply($1, $2) };
Проблема в том, что когда вы получаете выражение типа "a - b", парсер не знает, должно ли оно быть уменьшено как "a (-b)" (отрицание b с последующим применением) или "a - б "(вычитание). Сокращение вычитания является правильным. Как мне разрешить конфликт в пользу этого правила?