aboutsummaryrefslogtreecommitdiff
path: root/vernac/metasyntax.ml
diff options
context:
space:
mode:
authorHugo Herbelin2019-12-25 14:00:16 +0100
committerHugo Herbelin2020-02-15 22:23:08 +0100
commitaf8ddf0038e0caac1763da7ef510e4d5fdd4b8e7 (patch)
tree1739d127ac013589739f61723d19cd45cd855ca8 /vernac/metasyntax.ml
parent44ec3c8fd02f27d1dc7123bfbe5f5018937d6b86 (diff)
Fixing a precedence printing bug with custom entries.
Insertion of coercion to manage precedence of custom entries are treated in constrextern.ml, while ppconstr.ml is only about the management of precedences for constr.
Diffstat (limited to 'vernac/metasyntax.ml')
-rw-r--r--vernac/metasyntax.ml33
1 files changed, 25 insertions, 8 deletions
diff --git a/vernac/metasyntax.ml b/vernac/metasyntax.ml
index ecfebec6b8..c8c2376155 100644
--- a/vernac/metasyntax.ml
+++ b/vernac/metasyntax.ml
@@ -298,6 +298,7 @@ let precedence_of_position_and_level from_level = function
| NumLevel n, InternalProd -> n, Prec n
| NextLevel, _ -> from_level, L
+(** Computing precedences of subentries for parsing *)
let precedence_of_entry_type (from_custom,from_level) = function
| ETConstr (custom,_,x) when notation_entry_eq custom from_custom ->
precedence_of_position_and_level from_level x
@@ -309,6 +310,22 @@ let precedence_of_entry_type (from_custom,from_level) = function
| ETPattern (_,n) -> let n = match n with None -> 0 | Some n -> n in n, Prec n
| _ -> 0, E (* should not matter *)
+(** Computing precedences for future insertion of parentheses at
+ the time of printing using hard-wired constr levels *)
+let unparsing_precedence_of_entry_type from_level = function
+ | ETConstr (InConstrEntry,_,x) ->
+ (* Possible insertion of parentheses at printing time to deal
+ with precedence in a constr entry is managed using [prec_less]
+ in [ppconstr.ml] *)
+ snd (precedence_of_position_and_level from_level x)
+ | ETConstr (custom,_,_) ->
+ (* Precedence of printing for a custom entry is managed using
+ explicit insertion of entry coercions at the time of building
+ a [constr_expr] *)
+ Any
+ | ETPattern (_,n) -> (* in constr *) Prec (match n with Some n -> n | None -> 0)
+ | _ -> Any (* should not matter *)
+
(* Some breaking examples *)
(* "x = y" : "x /1 = y" (breaks before any symbol) *)
(* "x =S y" : "x /1 =S /1 y" (protect from confusion; each side for symmetry)*)
@@ -374,7 +391,7 @@ let check_open_binder isopen sl m =
let unparsing_metavar i from typs =
let x = List.nth typs (i-1) in
- let prec = snd (precedence_of_entry_type from x) in
+ let prec = unparsing_precedence_of_entry_type from x in
match x with
| ETConstr _ | ETGlobal | ETBigint ->
UnpMetaVar (i,prec)
@@ -389,12 +406,12 @@ let unparsing_metavar i from typs =
let index_id id l = List.index Id.equal id l
-let make_hunks etyps symbols from =
+let make_hunks etyps symbols from_level =
let vars,typs = List.split etyps in
let rec make b = function
| NonTerminal m :: prods ->
let i = index_id m vars in
- let u = unparsing_metavar i from typs in
+ let u = unparsing_metavar i from_level typs in
if is_next_non_terminal b prods then
(None, u) :: add_break_if_none 1 b (make b prods)
else
@@ -428,7 +445,7 @@ let make_hunks etyps symbols from =
| SProdList (m,sl) :: prods ->
let i = index_id m vars in
let typ = List.nth typs (i-1) in
- let _,prec = precedence_of_entry_type from typ in
+ let prec = unparsing_precedence_of_entry_type from_level typ in
let sl' =
(* If no separator: add a break *)
if List.is_empty sl then add_break 1 []
@@ -555,7 +572,7 @@ let read_recursive_format sl fmt =
the names in the notation *)
slfmt, res
-let hunks_of_format (from,(vars,typs)) symfmt =
+let hunks_of_format (from_level,(vars,typs)) symfmt =
let rec aux = function
| symbs, (_,(UnpTerminal s' as u)) :: fmt
when String.equal s' (String.make (String.length s') ' ') ->
@@ -565,13 +582,13 @@ let hunks_of_format (from,(vars,typs)) symfmt =
let symbs, l = aux (symbs,fmt) in symbs, UnpTerminal s :: l
| NonTerminal s :: symbs, (_,UnpTerminal s') :: fmt when Id.equal s (Id.of_string s') ->
let i = index_id s vars in
- let symbs, l = aux (symbs,fmt) in symbs, unparsing_metavar i from typs :: l
+ let symbs, l = aux (symbs,fmt) in symbs, unparsing_metavar i from_level typs :: l
| symbs, (_,(UnpCut _ as u)) :: fmt ->
let symbs, l = aux (symbs,fmt) in symbs, u :: l
| SProdList (m,sl) :: symbs, fmt when has_ldots fmt ->
let i = index_id m vars in
let typ = List.nth typs (i-1) in
- let _,prec = precedence_of_entry_type from typ in
+ let prec = unparsing_precedence_of_entry_type from_level typ in
let loc_slfmt,rfmt = read_recursive_format sl fmt in
let sl, slfmt = aux (sl,loc_slfmt) in
if not (List.is_empty sl) then error_format ?loc:(find_prod_list_loc loc_slfmt fmt) ();
@@ -1454,7 +1471,7 @@ let make_syntax_rules (sd : SynData.syn_data) = let open SynData in
let ntn_for_grammar, prec_for_grammar, need_squash = sd.not_data in
let custom,level,_,_ = sd.level in
let pa_rule = make_pa_rule prec_for_grammar sd.pa_syntax_data ntn_for_grammar need_squash in
- let pp_rule = make_pp_rule (custom,level) sd.pp_syntax_data sd.format in {
+ let pp_rule = make_pp_rule level sd.pp_syntax_data sd.format in {
synext_level = sd.level;
synext_notation = fst sd.info;
synext_notgram = { notgram_onlyprinting = sd.only_printing; notgram_rules = pa_rule };