123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135(************************************************************************)(* * 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) *)(************************************************************************)openUtilopenExtendopenPcoqopenGenargopenVernacexpr(** Grammar extensions declared at ML level *)type'sgrammar_prod_item=|GramTerminalofstring|GramNonTerminal:('araw_abstract_argument_type*('s,_,'a)Symbol.t)Loc.located->'sgrammar_prod_itemtype'aty_arg=('a->raw_generic_argument)type('self,'tr,_,'r)ty_rule=|TyStop:('self,Gramlib.Grammar.norec,'r,'r)ty_rule|TyNext:('self,_,'a,'r)ty_rule*('self,_,'b)Symbol.t*'bty_argoption->('self,Gramlib.Grammar.mayrec,'b->'a,'r)ty_ruletype('self,'r)any_ty_rule=|AnyTyRule:('self,_,'act,Loc.t->'r)ty_rule->('self,'r)any_ty_ruleletrecty_rule_of_gram=function|[]->AnyTyRuleTyStop|GramTerminals::rem->letAnyTyRulerem=ty_rule_of_gramreminlettok=Pcoq.Symbol.token(Pcoq.terminals)inletr=TyNext(rem,tok,None)inAnyTyRuler|GramNonTerminal(_,(t,tok))::rem->letAnyTyRulerem=ty_rule_of_gramreminletinj=Some(funobj->Genarg.in_gentobj)inletr=TyNext(rem,tok,inj)inAnyTyRulerletrecty_erase:typestrar.(s,tr,a,r)ty_rule->(s,tr,a,r)Pcoq.Rule.t=function|TyStop->Pcoq.Rule.stop|TyNext(rem,tok,_)->Pcoq.Rule.next(ty_eraserem)toktype'rgen_eval=Loc.t->raw_generic_argumentlist->'rletrecty_eval:typestra.(s,tr,a,Loc.t->s)ty_rule->sgen_eval->a=function|TyStop->funfloc->floc[]|TyNext(rem,tok,None)->funf_->ty_evalremf|TyNext(rem,tok,Someinj)->funfx->letflocargs=floc(injx::args)inty_evalremfletmake_rulefprod=letAnyTyRulety_rule=ty_rule_of_gram(List.revprod)inletsymb=ty_erasety_ruleinletflocl=floc(List.revl)inletact=ty_evalty_rulefinPcoq.Production.makesymbactletrecproj_symbol:typeabc.(a,b,c)ty_user_symbol->(a,b,c)genarg_type=function|TUentrya->ExtraArga|TUentryl(a,l)->ExtraArga|TUopt(o)->OptArg(proj_symbolo)|TUlist1l->ListArg(proj_symboll)|TUlist1sep(l,_)->ListArg(proj_symboll)|TUlist0l->ListArg(proj_symboll)|TUlist0sep(l,_)->ListArg(proj_symboll)(** Vernac grammar extensions *)letvernac_exts=Hashtbl.create211letget_extend_vernac_rules=snd(Hashtbl.findvernac_extss)letdeclare_vernac_command_grammar~allow_overridesntgl=let()=ifnotallow_override&&Hashtbl.memvernac_extssthenCErrors.anomalyPp.(str"bad vernac extend: "++strs.ext_entry++str", "++ints.ext_index)inletnt=Option.defaultPvernac.Vernac_.commandntinHashtbl.addvernac_extss(nt,gl)typeany_extend_statement=Extend:'aEntry.t*'aextend_statement->any_extend_statementletextend_vernac_command_grammars=letnt,gl=Hashtbl.findvernac_extssinletmkactlocl=VernacSynterp(VernacExtend(s,l))inletrules=[make_rulemkactgl]inifPcoq.Entry.is_emptyntthen(* Small hack to tolerate empty entries in VERNAC { ... } EXTEND *)Extend(nt,(Pcoq.Fresh(Gramlib.Gramext.First,[None,None,rules])))elseExtend(nt,(Pcoq.Reuse(None,rules)))letto_extend_rules(Extend(nt,r))=[ExtendRule(nt,r)]letextend_vernac=Pcoq.create_grammar_command"VernacExtend"{gext_fun=(funsst->to_extend_rules@@extend_vernac_command_grammars,st);gext_eq=(==);(* FIXME *)}letextend_vernac_command_grammar~undoables=ifundoablethenPcoq.extend_grammar_commandextend_vernacselseletExtend(nt,r)=extend_vernac_command_grammarsingrammar_extendntrletgrammar_exts=Hashtbl.create21letdeclare_grammar_ext~uide=let()=ifHashtbl.memgrammar_extsuidthenCErrors.anomalyPp.(str"bad grammar extend uid: "++struid)inHashtbl.addgrammar_extsuideletextend_grammar=Pcoq.create_grammar_command"GrammarExtend"{gext_fun=(funsst->to_extend_rules@@Hashtbl.findgrammar_extss,st);gext_eq=(==);(* FIXME *)}letgrammar_extend?plugin_uidntr=matchplugin_uidwith|None->Pcoq.grammar_extendntr|Some(plugin,uid)->letuid=plugin^":"^uidindeclare_grammar_ext~uid(Extend(nt,r));Mltop.add_init_functionplugin(fun()->Pcoq.extend_grammar_commandextend_grammaruid)