(************************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* ('b * raw_generic_argument) list -> 'a) pil = let rec make env = function | [] -> Gram.action (fun loc -> f (to_coqloc loc) env) | None :: tl -> (* parse a non-binding item *) Gram.action (fun _ -> make env tl) | Some (p, t) :: tl -> (* non-terminal *) Gram.action (fun v -> make ((p, Unsafe.inj t v) :: env) tl) in make [] (List.rev pil) (** Grammar extensions declared at ML level *) type grammar_prod_item = | GramTerminal of string | GramNonTerminal of Loc.t * argument_type * prod_entry_key * Id.t option let make_prod_item = function | GramTerminal s -> (gram_token_of_string s, None) | GramNonTerminal (_,t,e,po) -> (symbol_of_prod_entry_key e, Option.map (fun p -> (p,t)) po) let make_rule mkact pt = let (symbs,ntl) = List.split (List.map make_prod_item pt) in let act = make_generic_action mkact ntl in (symbs, act) (** Tactic grammar extensions *) let extend_tactic_grammar s gl = let mkact loc l = Tacexpr.TacExtend (loc,s,List.map snd l) in let rules = List.map (make_rule mkact) gl in maybe_uncurry (Gram.extend Tactic.simple_tactic) (None,[(None, None, List.rev rules)]) (** Vernac grammar extensions *) let vernac_exts = ref [] let get_extend_vernac_grammars () = !vernac_exts let extend_vernac_command_grammar s nt gl = let nt = Option.default Vernac_.command nt in vernac_exts := (s,gl) :: !vernac_exts; let mkact loc l = VernacExtend (s,List.map snd l) in let rules = List.map (make_rule mkact) gl in maybe_uncurry (Gram.extend nt) (None,[(None, None, List.rev rules)])