Commit 279d7732 authored by POTTIER Francois's avatar POTTIER Francois

Fixed a bug whereby Menhir would warn about a useless %prec declaration,

even though it was useful. This would happen when the declaration was
duplicated (by inlining or by macro-expansion) and some but not all of
the copies were useful.
parent 45d9e27b
2015/10/06:
Fixed a bug whereby Menhir would warn about a useless %prec declaration,
even though it was useful. This would happen when the declaration was
duplicated (by inlining or by macro-expansion) and some but not all of
the copies were useful.
2015/09/29:
Added [has_default_reduction] to the incremental API.
......
......@@ -207,12 +207,6 @@
(ça aurait un sens au moins quand on inline dans une production unité?)
(ou plus généralement quand on inline en dernière position?)
* BUG (message de Valentin Gatien-Baron du 09/01/2010): l'avertissement comme
quoi une directive %prec ne sert à rien est faux dans le cas où cette
directive a été dupliquée (par expansion des non-terminaux paramétrés ou par
%inline quand la production hôte porte un %prec) et une copie, mais pas
toutes, ne sert à rien.
* Reconnaître les directives # n "foo" dans le fichier .mly et en tenir
compte dans les locations.
......
Warning: you are using the standard library and/or the %inline keyword. We
recommend switching on --infer in order to avoid obscure type error messages.
(* Message from Valentin Gatien-Baron, Sat, 09 Jan 2010. *)
(* Version of Menhir earlier than 2015/10/06 would warn that the
declaration [%prec type_] is never useful. In fact, it is.
This definition is duplicated by the inlining of ioption,
and one of its copies is useful. *)
%token Eoi Rparen Lparen Colon Ident Typevar
%left type_
%left Lparen
%start <unit> expr_eoi
%%
expr_eoi: expr Eoi {}
type_expr:
| Ident ioption(delimited(Lparen, type_expr, Rparen)) {} %prec type_
| Typevar {}
expr:
| Ident {}
| expr Colon type_expr {}
| expr Lparen expr Rparen {}
Warning: you are using the standard library and/or the %inline keyword. We
recommend switching on --infer in order to avoid obscure type error messages.
%start expr_eoi
%token Typevar
%token Rparen
%token Ident
%token Eoi
%token Colon
%token Lparen
%left type_
%left Lparen
%type <unit> expr_eoi
%%
expr_eoi:
| _1 = expr _2 = Eoi
{ ()}
type_expr:
| _1 = Ident %prec type_
{let _2 =
( None )
in
()}
| _1 = Ident _100 = Lparen x00 = type_expr _300 = Rparen %prec type_
{let _2 =
let _30 = _300 in
let x0 = x00 in
let _10 = _100 in
let x =
let _3 = _30 in
let x = x0 in
let _1 = _10 in
( x )
in
( Some x )
in
()}
| _1 = Typevar
{ ()}
expr:
| _1 = Ident
{ ()}
| _1 = expr _2 = Colon _3 = type_expr
{ ()}
| _1 = expr _2 = Lparen _3 = expr _4 = Rparen
{ ()}
%%
......@@ -698,25 +698,43 @@ module Production = struct
let tabulateb f =
Misc.tabulateb n f
(* This array allows recording, on a production by production basis,
whether the production's shift precedence is ever useful. This
allows emitting warnings about useless %prec declarations. *)
(* This array allows recording, for each %prec declaration, whether it is
ever useful. This allows us to emit a warning about useless %prec
declarations. *)
let prec_decl_ever_useful =
Array.make n false
(* 2015/10/06: We take into account the fact that a %prec declaration can be
duplicated by inlining or by the expansion of parameterized non-terminal
symbols. Our table is not indexed by productions, but by positions (of
%prec declarations in the source). Thus, if a %prec declaration is
duplicated, at least one of its copies should be found useful for the
warning to be suppressed. *)
let ever_useful : (Positions.t, unit) Hashtbl.t =
(* assuming that generic hashing and equality on positions are OK *)
Hashtbl.create 16
let consult_prec_decl prod =
lazy (prec_decl_ever_useful.(prod) <- true),
prec_decl.(prod)
let osym = prec_decl.(prod) in
lazy (
Option.iter (fun sym ->
(* Mark this %prec declaration as useful. *)
let pos = Positions.position sym in
Hashtbl.add ever_useful pos ()
) osym
),
osym
let diagnostics () =
iterx (fun prod ->
if not prec_decl_ever_useful.(prod) then
match prec_decl.(prod) with
| None ->
()
| Some id ->
Error.grammar_warning [Positions.position id] "this %prec declaration is never useful."
let osym = prec_decl.(prod) in
Option.iter (fun sym ->
(* Check whether this %prec declaration was useless. *)
let pos = Positions.position sym in
if not (Hashtbl.mem ever_useful pos) then begin
Error.grammar_warning [pos] "this %prec declaration is never useful.";
Hashtbl.add ever_useful pos () (* hack: avoid two warnings at the same position *)
end
) osym
)
(* Determining the precedence level of a production. If no %prec
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment