123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)openPpopenCErrorsopenNotation(* Register the grammar of notation for parsing and printing
(also register the parsing rule if not onlyprinting) *)letnotation_grammar_map=Summary.ref~stage:Summary.Stage.Synterp~name:"notation_grammar_map"NotationMap.emptyletdeclare_notation_grammarntnrule=trylet_=NotationMap.findntn!notation_grammar_mapinanomaly(str"Notation "++pr_notationntn++str" is already assigned a grammar.")withNot_found->notation_grammar_map:=NotationMap.addntnrule!notation_grammar_mapletgrammar_of_notationntn=NotationMap.findntn!notation_grammar_mapletlist_prefixesntn=letrecauxinrec=function|[]->[]|s::symbols->letnt,inrec=matchswith|NonTerminal_->(ifinrecthen0else1),false|TerminalswhenString.equals(Names.Id.to_stringNotation_ops.ldots_var)->0,true(* the above is horribly hackish but we plan to rewrite recursive notations soon anyway *)|Terminal_|SProdList_|Break_->0,inrecin([s],nt)::List.map(fun(l,k)->s::l,k+nt)(auxinrecsymbols)inletentry,symbols=decompose_notation_keyntninletsymbols=matchsymbolswith(* don't consider notations "{ _ ..." that have a special treatment *)|Terminal"{"::NonTerminal_::_->[]|_->symbolsinauxfalsesymbols(* considering "_" as a prefix would make all infix notations incompatible *)|>List.filter(function[NonTerminal_],_->false|_->true)|>List.map(fun(l,k)->make_notation_keyentryl,k)letprefixes_map=Summary.ref~stage:Summary.Stage.Synterp~name:"notation_prefixes_map"NotationMap.emptyletdeclare_prefixesntn=letregister_prefix(pref,_)=ifnot(NotationMap.mempref!prefixes_map)thenprefixes_map:=NotationMap.addprefntn!prefixes_mapinList.iterregister_prefix(list_prefixesntn)letnotation_non_terminals_map=Summary.ref~stage:Summary.Stage.Synterp~name:"notation_non_terminals_map"NotationMap.emptyletdeclare_notation_non_terminalsntnentries=trylet_=NotationMap.findntn!notation_grammar_mapinanomaly(str"Notation "++pr_notationntn++str" is already assigned a grammar.")withNot_found->notation_non_terminals_map:=NotationMap.addntnentries!notation_non_terminals_map;declare_prefixesntnletnon_terminals_of_notationntn=NotationMap.findntn!notation_non_terminals_mapletlongest_common_prefixntn=CList.find_map(fun(pref,k)->NotationMap.find_optpref!prefixes_map|>Option.map(funntn->ntn,k))(List.rev(list_prefixesntn))letget_defined_notations()=NotationSet.elements@@NotationMap.domain!notation_grammar_map