1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283(************************************************************************)(* * The Rocq Prover / The Rocq 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,inrecinletq=List.map(fun(l,k)->s::l,k+nt)(auxinrecsymbols)inmatchs,symbolswith(* successive Terminal are considered at once by the parser,
don't list "'T1'" as prefix of "'T1' 'T2'" *)|Terminal_,Terminal_::_->q|_->([s],nt)::qinletentry,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