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: 2015/09/29:
Added [has_default_reduction] to the incremental API. Added [has_default_reduction] to the incremental API.
......
...@@ -207,12 +207,6 @@ ...@@ -207,12 +207,6 @@
(ça aurait un sens au moins quand on inline dans une production unité?) (ç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?) (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 * Reconnaître les directives # n "foo" dans le fichier .mly et en tenir
compte dans les locations. 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 ...@@ -698,25 +698,43 @@ module Production = struct
let tabulateb f = let tabulateb f =
Misc.tabulateb n f Misc.tabulateb n f
(* This array allows recording, on a production by production basis, (* This array allows recording, for each %prec declaration, whether it is
whether the production's shift precedence is ever useful. This ever useful. This allows us to emit a warning about useless %prec
allows emitting warnings about useless %prec declarations. *) declarations. *)
let prec_decl_ever_useful = (* 2015/10/06: We take into account the fact that a %prec declaration can be
Array.make n false 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 = let consult_prec_decl prod =
lazy (prec_decl_ever_useful.(prod) <- true), let osym = prec_decl.(prod) in
prec_decl.(prod) 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 () = let diagnostics () =
iterx (fun prod -> iterx (fun prod ->
if not prec_decl_ever_useful.(prod) then let osym = prec_decl.(prod) in
match prec_decl.(prod) with Option.iter (fun sym ->
| None -> (* Check whether this %prec declaration was useless. *)
() let pos = Positions.position sym in
| Some id -> if not (Hashtbl.mem ever_useful pos) then begin
Error.grammar_warning [Positions.position id] "this %prec declaration is never useful." 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 (* 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