Hello,
I’ve been trying to create parser for a subset of Julia, but I have an odd conflict that I can’t seem to resolve.
The minimal grammar I use is :
expr := CST x
| SUB expr
| expr SUB expr
| WHILE expr bloc END
bloc := List of expr? separated by ;
Unary minus has higher precedence than binary.
Here is a short code providing a conflict :
%{
open Ast
open Lexing
%}
%token WHILE END
%token <int> CST
%token SUB
%token SEMICOLON
%left SUB
%nonassoc unary_minus
%start expr
%type <Ast.expr> expr
%%
expr:
e = exprDesc
{ { desc = e; loc = $startpos, $endpos} : expr}
;
exprDesc:
| x = CST
{ Econst (Cint x) }
| SUB e = expr %prec unary_minus
{ Eunop (Uneg, e) }
| e1 = expr SUB e2 = expr
{ Ebinop (e1, Bsub, e2) }
| WHILE e = expr b = bloc END
{ Ewhile (e, b) }
;
bloc:
l = separated_nonempty_list(SEMICOLON, ioption(expr))
{
List.fold_right (fun x cur ->
match x with | None -> cur | Some v -> v :: cur
) l []
}
;
And here is the conflict as described by menhir -v :
** Conflict (shift/reduce/reduce) in state 8.
** Tokens involved: SUB SEMICOLON END
** The following explanations concentrate on token SUB.
** This state is reached from expr after reading:
WHILE expr SUB expr
** The derivations that appear below have the following common factor:
** (The question mark symbol (?) represents the spot where the derivations begin to differ.)
expr
exprDesc
(?)
** In state 8, looking ahead at SUB, reducing production
** exprDesc -> SUB expr
** is permitted because of the following sub-derivation:
WHILE expr bloc END
separated_nonempty_list(SEMICOLON,ioption(expr))
expr
exprDesc
expr SUB expr // lookahead token appears
exprDesc // lookahead token is inherited
SUB expr .
** In state 8, looking ahead at SUB, shifting is permitted
** because of the following sub-derivation:
WHILE expr bloc END
exprDesc
expr SUB expr
exprDesc
expr . SUB expr
** In state 8, looking ahead at SUB, reducing production
** exprDesc -> expr SUB expr
** is permitted because of the following sub-derivation:
WHILE expr bloc END // lookahead token appears because bloc can begin with SUB
exprDesc // lookahead token is inherited
expr SUB expr .
It seems like the precedence between unary_minus and SUB is not used. How can I fix that ?
Thank you for reading