aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2009-04-27 13:43:41 +0000
committerGravatar herbelin <herbelin@85f007b7-540e-0410-9357-904b9bb8a0f7>2009-04-27 13:43:41 +0000
commitf90fde30288f67b167b68bfd32363eaa20644c5f (patch)
tree00faf9b0c6aa8749d3ec67b8fdc4f14044535b1c
parent3f40ddb52ed52ea1e1939feaecf952269335500f (diff)
- Cleaning (unification of ML names, removal of obsolete code,
reorganization of code) and documentation (in pcoq.mli) of the code for parsing extensions (TACTIC/VERNAC/ARGUMENT EXTEND, Tactic Notation, Notation); merged the two copies of interp_entry_name to avoid they diverge. - Added support in Tactic Notation for ne_..._list_sep in general and for (ne_)ident_list(_sep) in particular. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12108 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--CHANGES4
-rw-r--r--dev/doc/changes.txt4
-rw-r--r--dev/printers.mllib1
-rw-r--r--dev/top_printers.ml20
-rw-r--r--interp/topconstr.ml7
-rw-r--r--interp/topconstr.mli1
-rw-r--r--lib/compat.ml44
-rw-r--r--parsing/argextend.ml433
-rw-r--r--parsing/egrammar.ml106
-rw-r--r--parsing/egrammar.mli48
-rw-r--r--parsing/extend.ml57
-rw-r--r--parsing/extend.mli49
-rw-r--r--parsing/extrawit.ml62
-rw-r--r--parsing/extrawit.mli51
-rw-r--r--parsing/g_constr.ml43
-rw-r--r--parsing/g_vernac.ml417
-rw-r--r--parsing/grammar.mllib4
-rw-r--r--parsing/lexer.ml445
-rw-r--r--parsing/lexer.mli9
-rw-r--r--parsing/parsing.mllib1
-rw-r--r--parsing/pcoq.ml4322
-rw-r--r--parsing/pcoq.mli227
-rw-r--r--parsing/pptactic.ml8
-rw-r--r--parsing/ppvernac.ml20
-rw-r--r--parsing/q_util.ml476
-rw-r--r--parsing/q_util.mli3
-rw-r--r--parsing/tacextend.ml470
-rw-r--r--parsing/vernacextend.ml455
-rw-r--r--plugins/interface/debug_tac.ml47
-rw-r--r--plugins/interface/xlate.ml32
-rw-r--r--tactics/tacinterp.ml31
-rw-r--r--toplevel/command.ml2
-rw-r--r--toplevel/metasyntax.ml46
-rw-r--r--toplevel/metasyntax.mli2
-rw-r--r--toplevel/vernacexpr.ml16
35 files changed, 742 insertions, 701 deletions
diff --git a/CHANGES b/CHANGES
index eb4245bd1..2ef2ab93b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -18,6 +18,10 @@ Tactics
- Tactic "tauto" now proves classical tautologies as soon as classical logic
(i.e. library Classical_Prop or Classical) is loaded.
+Tactic Language
+
+- Support for parsing non-empty lists with separators in tactic notations.
+
Vernacular commands
- New command "Timeout <n> <command>." interprets a command and a timeout
diff --git a/dev/doc/changes.txt b/dev/doc/changes.txt
index a9673664a..c82e1e652 100644
--- a/dev/doc/changes.txt
+++ b/dev/doc/changes.txt
@@ -2,6 +2,10 @@
= CHANGES BETWEEN COQ V8.2 AND COQ V8.3 =
=========================================
+** Cleaning in parsing extensions (commit )
+
+Many moves and renamings, one new file (Extrawit, that contains wit_tactic).
+
** Cleaning in tactical.mli
tclLAST_HYP -> onLastHyp
diff --git a/dev/printers.mllib b/dev/printers.mllib
index 25ec05fba..f4b3d7f6c 100644
--- a/dev/printers.mllib
+++ b/dev/printers.mllib
@@ -112,6 +112,7 @@ Tactic_debug
Decl_mode
Ppconstr
Extend
+Extrawit
Pcoq
Printer
Pptactic
diff --git a/dev/top_printers.ml b/dev/top_printers.ml
index 5e3fbb616..4881c3eef 100644
--- a/dev/top_printers.ml
+++ b/dev/top_printers.ml
@@ -400,12 +400,10 @@ let _ =
e -> Pp.pp (Cerrors.explain_exn e)
let _ =
extend_vernac_command_grammar "PrintConstr"
- [[TacTerm "PrintConstr";
- TacNonTerm
- (dummy_loc,
- (Gramext.Snterm (Pcoq.Gram.Entry.obj Constr.constr),
- ConstrArgType),
- Some "c")]]
+ [[GramTerminal "PrintConstr";
+ GramNonTerminal
+ (dummy_loc,ConstrArgType,Extend.Aentry ("constr","constr"),
+ Some (Names.id_of_string "c"))]]
let _ =
try
@@ -419,12 +417,10 @@ let _ =
e -> Pp.pp (Cerrors.explain_exn e)
let _ =
extend_vernac_command_grammar "PrintPureConstr"
- [[TacTerm "PrintPureConstr";
- TacNonTerm
- (dummy_loc,
- (Gramext.Snterm (Pcoq.Gram.Entry.obj Constr.constr),
- ConstrArgType),
- Some "c")]]
+ [[GramTerminal "PrintPureConstr";
+ GramNonTerminal
+ (dummy_loc,ConstrArgType,Extend.Aentry ("constr","constr"),
+ Some (Names.id_of_string "c"))]]
(* Setting printer of unbound global reference *)
open Names
diff --git a/interp/topconstr.ml b/interp/topconstr.ml
index 666f9022b..32595cdc6 100644
--- a/interp/topconstr.ml
+++ b/interp/topconstr.ml
@@ -890,6 +890,12 @@ let rec prod_constr_expr c = function
List.fold_right (fun x b -> mkProdC([x],bk,t,b)) idl
(prod_constr_expr c bl)
+let coerce_reference_to_id = function
+ | Ident (_,id) -> id
+ | Qualid (loc,_) ->
+ user_err_loc (loc, "coerce_reference_to_id",
+ str "This expression should be a simple identifier.")
+
let coerce_to_id = function
| CRef (Ident (loc,id)) -> (loc,id)
| a -> user_err_loc
@@ -903,6 +909,7 @@ let coerce_to_name = function
(constr_loc a,"coerce_to_name",
str "This expression should be a name.")
+
(* Used in correctness and interface *)
let map_binder g e nal = List.fold_right (fun (_,na) -> name_fold g na) nal e
diff --git a/interp/topconstr.mli b/interp/topconstr.mli
index 1982a08fd..0b6cf46c5 100644
--- a/interp/topconstr.mli
+++ b/interp/topconstr.mli
@@ -200,6 +200,7 @@ val mkLambdaC : name located list * binder_kind * constr_expr * constr_expr -> c
val mkLetInC : name located * constr_expr * constr_expr -> constr_expr
val mkProdC : name located list * binder_kind * constr_expr * constr_expr -> constr_expr
+val coerce_reference_to_id : reference -> identifier
val coerce_to_id : constr_expr -> identifier located
val coerce_to_name : constr_expr -> name located
diff --git a/lib/compat.ml4 b/lib/compat.ml4
index 40cffadb7..481b9f8d4 100644
--- a/lib/compat.ml4
+++ b/lib/compat.ml4
@@ -23,7 +23,6 @@ let join_loc loc1 loc2 =
else Stdpp.encl_loc loc1 loc2
type token = string*string
type lexer = token Token.glexer
-let using l x = l.Token.tok_using x
end
ELSE IFDEF OCAML308 THEN
module M = struct
@@ -43,7 +42,6 @@ let join_loc loc1 loc2 =
else (fst loc1, snd loc2)
type token = Token.t
type lexer = Token.lexer
-let using l x = l.Token.using x
end
ELSE
module M = struct
@@ -56,7 +54,6 @@ let join_loc loc1 loc2 =
else (fst loc1, snd loc2)
type token = Token.t
type lexer = Token.lexer
-let using l x = l.Token.using x
end
END
END
@@ -68,4 +65,3 @@ let unloc = M.unloc
let join_loc = M.join_loc
type token = M.token
type lexer = M.lexer
-let using = M.using
diff --git a/parsing/argextend.ml4 b/parsing/argextend.ml4
index 7f2a6dd48..aa0c3c771 100644
--- a/parsing/argextend.ml4
+++ b/parsing/argextend.ml4
@@ -13,6 +13,7 @@
open Genarg
open Q_util
open Q_coqast
+open Egrammar
let join_loc = Util.join_loc
let loc = Util.dummy_loc
@@ -96,18 +97,24 @@ let rec make_wit loc = function
let make_act loc act pil =
let rec make = function
| [] -> <:expr< Gramext.action (fun loc -> ($act$ : 'a)) >>
- | None :: tl -> <:expr< Gramext.action (fun _ -> $make tl$) >>
- | Some (p, t) :: tl ->
+ | GramNonTerminal (_,t,_,Some p) :: tl ->
+ let p = Names.string_of_id p in
<:expr<
Gramext.action
(fun $lid:p$ ->
let _ = Genarg.in_gen $make_rawwit loc t$ $lid:p$ in $make tl$)
- >> in
+ >>
+ | (GramTerminal _ | GramNonTerminal (_,_,_,None)) :: tl ->
+ <:expr< Gramext.action (fun _ -> $make tl$) >> in
make (List.rev pil)
+let make_prod_item = function
+ | GramTerminal s -> <:expr< (Gramext.Stoken (Lexer.terminal $str:s$)) >>
+ | GramNonTerminal (_,_,g,_) ->
+ <:expr< Pcoq.symbol_of_prod_entry_key $mlexpr_of_prod_entry_key g$ >>
+
let make_rule loc (prods,act) =
- let (symbs,pil) = List.split prods in
- <:expr< ($mlexpr_of_list (fun x -> x) symbs$,$make_act loc act pil$) >>
+ <:expr< ($mlexpr_of_list make_prod_item prods$,$make_act loc act prods$) >>
let declare_tactic_argument loc s typ pr f g h rawtyppr globtyppr cl =
let rawtyp, rawpr = match rawtyppr with
@@ -144,6 +151,8 @@ let declare_tactic_argument loc s typ pr f g h rawtyppr globtyppr cl =
let rules = mlexpr_of_list (make_rule loc) (List.rev cl) in
<:str_item<
declare
+ open Pcoq;
+ open Extrawit;
value ($lid:"wit_"^s$, $lid:"globwit_"^s$, $lid:"rawwit_"^s$) =
Genarg.create_arg $se$;
value $lid:s$ = Pcoq.create_generic_entry $se$ $rawwit$;
@@ -174,6 +183,8 @@ let declare_vernac_argument loc s pr cl =
| Some pr -> <:expr< fun _ _ _ -> $lid:pr$ >> in
<:str_item<
declare
+ open Pcoq;
+ open Extrawit;
value (($lid:"wit_"^s$:Genarg.abstract_argument_type unit Genarg.tlevel),
($lid:"globwit_"^s$:Genarg.abstract_argument_type unit Genarg.glevel),
$lid:"rawwit_"^s$) = Genarg.create_arg $se$;
@@ -227,7 +238,7 @@ EXTEND
[ e = argtype; LIDENT "list" -> List0ArgType e
| e = argtype; LIDENT "option" -> OptArgType e ]
| "0"
- [ e = LIDENT -> fst (interp_entry_name loc e "")
+ [ e = LIDENT -> fst (interp_entry_name None e "")
| "("; e = argtype; ")" -> e ] ]
;
argrule:
@@ -235,13 +246,15 @@ EXTEND
;
genarg:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = interp_entry_name loc e "" in (g, Some (s,t))
+ let t, g = interp_entry_name None e "" in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = interp_entry_name loc e sep in (g, Some (s,t))
+ let t, g = interp_entry_name None e sep in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| s = STRING ->
if String.length s > 0 && Util.is_letter s.[0] then
- Compat.using Pcoq.lexer ("", s);
- (<:expr< (Gramext.Stoken (Lexer.terminal $str:s$)) >>, None)
+ Lexer.add_token ("", s);
+ GramTerminal s
] ]
;
END
diff --git a/parsing/egrammar.ml b/parsing/egrammar.ml
index b784acdc3..6ce6c2c09 100644
--- a/parsing/egrammar.ml
+++ b/parsing/egrammar.ml
@@ -12,6 +12,7 @@ open Pp
open Util
open Pcoq
open Extend
+open Ppextend
open Topconstr
open Genarg
open Libnames
@@ -55,10 +56,9 @@ let cases_pattern_expr_of_name (loc,na) = match na with
| Anonymous -> CPatAtom (loc,None)
| Name id -> CPatAtom (loc,Some (Ident (loc,id)))
-type prod_item =
- | Term of Token.pattern
- | NonTerm of constr_production_entry *
- (Names.identifier * constr_production_entry) option
+type grammar_constr_prod_item =
+ | GramConstrTerminal of Token.pattern
+ | GramConstrNonTerminal of constr_prod_entry_key * identifier option
type 'a action_env = 'a list * 'a list list
@@ -111,10 +111,10 @@ let make_cases_pattern_action
make ([],[]) (List.rev pil)
let make_constr_prod_item univ assoc from forpat = function
- | Term tok -> (Gramext.Stoken tok, None)
- | NonTerm (nt, ovar) ->
- let eobj = symbol_of_production assoc from forpat nt in
- (eobj, ovar)
+ | GramConstrTerminal tok -> (Gramext.Stoken tok, None)
+ | GramConstrNonTerminal (nt, ovar) ->
+ let eobj = symbol_of_constr_prod_entry_key assoc from forpat nt in
+ (eobj, Option.map (fun x -> (x,nt)) ovar)
let prepare_empty_levels entry (pos,p4assoc,name,reinit) =
grammar_extend entry pos reinit [(name, p4assoc, [])]
@@ -139,11 +139,11 @@ let extend_constr (entry,level) (n,assoc) mkact forpat pt =
let extend_constr_notation (n,assoc,ntn,rule) =
(* Add the notation in constr *)
let mkact loc env = CNotation (loc,ntn,env) in
- let e = get_constr_entry false (ETConstr (n,())) in
+ let e = interp_constr_entry_key false (ETConstr (n,())) in
extend_constr e (ETConstr(n,()),assoc) (make_constr_action mkact) false rule;
(* Add the notation in cases_pattern *)
let mkact loc env = CPatNotation (loc,ntn,env) in
- let e = get_constr_entry true (ETConstr (n,())) in
+ let e = interp_constr_entry_key true (ETConstr (n,())) in
extend_constr e (ETConstr (n,()),assoc) (make_cases_pattern_action mkact)
true rule
@@ -169,22 +169,19 @@ let make_rule univ f g pt =
(**********************************************************************)
(** Grammar extensions declared at ML level *)
-type grammar_tactic_production =
- | TacTerm of string
- | TacNonTerm of
- loc * (Gram.te Gramext.g_symbol * argument_type) * string option
+type grammar_prod_item =
+ | GramTerminal of string
+ | GramNonTerminal of
+ loc * argument_type * Gram.te prod_entry_key * identifier option
let make_prod_item = function
- | TacTerm s -> (Gramext.Stoken (Lexer.terminal s), None)
- | TacNonTerm (_,(nont,t), po) -> (nont, Option.map (fun p -> (p,t)) po)
+ | GramTerminal s -> (Gramext.Stoken (Lexer.terminal s), None)
+ | GramNonTerminal (_,t,e,po) ->
+ (symbol_of_prod_entry_key e, Option.map (fun p -> (p,t)) po)
(* Tactic grammar extensions *)
-let tac_exts = ref []
-let get_extend_tactic_grammars () = !tac_exts
-
let extend_tactic_grammar s gl =
- tac_exts := (s,gl) :: !tac_exts;
let univ = get_univ "tactic" in
let mkact loc l = Tacexpr.TacExtend (loc,s,List.map snd l) in
let rules = List.map (make_rule univ mkact make_prod_item) gl in
@@ -205,52 +202,6 @@ let extend_vernac_command_grammar s gl =
(**********************************************************************)
(** Grammar declaration for Tactic Notation (Coq level) *)
-(* Interpretation of the grammar entry names *)
-
-let find_index s t =
- let t,n = repr_ident (id_of_string t) in
- if s <> t or n = None then raise Not_found;
- Option.get n
-
-let rec interp_entry_name up_level s =
- let l = String.length s in
- if l > 8 & String.sub s 0 3 = "ne_" & String.sub s (l-5) 5 = "_list" then
- let t, g = interp_entry_name up_level (String.sub s 3 (l-8)) in
- List1ArgType t, Gramext.Slist1 g
- else if l > 5 & String.sub s (l-5) 5 = "_list" then
- let t, g = interp_entry_name up_level (String.sub s 0 (l-5)) in
- List0ArgType t, Gramext.Slist0 g
- else if l > 4 & String.sub s (l-4) 4 = "_opt" then
- let t, g = interp_entry_name up_level (String.sub s 0 (l-4)) in
- OptArgType t, Gramext.Sopt g
- else
- let s = if s = "hyp" then "var" else s in
- try
- let i = find_index "tactic" s in
- ExtraArgType s,
- if up_level<>5 && i=up_level then Gramext.Sself else
- if up_level<>5 && i=up_level-1 then Gramext.Snext else
- Gramext.Snterml(Pcoq.Gram.Entry.obj Tactic.tactic_expr,string_of_int i)
- with Not_found ->
- let e =
- (* Qualified entries are no longer in use *)
- try get_entry (get_univ "tactic") s
- with _ ->
- try get_entry (get_univ "prim") s
- with _ ->
- try get_entry (get_univ "constr") s
- with _ -> error ("Unknown entry "^s^".")
- in
- let o = object_of_typed_entry e in
- let t = type_of_typed_entry e in
- t,Gramext.Snterm (Pcoq.Gram.Entry.obj o)
-
-let make_vprod_item n = function
- | VTerm s -> (Gramext.Stoken (Lexer.terminal s), None)
- | VNonTerm (loc, nt, po) ->
- let (etyp, e) = interp_entry_name n nt in
- e, Option.map (fun p -> (p,etyp)) po
-
let get_tactic_entry n =
if n = 0 then
weaken_entry Tactic.simple_tactic, None
@@ -263,24 +214,23 @@ let get_tactic_entry n =
(* Declaration of the tactic grammar rule *)
-let head_is_ident = function VTerm _::_ -> true | _ -> false
+let head_is_ident = function GramTerminal _::_ -> true | _ -> false
let add_tactic_entry (key,lev,prods,tac) =
let univ = get_univ "tactic" in
let entry, pos = get_tactic_entry lev in
- let mkprod = make_vprod_item lev in
let rules =
if lev = 0 then begin
if not (head_is_ident prods) then
error "Notation for simple tactic must start with an identifier.";
let mkact s tac loc l =
(TacAlias(loc,s,l,tac):raw_atomic_tactic_expr) in
- make_rule univ (mkact key tac) mkprod prods
+ make_rule univ (mkact key tac) make_prod_item prods
end
else
let mkact s tac loc l =
(TacAtom(loc,TacAlias(loc,s,l,tac)):raw_tactic_expr) in
- make_rule univ (mkact key tac) mkprod prods in
+ make_rule univ (mkact key tac) make_prod_item prods in
synchronize_level_positions ();
grammar_extend entry pos None [(None, None, List.rev [rules])]
@@ -288,13 +238,13 @@ let add_tactic_entry (key,lev,prods,tac) =
(** State of the grammar extensions *)
type notation_grammar =
- int * Gramext.g_assoc option * notation * prod_item list
+ int * Gramext.g_assoc option * notation * grammar_constr_prod_item list
type all_grammar_command =
- | Notation of Notation.level * notation_grammar
+ | Notation of (precedence * tolerability list) * notation_grammar
| TacticGrammar of
- (string * int * grammar_production list *
- (Names.dir_path * Tacexpr.glob_tactic_expr))
+ (string * int * grammar_prod_item list *
+ (dir_path * Tacexpr.glob_tactic_expr))
let (grammar_state : all_grammar_command list ref) = ref []
@@ -304,14 +254,6 @@ let extend_grammar gram =
| TacticGrammar g -> add_tactic_entry g);
grammar_state := gram :: !grammar_state
-let reset_extend_grammars_v8 () =
- let te = List.rev !tac_exts in
- let tv = List.rev !vernac_exts in
- tac_exts := [];
- vernac_exts := [];
- List.iter (fun (s,gl) -> print_string ("Resinstalling "^s); flush stdout; extend_tactic_grammar s gl) te;
- List.iter (fun (s,gl) -> extend_vernac_command_grammar s gl) tv
-
let recover_notation_grammar ntn prec =
let l = map_succeed (function
| Notation (prec',(_,_,ntn',_ as x)) when prec = prec' & ntn = ntn' -> x
diff --git a/parsing/egrammar.mli b/parsing/egrammar.mli
index e99741a6e..e632e5bb8 100644
--- a/parsing/egrammar.mli
+++ b/parsing/egrammar.mli
@@ -10,12 +10,14 @@
(*i*)
open Util
+open Names
open Topconstr
open Pcoq
open Extend
open Vernacexpr
open Ppextend
open Rawterm
+open Genarg
open Mod_subst
(*i*)
@@ -24,44 +26,40 @@ open Mod_subst
and for ML-level tactic and vernac extensions
*)
-type prod_item =
- | Term of Token.pattern
- | NonTerm of constr_production_entry *
- (Names.identifier * constr_production_entry) option
+(* For constr notations *)
+
+type grammar_constr_prod_item =
+ | GramConstrTerminal of Token.pattern
+ | GramConstrNonTerminal of constr_prod_entry_key * identifier option
type notation_grammar =
- int * Gramext.g_assoc option * notation * prod_item list
+ int * Gramext.g_assoc option * notation * grammar_constr_prod_item list
+
+(* For tactic and vernac notations *)
+
+type grammar_prod_item =
+ | GramTerminal of string
+ | GramNonTerminal of loc * argument_type *
+ Gram.te prod_entry_key * identifier option
+
+(* Adding notations *)
type all_grammar_command =
| Notation of (precedence * tolerability list) * notation_grammar
| TacticGrammar of
- (string * int * grammar_production list *
- (Names.dir_path * Tacexpr.glob_tactic_expr))
+ (string * int * grammar_prod_item list *
+ (dir_path * Tacexpr.glob_tactic_expr))
val extend_grammar : all_grammar_command -> unit
-(* Add grammar rules for tactics *)
-
-type grammar_tactic_production =
- | TacTerm of string
- | TacNonTerm of
- loc * (Compat.token Gramext.g_symbol * Genarg.argument_type) * string option
-
val extend_tactic_grammar :
- string -> grammar_tactic_production list list -> unit
+ string -> grammar_prod_item list list -> unit
val extend_vernac_command_grammar :
- string -> grammar_tactic_production list list -> unit
-(*
-val get_extend_tactic_grammars :
- unit -> (string * grammar_tactic_production list list) list
-*)
+ string -> grammar_prod_item list list -> unit
+
val get_extend_vernac_grammars :
- unit -> (string * grammar_tactic_production list list) list
-(*
-val reset_extend_grammars_v8 : unit -> unit
-*)
-val interp_entry_name : int -> string -> entry_type * Compat.token Gramext.g_symbol
+ unit -> (string * grammar_prod_item list list) list
val recover_notation_grammar :
notation -> (precedence * tolerability list) -> notation_grammar
diff --git a/parsing/extend.ml b/parsing/extend.ml
index 36e1000b1..2121671a8 100644
--- a/parsing/extend.ml
+++ b/parsing/extend.ml
@@ -6,52 +6,53 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-
(*i $Id$ i*)
open Util
-open Pp
-open Gramext
-open Names
-open Ppextend
-open Topconstr
-open Genarg
(**********************************************************************)
-(* constr entry keys *)
+(* General entry keys *)
+
+(* This intermediate abstract representation of entries can *)
+(* both be reified into mlexpr for the ML extensions and *)
+(* dynamically interpreted as entries for the Coq level extensions *)
+
+type 'a prod_entry_key =
+ | Alist1 of 'a prod_entry_key
+ | Alist1sep of 'a prod_entry_key * string
+ | Alist0 of 'a prod_entry_key
+ | Alist0sep of 'a prod_entry_key * string
+ | Aopt of 'a prod_entry_key
+ | Amodifiers of 'a prod_entry_key
+ | Aself
+ | Anext
+ | Atactic of int
+ | Agram of 'a Gramext.g_entry
+ | Aentry of string * string
+
+(**********************************************************************)
+(* Entry keys for constr notations *)
type side = Left | Right
type production_position =
- | BorderProd of side * Gramext.g_assoc option (* true=left; false=right *)
+ | BorderProd of side * Gramext.g_assoc option
| InternalProd
type production_level =
| NextLevel
| NumLevel of int
-type ('lev,'pos) constr_entry_key =
+type ('lev,'pos) constr_entry_key_gen =
| ETName | ETReference | ETBigint
| ETConstr of ('lev * 'pos)
| ETPattern
| ETOther of string * string
| ETConstrList of ('lev * 'pos) * Token.pattern list
-type constr_production_entry =
- (production_level,production_position) constr_entry_key
-type constr_entry =
- (int,unit) constr_entry_key
-type simple_constr_production_entry =
- (production_level,unit) constr_entry_key
-
-(**********************************************************************)
-(* syntax modifiers *)
-
-type syntax_modifier =
- | SetItemLevel of string list * production_level
- | SetLevel of int
- | SetAssoc of Gramext.g_assoc
- | SetEntryType of string * simple_constr_production_entry
- | SetOnlyParsing
- | SetFormat of string located
-
+type constr_prod_entry_key =
+ (production_level,production_position) constr_entry_key_gen
+type constr_entry_key =
+ (int,unit) constr_entry_key_gen
+type simple_constr_prod_entry_key =
+ (production_level,unit) constr_entry_key_gen
diff --git a/parsing/extend.mli b/parsing/extend.mli
index 61fee077a..0ca073956 100644
--- a/parsing/extend.mli
+++ b/parsing/extend.mli
@@ -11,40 +11,49 @@
open Util
(**********************************************************************)
-(* constr entry keys *)
+(* General entry keys *)
+
+(* This intermediate abstract representation of entries can *)
+(* both be reified into mlexpr for the ML extensions and *)
+(* dynamically interpreted as entries for the Coq level extensions *)
+
+type 'a prod_entry_key =
+ | Alist1 of 'a prod_entry_key
+ | Alist1sep of 'a prod_entry_key * string
+ | Alist0 of 'a prod_entry_key
+ | Alist0sep of 'a prod_entry_key * string
+ | Aopt of 'a prod_entry_key
+ | Amodifiers of 'a prod_entry_key
+ | Aself
+ | Anext
+ | Atactic of int
+ | Agram of 'a Gramext.g_entry
+ | Aentry of string * string
+
+(**********************************************************************)
+(* Entry keys for constr notations *)
type side = Left | Right
type production_position =
- | BorderProd of side * Gramext.g_assoc option (* true=left; false=right *)
+ | BorderProd of side * Gramext.g_assoc option
| InternalProd
type production_level =
| NextLevel
| NumLevel of int
-type ('lev,'pos) constr_entry_key =
+type ('lev,'pos) constr_entry_key_gen =
| ETName | ETReference | ETBigint
| ETConstr of ('lev * 'pos)
| ETPattern
| ETOther of string * string
| ETConstrList of ('lev * 'pos) * Token.pattern list
-type constr_production_entry =
- (production_level,production_position) constr_entry_key
-type constr_entry =
- (int,unit) constr_entry_key
-type simple_constr_production_entry =
- (production_level,unit) constr_entry_key
-
-(**********************************************************************)
-(* syntax modifiers *)
-
-type syntax_modifier =
- | SetItemLevel of string list * production_level
- | SetLevel of int
- | SetAssoc of Gramext.g_assoc
- | SetEntryType of string * simple_constr_production_entry
- | SetOnlyParsing
- | SetFormat of string located
+type constr_prod_entry_key =
+ (production_level,production_position) constr_entry_key_gen
+type constr_entry_key =
+ (int,unit) constr_entry_key_gen
+type simple_constr_prod_entry_key =
+ (production_level,unit) constr_entry_key_gen
diff --git a/parsing/extrawit.ml b/parsing/extrawit.ml
new file mode 100644
index 000000000..122730f72
--- /dev/null
+++ b/parsing/extrawit.ml
@@ -0,0 +1,62 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i $Id$ i*)
+
+open Util
+open Genarg
+
+(* This file defines extra argument types *)
+
+(* Tactics as arguments *)
+
+let tactic_main_level = 5
+
+let (wit_tactic0,globwit_tactic0,rawwit_tactic0) = create_arg "tactic0"
+let (wit_tactic1,globwit_tactic1,rawwit_tactic1) = create_arg "tactic1"
+let (wit_tactic2,globwit_tactic2,rawwit_tactic2) = create_arg "tactic2"
+let (wit_tactic3,globwit_tactic3,rawwit_tactic3) = create_arg "tactic3"
+let (wit_tactic4,globwit_tactic4,rawwit_tactic4) = create_arg "tactic4"
+let (wit_tactic5,globwit_tactic5,rawwit_tactic5) = create_arg "tactic5"
+
+let wit_tactic = function
+ | 0 -> wit_tactic0
+ | 1 -> wit_tactic1
+ | 2 -> wit_tactic2
+ | 3 -> wit_tactic3
+ | 4 -> wit_tactic4
+ | 5 -> wit_tactic5
+ | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
+
+let globwit_tactic = function
+ | 0 -> globwit_tactic0
+ | 1 -> globwit_tactic1
+ | 2 -> globwit_tactic2
+ | 3 -> globwit_tactic3
+ | 4 -> globwit_tactic4
+ | 5 -> globwit_tactic5
+ | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
+
+let rawwit_tactic = function
+ | 0 -> rawwit_tactic0
+ | 1 -> rawwit_tactic1
+ | 2 -> rawwit_tactic2
+ | 3 -> rawwit_tactic3
+ | 4 -> rawwit_tactic4
+ | 5 -> rawwit_tactic5
+ | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
+
+let tactic_genarg_level s =
+ if String.length s = 7 && String.sub s 0 6 = "tactic" then
+ let c = s.[6] in if '5' >= c && c >= '0' then Some (Char.code c - 48)
+ else None
+ else None
+
+let is_tactic_genarg = function
+| ExtraArgType s -> tactic_genarg_level s <> None
+| _ -> false
diff --git a/parsing/extrawit.mli b/parsing/extrawit.mli
new file mode 100644
index 000000000..9eff5dc13
--- /dev/null
+++ b/parsing/extrawit.mli
@@ -0,0 +1,51 @@
+(************************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * CNRS-Ecole Polytechnique-INRIA Futurs-Universite Paris Sud *)
+(* \VV/ **************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(************************************************************************)
+
+(*i $Id$ i*)
+
+open Util
+open Genarg
+open Tacexpr
+
+(* This file defines extra argument types *)
+
+(* Tactics as arguments *)
+
+val tactic_main_level : int
+
+val rawwit_tactic : int -> (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic : int -> (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic : int -> (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic0 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic0 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic0 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic1 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic1 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic1 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic2 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic2 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic2 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic3 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic3 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic3 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic4 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic4 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic4 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val rawwit_tactic5 : (raw_tactic_expr,rlevel) abstract_argument_type
+val globwit_tactic5 : (glob_tactic_expr,glevel) abstract_argument_type
+val wit_tactic5 : (glob_tactic_expr,tlevel) abstract_argument_type
+
+val is_tactic_genarg : argument_type -> bool
+
+val tactic_genarg_level : string -> int option
diff --git a/parsing/g_constr.ml4 b/parsing/g_constr.ml4
index 8db62c392..f91f0170c 100644
--- a/parsing/g_constr.ml4
+++ b/parsing/g_constr.ml4
@@ -80,9 +80,6 @@ let mk_fix(loc,kw,id,dcls) =
let mk_single_fix (loc,kw,dcl) =
let (id,_,_,_,_) = dcl in mk_fix(loc,kw,id,[dcl])
-let binder_constr =
- create_constr_entry (get_univ "constr") "binder_constr"
-
(* Hack to parse "(x:=t)" as an explicit argument without conflicts with the *)
(* admissible notation "(x t)" *)
let lpar_id_coloneq =
diff --git a/parsing/g_vernac.ml4 b/parsing/g_vernac.ml4
index f656fb32e..56c00ca78 100644
--- a/parsing/g_vernac.ml4
+++ b/parsing/g_vernac.ml4
@@ -16,13 +16,13 @@ open Pp
open Util
open Names
open Topconstr
+open Extend
open Vernacexpr
open Pcoq
open Decl_mode
open Tactic
open Decl_kinds
open Genarg
-open Extend
open Ppextend
open Goptions
@@ -471,17 +471,17 @@ GEXTEND Gram
| IDENT "Canonical"; IDENT "Structure"; qid = global ->
VernacCanonical qid
| IDENT "Canonical"; IDENT "Structure"; qid = global; d = def_body ->
- let s = coerce_global_to_id qid in
+ let s = coerce_reference_to_id qid in
VernacDefinition
((Global,false,CanonicalStructure),(dummy_loc,s),d,
(fun _ -> Recordops.declare_canonical_structure))
(* Coercions *)
| IDENT "Coercion"; qid = global; d = def_body ->
- let s = coerce_global_to_id qid in
+ let s = coerce_reference_to_id qid in
VernacDefinition ((use_locality_exp (),false,Coercion),(dummy_loc,s),d,Class.add_coercion_hook)
| IDENT "Coercion"; IDENT "Local"; qid = global; d = def_body ->
- let s = coerce_global_to_id qid in
+ let s = coerce_reference_to_id qid in
VernacDefinition ((enforce_locality_exp (),false,Coercion),(dummy_loc,s),d,Class.add_coercion_hook)
| IDENT "Identity"; IDENT "Coercion"; IDENT "Local"; f = identref;
":"; s = class_rawexpr; ">->"; t = class_rawexpr ->
@@ -851,15 +851,16 @@ GEXTEND Gram
;
syntax_extension_type:
[ [ IDENT "ident" -> ETName | IDENT "global" -> ETReference
- | IDENT "bigint" -> ETBigint
+ | IDENT "bigint" -> ETBigint
] ]
;
opt_scope:
[ [ "_" -> None | sc = IDENT -> Some sc ] ]
;
production_item:
- [ [ s = ne_string -> VTerm s
- | nt = IDENT; po = OPT [ "("; p = ident; ")" -> p ] ->
- VNonTerm (loc,nt,po) ] ]
+ [ [ s = ne_string -> TacTerm s
+ | nt = IDENT;
+ po = OPT [ "("; p = ident; sep = [ -> "" | ","; sep = STRING -> sep ];
+ ")" -> (p,sep) ] -> TacNonTerm (loc,nt,po) ] ]
;
END
diff --git a/parsing/grammar.mllib b/parsing/grammar.mllib
index 128ca9445..9e714352b 100644
--- a/parsing/grammar.mllib
+++ b/parsing/grammar.mllib
@@ -64,10 +64,12 @@ Tacexpr
Lexer
Extend
Vernacexpr
+Extrawit
Pcoq
Q_util
Q_coqast
+Egrammar
Argextend
Tacextend
Vernacextend
@@ -75,4 +77,4 @@ Vernacextend
G_prim
G_tactic
G_ltac
-G_constr \ No newline at end of file
+G_constr
diff --git a/parsing/lexer.ml4 b/parsing/lexer.ml4
index 045c2ecca..c827ab381 100644
--- a/parsing/lexer.ml4
+++ b/parsing/lexer.ml4
@@ -6,13 +6,12 @@
(* * GNU Lesser General Public License Version 2.1 *)
(************************************************************************)
-(*i $Id$ i*)
-
-
-(*i camlp4use: "pr_o.cmo" i*)
+(*i camlp4use: "pr_o.cmo pa_macro.cmo" i*)
(* Add pr_o.cmo to circumvent a useless-warning bug when preprocessed with
* ast-based camlp4 *)
+(*i $Id$ i*)
+
open Pp
open Util
open Token
@@ -512,14 +511,36 @@ let token_text = function
| (con, "") -> con
| (con, prm) -> con ^ " \"" ^ prm ^ "\""
-let tparse (p_con, p_prm) =
- None
- (*i was
- if p_prm = "" then
- (parser [< '(con, prm) when con = p_con >] -> prm)
- else
- (parser [< '(con, prm) when con = p_con && prm = p_prm >] -> prm)
- i*)
+(* The lexer of Coq *)
+
+(* Note: removing a token.
+ We do nothing because [remove_token] is called only when removing a grammar
+ rule with [Grammar.delete_rule]. The latter command is called only when
+ unfreezing the state of the grammar entries (see GRAMMAR summary, file
+ env/metasyntax.ml). Therefore, instead of removing tokens one by one,
+ we unfreeze the state of the lexer. This restores the behaviour of the
+ lexer. B.B. *)
+
+IFDEF CAMLP5 THEN
+
+let lexer = {
+ Token.tok_func = func;
+ Token.tok_using = add_token;
+ Token.tok_removing = (fun _ -> ());
+ Token.tok_match = default_match;
+ Token.tok_comm = None;
+ Token.tok_text = token_text }
+
+ELSE
+
+let lexer = {
+ Token.func = func;
+ Token.using = add_token;
+ Token.removing = (fun _ -> ());
+ Token.tparse = (fun _ -> None);
+ Token.text = token_text }
+
+END
(* Terminal symbols interpretation *)
diff --git a/parsing/lexer.mli b/parsing/lexer.mli
index 84f25ca5e..1a3a10aaa 100644
--- a/parsing/lexer.mli
+++ b/parsing/lexer.mli
@@ -23,7 +23,6 @@ exception Error of error
val add_token : string * string -> unit
val is_keyword : string -> bool
-val func : char Stream.t -> (string * string) Stream.t * (int -> loc)
val location_function : int -> loc
(* for coqdoc *)
@@ -34,10 +33,6 @@ val restore_location_table : location_table -> unit
val check_ident : string -> unit
val check_keyword : string -> unit
-val tparse : string * string -> ((string * string) Stream.t -> string) option
-
-val token_text : string * string -> string
-
type frozen_t
val freeze : unit -> frozen_t
val unfreeze : frozen_t -> unit
@@ -50,3 +45,7 @@ val restore_com_state: com_state -> unit
val set_xml_output_comment : (string -> unit) -> unit
val terminal : string -> string * string
+
+(* The lexer of Coq *)
+
+val lexer : Compat.lexer
diff --git a/parsing/parsing.mllib b/parsing/parsing.mllib
index c705e45cd..c0c1817d1 100644
--- a/parsing/parsing.mllib
+++ b/parsing/parsing.mllib
@@ -1,4 +1,5 @@
Extend
+Extrawit
Pcoq
Egrammar
G_xml
diff --git a/parsing/pcoq.ml4 b/parsing/pcoq.ml4
index 8f7567595..99c6d8528 100644
--- a/parsing/pcoq.ml4
+++ b/parsing/pcoq.ml4
@@ -19,55 +19,28 @@ open Rawterm
open Topconstr
open Genarg
open Tacexpr
+open Extrawit
open Ppextend
-(* The lexer of Coq *)
-
-(* Note: removing a token.
- We do nothing because [remove_token] is called only when removing a grammar
- rule with [Grammar.delete_rule]. The latter command is called only when
- unfreezing the state of the grammar entries (see GRAMMAR summary, file
- env/metasyntax.ml). Therefore, instead of removing tokens one by one,
- we unfreeze the state of the lexer. This restores the behaviour of the
- lexer. B.B. *)
+(* The parser of Coq *)
IFDEF CAMLP5 THEN
-let lexer = {
- Token.tok_func = Lexer.func;
- Token.tok_using = Lexer.add_token;
- Token.tok_removing = (fun _ -> ());
- Token.tok_match = Token.default_match;
- (* Token.parse = Lexer.tparse; *)
- Token.tok_comm = None;
- Token.tok_text = Lexer.token_text }
-
module L =
struct
type te = string * string
- let lexer = lexer
+ let lexer = Lexer.lexer
end
-(* The parser of Coq *)
-
module G = Grammar.GMake(L)
ELSE
-let lexer = {
- Token.func = Lexer.func;
- Token.using = Lexer.add_token;
- Token.removing = (fun _ -> ());
- Token.tparse = Lexer.tparse;
- Token.text = Lexer.token_text }
-
module L =
struct
- let lexer = lexer
+ let lexer = Lexer.lexer
end
-(* The parser of Coq *)
-
module G = Grammar.Make(L)
END
@@ -134,12 +107,17 @@ end
open Gramtypes
+type camlp4_rule =
+ Compat.token Gramext.g_symbol list * Gramext.g_action
+
+type camlp4_entry_rules =
+ (* first two parameters are name and assoc iff a level is created *)
+ string option * Gramext.g_assoc option * camlp4_rule list
+
type ext_kind =
| ByGrammar of
- grammar_object G.Entry.e * Gramext.position option *
- (string option * Gramext.g_assoc option *
- (Compat.token Gramext.g_symbol list * Gramext.g_action) list) list *
- Gramext.g_assoc option
+ grammar_object G.Entry.e * Gramext.position option *
+ camlp4_entry_rules list * Gramext.g_assoc option
| ByGEXTEND of (unit -> unit) * (unit -> unit)
let camlp4_state = ref []
@@ -212,14 +190,14 @@ let map_entry f en =
let parse_string f x =
let strm = Stream.of_string x in Gram.Entry.parse f (Gram.parsable strm)
-type gram_universe = (string, typed_entry) Hashtbl.t
+type gram_universe = string * (string, typed_entry) Hashtbl.t
let trace = ref false
-(* The univ_tab is not part of the state. It contains all the grammar that
+(* The univ_tab is not part of the state. It contains all the grammars that
exist or have existed before in the session. *)
-let univ_tab = (Hashtbl.create 7 : (string, string * gram_universe) Hashtbl.t)
+let univ_tab = (Hashtbl.create 7 : (string, gram_universe) Hashtbl.t)
let create_univ s =
let u = s, Hashtbl.create 29 in Hashtbl.add univ_tab s u; u
@@ -229,49 +207,27 @@ let uconstr = create_univ "constr"
let utactic = create_univ "tactic"
let uvernac = create_univ "vernac"
-let create_univ_if_new s =
- (* compatibilite *)
- let s = if s = "command" then (warning "'command' grammar universe is obsolete; use name 'constr' instead"; "constr") else s in
+let get_univ s =
try
Hashtbl.find univ_tab s
- with Not_found ->
- if !trace then begin
- Printf.eprintf "[Creating univ %s]\n" s; flush stderr; ()
- end;
- let u = s, Hashtbl.create 29 in Hashtbl.add univ_tab s u; u
+ with Not_found ->
+ anomaly ("Unknown grammar universe: "^s)
-let get_univ = create_univ_if_new
+let get_entry (u, utab) s = Hashtbl.find utab s
-let get_entry (u, utab) s =
- try
- Hashtbl.find utab s
- with Not_found ->
+let get_entry_type (u, utab) s =
+ try
+ type_of_typed_entry (get_entry (u, utab) s)
+ with Not_found ->
errorlabstrm "Pcoq.get_entry"
(str "Unknown grammar entry " ++ str u ++ str ":" ++ str s ++ str ".")
let new_entry etyp (u, utab) s =
+ if !trace then (Printf.eprintf "[Creating entry %s:%s]\n" u s; flush stderr);
let ename = u ^ ":" ^ s in
let e = in_typed_entry etyp (Gram.Entry.create ename) in
Hashtbl.add utab s e; e
-let entry_type (u, utab) s =
- try
- let e = Hashtbl.find utab s in
- Some (type_of_typed_entry e)
- with Not_found -> None
-
-let get_entry_type (u,n) = type_of_typed_entry (get_entry (get_univ u) n)
-
-let create_entry_if_new (u, utab) s etyp =
- try
- if type_of_typed_entry (Hashtbl.find utab s) <> etyp then
- failwith ("Entry " ^ u ^ ":" ^ s ^ " already exists with another type")
- with Not_found ->
- if !trace then begin
- Printf.eprintf "[Creating entry %s:%s]\n" u s; flush stderr; ()
- end;
- let _ = new_entry etyp (u, utab) s in ()
-
let create_entry (u, utab) s etyp =
try
let e = Hashtbl.find utab s in
@@ -279,105 +235,13 @@ let create_entry (u, utab) s etyp =
failwith ("Entry " ^ u ^ ":" ^ s ^ " already exists with another type");
e
with Not_found ->
- if !trace then begin
- Printf.eprintf "[Creating entry %s:%s]\n" u s; flush stderr; ()
- end;
new_entry etyp (u, utab) s
-let create_constr_entry u s =
- outGramObj rawwit_constr (create_entry u s ConstrArgType)
-
-let create_generic_entry s wit =
- let (u,utab) = utactic in
- let etyp = unquote wit in
- try
- let e = Hashtbl.find utab s in
- if type_of_typed_entry e <> etyp then
- failwith ("Entry " ^ u ^ ":" ^ s ^ " already exists with another type");
- outGramObj wit e
- with Not_found ->
- if !trace then begin
- Printf.eprintf "[Creating entry %s:%s]\n" u s; flush stderr; ()
- end;
- let e = Gram.Entry.create s in
- Hashtbl.add utab s (inGramObj wit e); e
-
-let get_generic_entry s =
- let (u,utab) = utactic in
- try
- object_of_typed_entry (Hashtbl.find utab s)
- with Not_found ->
- error ("Unknown grammar entry "^u^":"^s^".")
-
-let get_generic_entry_type (u,utab) s =
- try type_of_typed_entry (Hashtbl.find utab s)
- with Not_found ->
- error ("Unknown grammar entry "^u^":"^s^".")
-
-let force_entry_type (u, utab) s etyp =
- try
- let entry = Hashtbl.find utab s in
- let extyp = type_of_typed_entry entry in
- if etyp = extyp then
- entry
- else begin
- prerr_endline
- ("Grammar entry " ^ u ^ ":" ^ s ^
- " redefined with another type;\n older entry hidden.");
- Hashtbl.remove utab s;
- new_entry etyp (u, utab) s
- end
- with Not_found ->
- new_entry etyp (u, utab) s
-
-(* Tactics as arguments *)
-
-let tactic_main_level = 5
-
-let (wit_tactic0,globwit_tactic0,rawwit_tactic0) = create_arg "tactic0"
-let (wit_tactic1,globwit_tactic1,rawwit_tactic1) = create_arg "tactic1"
-let (wit_tactic2,globwit_tactic2,rawwit_tactic2) = create_arg "tactic2"
-let (wit_tactic3,globwit_tactic3,rawwit_tactic3) = create_arg "tactic3"
-let (wit_tactic4,globwit_tactic4,rawwit_tactic4) = create_arg "tactic4"
-let (wit_tactic5,globwit_tactic5,rawwit_tactic5) = create_arg "tactic5"
-
-let wit_tactic = function
- | 0 -> wit_tactic0
- | 1 -> wit_tactic1
- | 2 -> wit_tactic2
- | 3 -> wit_tactic3
- | 4 -> wit_tactic4
- | 5 -> wit_tactic5
- | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
-
-let globwit_tactic = function
- | 0 -> globwit_tactic0
- | 1 -> globwit_tactic1
- | 2 -> globwit_tactic2
- | 3 -> globwit_tactic3
- | 4 -> globwit_tactic4
- | 5 -> globwit_tactic5
- | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
-
-let rawwit_tactic = function
- | 0 -> rawwit_tactic0
- | 1 -> rawwit_tactic1
- | 2 -> rawwit_tactic2
- | 3 -> rawwit_tactic3
- | 4 -> rawwit_tactic4
- | 5 -> rawwit_tactic5
- | n -> anomaly ("Unavailable tactic level: "^string_of_int n)
-
-let tactic_genarg_level s =
- if String.length s = 7 && String.sub s 0 6 = "tactic" then
- let c = s.[6] in if '5' >= c && c >= '0' then Some (Char.code c - 48)
- else None
- else None
-
-let is_tactic_genarg = function
-| ExtraArgType s -> tactic_genarg_level s <> None
-| _ -> false
+let create_constr_entry s =
+ outGramObj rawwit_constr (create_entry uconstr s ConstrArgType)
+let create_generic_entry s wit =
+ outGramObj wit (create_entry utactic s (unquote wit))
(* [make_gen_entry] builds entries extensible by giving its name (a string) *)
(* For entries extensible only via the ML name, Gram.Entry.create is enough *)
@@ -386,7 +250,7 @@ let make_gen_entry (u,univ) rawwit s =
let e = Gram.Entry.create (u ^ ":" ^ s) in
Hashtbl.add univ s (inGramObj rawwit e); e
-(* Grammar entries *)
+(* Initial grammar entries *)
module Prim =
struct
@@ -421,7 +285,6 @@ module Prim =
end
-
module Constr =
struct
let gec_constr = make_gen_entry uconstr rawwit_constr
@@ -432,7 +295,7 @@ module Constr =
let operconstr = gec_constr "operconstr"
let constr_eoi = eoi_entry constr
let lconstr = gec_constr "lconstr"
- let binder_constr = create_constr_entry uconstr "binder_constr"
+ let binder_constr = create_constr_entry "binder_constr"
let ident = make_gen_entry uconstr rawwit_ident "ident"
let global = make_gen_entry uconstr rawwit_ref "global"
let sort = make_gen_entry uconstr rawwit_sort "sort"
@@ -489,8 +352,6 @@ module Tactic =
end
-
-
module Vernac_ =
struct
let gec_vernac s = Gram.Entry.create ("vernac:" ^ s)
@@ -500,24 +361,22 @@ module Vernac_ =
let gallina_ext = gec_vernac "gallina_ext"
let command = gec_vernac "command"
let syntax = gec_vernac "syntax_command"
- let vernac = gec_vernac "Vernac_.vernac"
-
- (* MMode *)
-
+ let vernac = gec_vernac "Vernac.vernac"
let proof_instr = Gram.Entry.create "proofmode:instr"
- (* /MMode *)
-
let vernac_eoi = eoi_entry vernac
- end
-let main_entry = Gram.Entry.create "vernac"
+ (* Main vernac entry *)
+ let main_entry = Gram.Entry.create "vernac"
+ GEXTEND Gram
+ main_entry:
+ [ [ a = vernac -> Some (loc,a) | EOI -> None ] ]
+ ;
+ END
-GEXTEND Gram
- main_entry:
- [ [ a = Vernac_.vernac -> Some (loc,a) | EOI -> None ] ]
- ;
-END
+ end
+
+let main_entry = Vernac_.main_entry
(**********************************************************************)
(* This determines (depending on the associativity of the current
@@ -643,6 +502,9 @@ let find_position forpat assoc level =
let synchronize_level_positions () =
let _ = find_position true None None in ()
+(**********************************************************************)
+(* Binding constr entry keys to entries *)
+
(* Camlp4 levels do not treat NonA: use RightA with a NEXT on the left *)
let camlp4_assoc = function
| Some Gramext.NonA | Some Gramext.RightA -> Gramext.RightA
@@ -698,11 +560,11 @@ let compute_entry allow_create adjust forpat = function
let u = get_univ u in
let e =
try get_entry u n
- with e when allow_create -> create_entry u n ConstrArgType in
+ with Not_found when allow_create -> create_entry u n ConstrArgType in
object_of_typed_entry e, None, true
(* This computes the name of the level where to add a new rule *)
-let get_constr_entry forpat = function
+let interp_constr_entry_key forpat = function
| ETConstr(200,()) when not forpat ->
weaken_entry Constr.binder_constr, None
| e ->
@@ -711,9 +573,12 @@ let get_constr_entry forpat = function
(* This computes the name to give to a production knowing the name and
associativity of the level where it must be added *)
-let get_constr_production_entry ass from forpat en =
+let interp_constr_prod_entry_key ass from forpat en =
compute_entry false (adjust_level ass from) forpat en
+(**********************************************************************)
+(* Binding constr entry keys to symbols *)
+
let is_self from e =
match from, e with
ETConstr(n,()), ETConstr(NumLevel n',
@@ -730,7 +595,7 @@ let is_binder_level from e =
ETConstr(NumLevel 200,(BorderProd(Right,_)|InternalProd)) -> true
| _ -> false
-let rec symbol_of_production assoc from forpat typ =
+let rec symbol_of_constr_prod_entry_key assoc from forpat typ =
if is_binder_level from typ then
if forpat then
Gramext.Snterml (Gram.Entry.obj Constr.pattern,"200")
@@ -741,28 +606,87 @@ let rec symbol_of_production assoc from forpat typ =
else
match typ with
| ETConstrList (typ',[]) ->
- Gramext.Slist1 (symbol_of_production assoc from forpat (ETConstr typ'))
+ Gramext.Slist1 (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'))
| ETConstrList (typ',tkl) ->
Gramext.Slist1sep
- (symbol_of_production assoc from forpat (ETConstr typ'),
+ (symbol_of_constr_prod_entry_key assoc from forpat (ETConstr typ'),
Gramext.srules
[List.map (fun x -> Gramext.Stoken x) tkl,
List.fold_right (fun _ v -> Gramext.action (fun _ -> v)) tkl
(Gramext.action (fun loc -> ()))])
| _ ->
- match get_constr_production_entry assoc from forpat typ with
+ match interp_constr_prod_entry_key assoc from forpat typ with
| (eobj,None,_) -> Gramext.Snterm (Gram.Entry.obj eobj)
| (eobj,Some None,_) -> Gramext.Snext
| (eobj,Some (Some (lev,cur)),_) ->
Gramext.Snterml (Gram.Entry.obj eobj,constr_level lev)
-(*****************************)
-(* Coercions between entries *)
-
-let coerce_reference_to_id = function
- | Ident (_,id) -> id
- | Qualid (loc,_) ->
- user_err_loc (loc, "coerce_reference_to_id",
- str "This expression should be a simple identifier.")
+(**********************************************************************)
+(* Binding general entry keys to symbol *)
+
+let rec symbol_of_prod_entry_key = function
+ | Alist1 s -> Gramext.Slist1 (symbol_of_prod_entry_key s)
+ | Alist1sep (s,sep) ->
+ Gramext.Slist1sep (symbol_of_prod_entry_key s, Gramext.Stoken ("",sep))
+ | Alist0 s -> Gramext.Slist0 (symbol_of_prod_entry_key s)
+ | Alist0sep (s,sep) ->
+ Gramext.Slist0sep (symbol_of_prod_entry_key s, Gramext.Stoken ("",sep))
+ | Aopt s -> Gramext.Sopt (symbol_of_prod_entry_key s)
+ | Amodifiers s ->
+ Gramext.srules
+ [([], Gramext.action(fun _loc -> []));
+ ([Gramext.Stoken ("", "(");
+ Gramext.Slist1sep ((symbol_of_prod_entry_key s), Gramext.Stoken ("", ","));
+ Gramext.Stoken ("", ")")],
+ Gramext.action (fun _ l _ _loc -> l))]
+ | Aself -> Gramext.Sself
+ | Anext -> Gramext.Snext
+ | Atactic 5 -> Gramext.Snterm (Gram.Entry.obj Tactic.binder_tactic)
+ | Atactic n ->
+ Gramext.Snterml (Gram.Entry.obj Tactic.tactic_expr, string_of_int n)
+ | Agram s -> Gramext.Snterm s
+ | Aentry (u,s) ->
+ Gramext.Snterm (Gram.Entry.obj
+ (object_of_typed_entry (get_entry (get_univ u) s)))
-let coerce_global_to_id = coerce_reference_to_id
+(**********************************************************************)
+(* Interpret entry names of the form "ne_constr_list" as entry keys *)
+
+let rec interp_entry_name up_level s sep =
+ let l = String.length s in
+ if l > 8 & String.sub s 0 3 = "ne_" & String.sub s (l-5) 5 = "_list" then
+ let t, g = interp_entry_name up_level (String.sub s 3 (l-8)) "" in
+ List1ArgType t, Alist1 g
+ else if l > 12 & String.sub s 0 3 = "ne_" &
+ String.sub s (l-9) 9 = "_list_sep" then
+ let t, g = interp_entry_name up_level (String.sub s 3 (l-12)) "" in
+ List1ArgType t, Alist1sep (g,sep)
+ else if l > 5 & String.sub s (l-5) 5 = "_list" then
+ let t, g = interp_entry_name up_level (String.sub s 0 (l-5)) "" in
+ List0ArgType t, Alist0 g
+ else if l > 9 & String.sub s (l-9) 9 = "_list_sep" then
+ let t, g = interp_entry_name up_level (String.sub s 0 (l-9)) "" in
+ List0ArgType t, Alist0sep (g,sep)
+ else if l > 4 & String.sub s (l-4) 4 = "_opt" then
+ let t, g = interp_entry_name up_level (String.sub s 0 (l-4)) "" in
+ OptArgType t, Aopt g
+ else if l > 5 & String.sub s (l-5) 5 = "_mods" then
+ let t, g = interp_entry_name up_level (String.sub s 0 (l-1)) "" in
+ List0ArgType t, Amodifiers g
+ else
+ let s = if s = "hyp" then "var" else s in
+ let t, se =
+ match Extrawit.tactic_genarg_level s with
+ | Some n when Some n = up_level & up_level <> Some 5 -> None, Aself
+ | Some n when Some (n+1) = up_level & up_level <> Some 5 -> None, Anext
+ | Some n -> None, Atactic n
+ | None ->
+ try Some (get_entry uprim s), Aentry ("prim",s) with Not_found ->
+ try Some (get_entry uconstr s), Aentry ("constr",s) with Not_found ->
+ try Some (get_entry utactic s), Aentry ("tactic",s) with Not_found ->
+ None, Aentry ("",s) in
+ let t =
+ match t with
+ | Some t -> type_of_typed_entry t
+ | None -> ExtraArgType s in
+ t, se
diff --git a/parsing/pcoq.mli b/parsing/pcoq.mli
index 97a47dcc4..02db8d55d 100644
--- a/parsing/pcoq.mli
+++ b/parsing/pcoq.mli
@@ -12,41 +12,125 @@ open Util
open Names
open Rawterm
open Extend
+open Vernacexpr
open Genarg
open Topconstr
open Tacexpr
-open Vernacexpr
open Libnames
-(* The lexer and parser of Coq. *)
-
-val lexer : Compat.lexer
+(**********************************************************************)
+(* The parser of Coq *)
module Gram : Grammar.S with type te = Compat.token
+(**********************************************************************)
+(* The parser of Coq is built from three kinds of rule declarations:
+ - dynamic rules declared at the evaluation of Coq files (using
+ e.g. Notation, Infix, or Tactic Notation)
+ - static rules explicitly defined in files g_*.ml4
+ - static rules macro-generated by ARGUMENT EXTEND, TACTIC EXTEND and
+ VERNAC EXTEND (see e.g. file extratactics.ml4)
+*)
+
+(* Dynamic extension of rules
+
+ For constr notations, dynamic addition of new rules is done in
+ several steps:
+
+ - "x + y" (user gives a notation string of type Topconstr.notation)
+ | (together with a constr entry level, e.g. 50, and indications of)
+ | (subentries, e.g. x in constr next level and y constr same level)
+ |
+ | spliting into tokens by Metasyntax.split_notation_string
+ V
+ [String "x"; String "+"; String "y"] : symbol_token list
+ |
+ | interpreted as a mixed parsing/printing production
+ | by Metasyntax.analyse_notation_tokens
+ V
+ [NonTerminal "x"; Terminal "+"; NonTerminal "y"] : symbol list
+ |
+ | translated to a parsing production by Metasyntax.make_production
+ V
+ [GramConstrNonTerminal (ETConstr (NextLevel,(BorderProd Left,LeftA)),
+ Some "x");
+ GramConstrTerminal ("","+");
+ GramConstrNonTerminal (ETConstr (NextLevel,(BorderProd Right,LeftA)),
+ Some "y")]
+ : grammar_constr_prod_item list
+ |
+ | Egrammar.make_constr_prod_item
+ V
+ Gramext.g_symbol list which is sent to camlp4
+
+ For user level tactic notations, dynamic addition of new rules is
+ also done in several steps:
+
+ - "f" constr(x) (user gives a Tactic Notation command)
+ |
+ | parsing
+ V
+ [TacTerm "f"; TacNonTerm ("constr", Some "x")]
+ : grammar_tactic_prod_item_expr list
+ |
+ | Metasyntax.interp_prod_item
+ V
+ [GramTerminal "f";
+ GramNonTerminal (ConstrArgType, Aentry ("constr","constr"), Some "x")]
+ : grammar_prod_item list
+ |
+ | Egrammar.make_prod_item
+ V
+ Gramext.g_symbol list
+
+ For TACTIC/VERNAC/ARGUMENT EXTEND, addition of new rules is done as follows:
+
+ - "f" constr(x) (developer gives an EXTEND rule)
+ |
+ | macro-generation in tacextend.ml4/vernacextend.ml4/argextend.ml4
+ V
+ [GramTerminal "f";
+ GramNonTerminal (ConstrArgType, Aentry ("constr","constr"), Some "x")]
+ |
+ | Egrammar.make_prod_item
+ V
+ Gramext.g_symbol list
+
+*)
+
(* The superclass of all grammar entries *)
type grammar_object
+type camlp4_rule =
+ Compat.token Gramext.g_symbol list * Gramext.g_action
+
+type camlp4_entry_rules =
+ (* first two parameters are name and assoc iff a level is created *)
+ string option * Gramext.g_assoc option * camlp4_rule list
+
+(* Add one extension at some camlp4 position of some camlp4 entry *)
+val grammar_extend :
+ grammar_object Gram.Entry.e -> Gramext.position option ->
+ (* for reinitialization if ever needed: *) Gramext.g_assoc option ->
+ camlp4_entry_rules list -> unit
+
+(* Remove the last n extensions *)
+val remove_grammars : int -> unit
+
+
+
+
(* The type of typed grammar objects *)
type typed_entry
+(* The possible types for extensible grammars *)
type entry_type = argument_type
val type_of_typed_entry : typed_entry -> entry_type
val object_of_typed_entry : typed_entry -> grammar_object Gram.Entry.e
val weaken_entry : 'a Gram.Entry.e -> grammar_object Gram.Entry.e
-val get_constr_entry :
- bool -> constr_entry -> grammar_object Gram.Entry.e * int option
-
-val grammar_extend :
- grammar_object Gram.Entry.e -> Gramext.position option ->
- (* for reinitialization if ever: *) Gramext.g_assoc option ->
- (string option * Gramext.g_assoc option *
- (Compat.token Gramext.g_symbol list * Gramext.g_action) list) list
- -> unit
-
-val remove_grammars : int -> unit
+(* Temporary activate camlp4 verbosity *)
val camlp4_verbosity : bool -> ('a -> unit) -> 'a -> unit
@@ -56,73 +140,28 @@ val parse_string : 'a Gram.Entry.e -> string -> 'a
val eoi_entry : 'a Gram.Entry.e -> 'a Gram.Entry.e
val map_entry : ('a -> 'b) -> 'a Gram.Entry.e -> 'b Gram.Entry.e
-(* Entry types *)
-
-(* Table of Coq's grammar entries *)
+(**********************************************************************)
+(* Table of Coq statically defined grammar entries *)
type gram_universe
-val create_univ_if_new : string -> string * gram_universe
-val get_univ : string -> string * gram_universe
-val get_entry : string * gram_universe -> string -> typed_entry
-
-val entry_type : string * gram_universe -> string -> entry_type option
-
-val get_entry_type : string * string -> entry_type
-val create_entry_if_new :
- string * gram_universe -> string -> entry_type -> unit
-val create_entry :
- string * gram_universe -> string -> entry_type -> typed_entry
-val force_entry_type :
- string * gram_universe -> string -> entry_type -> typed_entry
-
-val create_constr_entry :
- string * gram_universe -> string -> constr_expr Gram.Entry.e
-val create_generic_entry : string -> ('a, rlevel) abstract_argument_type -> 'a Gram.Entry.e
-val get_generic_entry : string -> grammar_object Gram.Entry.e
-val get_generic_entry_type : string * gram_universe -> string -> Genarg.argument_type
-
-(* Tactics as arguments *)
+(* There are four predefined universes: "prim", "constr", "tactic", "vernac" *)
-val tactic_main_level : int
+val get_univ : string -> gram_universe
-val rawwit_tactic : int -> (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic : int -> (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic : int -> (glob_tactic_expr,tlevel) abstract_argument_type
+val uprim : gram_universe
+val uconstr : gram_universe
+val utactic : gram_universe
+val uvernac : gram_universe
-val rawwit_tactic0 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic0 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic0 : (glob_tactic_expr,tlevel) abstract_argument_type
+(*
+val get_entry : gram_universe -> string -> typed_entry
+val get_entry_type : gram_universe -> string -> entry_type
+*)
-val rawwit_tactic1 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic1 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic1 : (glob_tactic_expr,tlevel) abstract_argument_type
-
-val rawwit_tactic2 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic2 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic2 : (glob_tactic_expr,tlevel) abstract_argument_type
-
-val rawwit_tactic3 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic3 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic3 : (glob_tactic_expr,tlevel) abstract_argument_type
-
-val rawwit_tactic4 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic4 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic4 : (glob_tactic_expr,tlevel) abstract_argument_type
-
-val rawwit_tactic5 : (raw_tactic_expr,rlevel) abstract_argument_type
-val globwit_tactic5 : (glob_tactic_expr,glevel) abstract_argument_type
-val wit_tactic5 : (glob_tactic_expr,tlevel) abstract_argument_type
-
-val is_tactic_genarg : argument_type -> bool
-
-val tactic_genarg_level : string -> int option
-
-(* The main entry: reads an optional vernac command *)
-
-val main_entry : (loc * vernac_expr) option Gram.Entry.e
-
-(* Initial state of the grammar *)
+val create_entry : gram_universe -> string -> entry_type -> typed_entry
+val create_generic_entry : string -> ('a, rlevel) abstract_argument_type ->
+ 'a Gram.Entry.e
module Prim :
sig
@@ -204,22 +243,38 @@ module Vernac_ :
val command : vernac_expr Gram.Entry.e
val syntax : vernac_expr Gram.Entry.e
val vernac : vernac_expr Gram.Entry.e
-
- (* MMode *)
-
+ val vernac_eoi : vernac_expr Gram.Entry.e
val proof_instr : Decl_expr.raw_proof_instr Gram.Entry.e
+ end
- (*/ MMode *)
+(* The main entry: reads an optional vernac command *)
+val main_entry : (loc * vernac_expr) option Gram.Entry.e
- val vernac_eoi : vernac_expr Gram.Entry.e
- end
+(**********************************************************************)
+(* Mapping formal entries into concrete ones *)
-(* Binding entry names to campl4 entries *)
+(* Binding constr entry keys to entries and symbols *)
-val symbol_of_production : Gramext.g_assoc option -> constr_entry ->
- bool -> constr_production_entry -> Compat.token Gramext.g_symbol
+val interp_constr_entry_key : bool (* true for cases_pattern *) ->
+ constr_entry_key -> grammar_object Gram.Entry.e * int option
-(* Registering/resetting the level of an entry *)
+val symbol_of_constr_prod_entry_key : Gramext.g_assoc option ->
+ constr_entry_key -> bool -> constr_prod_entry_key ->
+ Compat.token Gramext.g_symbol
+
+(* Binding general entry keys to symbols *)
+
+val symbol_of_prod_entry_key :
+ Gram.te prod_entry_key -> Gram.te Gramext.g_symbol
+
+(**********************************************************************)
+(* Interpret entry names of the form "ne_constr_list" as entry keys *)
+
+val interp_entry_name : int option -> string -> string ->
+ entry_type * Gram.te prod_entry_key
+
+(**********************************************************************)
+(* Registering/resetting the level of a constr entry *)
val find_position :
bool (* true if for creation in pattern entry; false if in constr entry *) ->
@@ -234,5 +289,3 @@ val register_empty_levels : bool -> int list ->
string option * Gramext.g_assoc option) list
val remove_levels : int -> unit
-
-val coerce_global_to_id : reference -> identifier
diff --git a/parsing/pptactic.ml b/parsing/pptactic.ml
index 801c0334b..357a572be 100644
--- a/parsing/pptactic.ml
+++ b/parsing/pptactic.ml
@@ -555,12 +555,6 @@ let pr_autoarg_usingTDB = function
| true -> spc () ++ str "using tdb"
| false -> mt ()
-let rec pr_tacarg_using_rule pr_gen = function
- | Egrammar.TacTerm s :: l, al -> spc () ++ str s ++ pr_tacarg_using_rule pr_gen (l,al)
- | Egrammar.TacNonTerm _ :: l, a :: al -> pr_gen a ++ pr_tacarg_using_rule pr_gen (l,al)
- | [], [] -> mt ()
- | _ -> failwith "Inconsistent arguments of extended tactic"
-
let pr_then () = str ";"
let ltop = (5,E)
@@ -1086,7 +1080,7 @@ let _ = Tactic_debug.set_match_rule_printer
(fun rl ->
pr_match_rule false (pr_glob_tactic (Global.env())) pr_constr_pattern rl)
-open Pcoq
+open Extrawit
let pr_tac_polymorphic n _ _ prtac = prtac (n,E)
diff --git a/parsing/ppvernac.ml b/parsing/ppvernac.ml
index 0054326e4..be04f584d 100644
--- a/parsing/ppvernac.ml
+++ b/parsing/ppvernac.ml
@@ -73,7 +73,7 @@ let pr_raw_tactic tac = pr_raw_tactic (Global.env()) tac
let rec extract_signature = function
| [] -> []
- | Egrammar.TacNonTerm (_,(_,t),_) :: l -> t :: extract_signature l
+ | Egrammar.GramNonTerminal (_,t,_,_) :: l -> t :: extract_signature l
| _::l -> extract_signature l
let rec match_vernac_rule tys = function
@@ -119,9 +119,11 @@ let strip_meta id =
else id
let pr_production_item = function
- | VNonTerm (loc,nt,Some p) -> str nt ++ str"(" ++ pr_id (strip_meta p) ++ str")"
- | VNonTerm (loc,nt,None) -> str nt
- | VTerm s -> qs s
+ | TacNonTerm (loc,nt,Some (p,sep)) ->
+ let pp_sep = if sep <> "" then str "," ++ quote (str sep) else mt () in
+ str nt ++ str"(" ++ pr_id (strip_meta p) ++ pp_sep ++ str")"
+ | TacNonTerm (loc,nt,None) -> str nt
+ | TacTerm s -> qs s
let pr_comment pr_c = function
| CommentConstr c -> pr_c c
@@ -811,7 +813,7 @@ let rec pr_vernac = function
++ (if redef then str" ::=" else str" :=") ++ brk(1,1) ++
let idl = List.map Option.get (List.filter (fun x -> not (x=None)) idl)in
pr_raw_tactic_env
- (idl @ List.map coerce_global_to_id
+ (idl @ List.map coerce_reference_to_id
(List.map (fun (x, _, _) -> x) (List.filter (fun (_, redef, _) -> not redef) l)))
(Global.env())
body in
@@ -945,15 +947,15 @@ and pr_extend s cl =
let rl = match_vernac_rule (List.map Genarg.genarg_tag cl) rls in
let start,rl,cl =
match rl with
- | Egrammar.TacTerm s :: rl -> str s, rl, cl
- | Egrammar.TacNonTerm _ :: rl -> pr_arg (List.hd cl), rl, List.tl cl
+ | Egrammar.GramTerminal s :: rl -> str s, rl, cl
+ | Egrammar.GramNonTerminal _ :: rl -> pr_arg (List.hd cl), rl, List.tl cl
| [] -> anomaly "Empty entry" in
let (pp,_) =
List.fold_left
(fun (strm,args) pi ->
let pp,args = match pi with
- | Egrammar.TacNonTerm _ -> (pr_arg (List.hd args), List.tl args)
- | Egrammar.TacTerm s -> (str s, args) in
+ | Egrammar.GramNonTerminal _ -> (pr_arg (List.hd args), List.tl args)
+ | Egrammar.GramTerminal s -> (str s, args) in
(strm ++ spc() ++ pp), args)
(start,cl) rl in
hov 1 pp
diff --git a/parsing/q_util.ml4 b/parsing/q_util.ml4
index 9b59ba8e5..469449749 100644
--- a/parsing/q_util.ml4
+++ b/parsing/q_util.ml4
@@ -13,6 +13,8 @@
(* This file defines standard combinators to build ml expressions *)
open Util
+open Extrawit
+open Pcoq
let not_impl name x =
let desc =
@@ -78,64 +80,16 @@ open Vernacexpr
open Pcoq
open Genarg
-let modifiers e =
-<:expr< Gramext.srules
- [([], Gramext.action(fun _loc -> []));
- ([Gramext.Stoken ("", "(");
- Gramext.Slist1sep ($e$, Gramext.Stoken ("", ","));
- Gramext.Stoken ("", ")")],
- Gramext.action (fun _ l _ _loc -> l))]
- >>
-
-let rec interp_entry_name loc s sep =
- let l = String.length s in
- if l > 8 & String.sub s 0 3 = "ne_" & String.sub s (l-5) 5 = "_list" then
- let t, g = interp_entry_name loc (String.sub s 3 (l-8)) "" in
- List1ArgType t, <:expr< Gramext.Slist1 $g$ >>
- else if l > 12 & String.sub s 0 3 = "ne_" &
- String.sub s (l-9) 9 = "_list_sep" then
- let t, g = interp_entry_name loc (String.sub s 3 (l-12)) "" in
- let sep = <:expr< Gramext.Stoken("",$str:sep$) >> in
- List1ArgType t, <:expr< Gramext.Slist1sep $g$ $sep$ >>
- else if l > 5 & String.sub s (l-5) 5 = "_list" then
- let t, g = interp_entry_name loc (String.sub s 0 (l-5)) "" in
- List0ArgType t, <:expr< Gramext.Slist0 $g$ >>
- else if l > 9 & String.sub s (l-9) 9 = "_list_sep" then
- let t, g = interp_entry_name loc (String.sub s 0 (l-9)) "" in
- let sep = <:expr< Gramext.Stoken("",$str:sep$) >> in
- List0ArgType t, <:expr< Gramext.Slist0sep $g$ $sep$ >>
- else if l > 4 & String.sub s (l-4) 4 = "_opt" then
- let t, g = interp_entry_name loc (String.sub s 0 (l-4)) "" in
- OptArgType t, <:expr< Gramext.Sopt $g$ >>
- else if l > 5 & String.sub s (l-5) 5 = "_mods" then
- let t, g = interp_entry_name loc (String.sub s 0 (l-1)) "" in
- List0ArgType t, modifiers g
- else
- let s = if s = "hyp" then "var" else s in
- let t, se, lev =
- match tactic_genarg_level s with
- | Some 5 ->
- Some (ExtraArgType s), <:expr< Tactic. binder_tactic >>, None
- | Some n ->
- Some (ExtraArgType s), <:expr< Tactic. tactic_expr >>, Some n
- | None ->
- match Pcoq.entry_type (Pcoq.get_univ "prim") s with
- | Some _ as x -> x, <:expr< Prim. $lid:s$ >>, None
- | None ->
- match Pcoq.entry_type (Pcoq.get_univ "constr") s with
- | Some _ as x -> x, <:expr< Constr. $lid:s$ >>, None
- | None ->
- match Pcoq.entry_type (Pcoq.get_univ "tactic") s with
- | Some _ as x -> x, <:expr< Tactic. $lid:s$ >>, None
- | None -> None, <:expr< $lid:s$ >>, None in
- let t =
- match t with
- | Some t -> t
- | None -> ExtraArgType s in
- let entry = match lev with
- | Some n ->
- let s = string_of_int n in
- <:expr< Gramext.Snterml (Pcoq.Gram.Entry.obj $se$, $str:s$) >>
- | None ->
- <:expr< Gramext.Snterm (Pcoq.Gram.Entry.obj $se$) >>
- in t, entry
+let rec mlexpr_of_prod_entry_key = function
+ | Extend.Alist1 s -> <:expr< Extend.Alist1 $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Alist1sep (s,sep) -> <:expr< Extend.Alist1sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
+ | Extend.Alist0 s -> <:expr< Extend.Alist0 $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Alist0sep (s,sep) -> <:expr< Extend.Alist0sep $mlexpr_of_prod_entry_key s$ $str:sep$ >>
+ | Extend.Aopt s -> <:expr< Extend.Aopt $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Amodifiers s -> <:expr< Extend.Amodifiers $mlexpr_of_prod_entry_key s$ >>
+ | Extend.Aself -> <:expr< Extend.Aself >>
+ | Extend.Anext -> <:expr< Extend.Anext >>
+ | Extend.Atactic n -> <:expr< Extend.Atactic $mlexpr_of_int n$ >>
+ | Extend.Agram s -> anomaly "Agram not supported"
+ | Extend.Aentry ("",s) -> <:expr< Extend.Agram (Gram.Entry.obj $lid:s$) >>
+ | Extend.Aentry (u,s) -> <:expr< Extend.Aentry $str:u$ $str:s$ >>
diff --git a/parsing/q_util.mli b/parsing/q_util.mli
index a160310e4..7c0fec9a2 100644
--- a/parsing/q_util.mli
+++ b/parsing/q_util.mli
@@ -32,5 +32,4 @@ val mlexpr_of_string : string -> MLast.expr
val mlexpr_of_option : ('a -> MLast.expr) -> 'a option -> MLast.expr
-val interp_entry_name : Util.loc -> string -> string ->
- Pcoq.entry_type * MLast.expr
+val mlexpr_of_prod_entry_key : Pcoq.Gram.te Extend.prod_entry_key -> MLast.expr
diff --git a/parsing/tacextend.ml4 b/parsing/tacextend.ml4
index 03c704758..fc499241c 100644
--- a/parsing/tacextend.ml4
+++ b/parsing/tacextend.ml4
@@ -15,20 +15,21 @@ open Genarg
open Q_util
open Q_coqast
open Argextend
-
-type grammar_tactic_production_expr =
- | TacTerm of string
- | TacNonTerm of Util.loc * Genarg.argument_type * MLast.expr * string option
+open Pcoq
+open Extrawit
+open Egrammar
let rec make_patt = function
| [] -> <:patt< [] >>
- | TacNonTerm(loc',_,_,Some p)::l ->
+ | GramNonTerminal(loc',_,_,Some p)::l ->
+ let p = Names.string_of_id p in
<:patt< [ $lid:p$ :: $make_patt l$ ] >>
| _::l -> make_patt l
let rec make_when loc = function
| [] -> <:expr< True >>
- | TacNonTerm(loc',t,_,Some p)::l ->
+ | GramNonTerminal(loc',t,_,Some p)::l ->
+ let p = Names.string_of_id p in
let l = make_when loc l in
let loc = join_loc loc' loc in
let t = mlexpr_of_argtype loc' t in
@@ -37,14 +38,15 @@ let rec make_when loc = function
let rec make_let e = function
| [] -> e
- | TacNonTerm(loc,t,_,Some p)::l ->
+ | GramNonTerminal(loc,t,_,Some p)::l ->
+ let p = Names.string_of_id p in
let loc = join_loc loc (MLast.loc_of_expr e) in
let e = make_let e l in
let v = <:expr< Genarg.out_gen $make_wit loc t$ $lid:p$ >> in
let v =
(* Special case for tactics which must be stored in algebraic
form to avoid marshalling closures and to be reprinted *)
- if Pcoq.is_tactic_genarg t then
+ if is_tactic_genarg t then
<:expr< ($v$, Tacinterp.eval_tactic $v$) >>
else v in
<:expr< let $lid:p$ = $v$ in $e$ >>
@@ -57,7 +59,7 @@ let add_clause s (pt,e) l =
let rec extract_signature = function
| [] -> []
- | TacNonTerm (_,t,_,_) :: l -> t :: extract_signature l
+ | GramNonTerminal (_,t,_,_) :: l -> t :: extract_signature l
| _::l -> extract_signature l
let check_unicity s l =
@@ -75,13 +77,15 @@ let make_clauses s l =
let rec make_args = function
| [] -> <:expr< [] >>
- | TacNonTerm(loc,t,_,Some p)::l ->
+ | GramNonTerminal(loc,t,_,Some p)::l ->
+ let p = Names.string_of_id p in
<:expr< [ Genarg.in_gen $make_wit loc t$ $lid:p$ :: $make_args l$ ] >>
| _::l -> make_args l
let rec make_eval_tactic e = function
| [] -> e
- | TacNonTerm(loc,tag,_,Some p)::l when Pcoq.is_tactic_genarg tag ->
+ | GramNonTerminal(loc,tag,_,Some p)::l when is_tactic_genarg tag ->
+ let p = Names.string_of_id p in
let loc = join_loc loc (MLast.loc_of_expr e) in
let e = make_eval_tactic e l in
(* Special case for tactics which must be stored in algebraic
@@ -91,26 +95,27 @@ let rec make_eval_tactic e = function
let rec make_fun e = function
| [] -> e
- | TacNonTerm(loc,_,_,Some p)::l ->
+ | GramNonTerminal(loc,_,_,Some p)::l ->
+ let p = Names.string_of_id p in
<:expr< fun $lid:p$ -> $make_fun e l$ >>
| _::l -> make_fun e l
-let mlexpr_of_grammar_production = function
- | TacTerm s ->
- <:expr< Egrammar.TacTerm $mlexpr_of_string s$ >>
- | TacNonTerm (loc,nt,g,sopt) ->
- <:expr< Egrammar.TacNonTerm $default_loc$ ($g$,$mlexpr_of_argtype loc nt$) $mlexpr_of_option mlexpr_of_string sopt$ >>
+let mlexpr_terminals_of_grammar_tactic_prod_item_expr = function
+ | GramTerminal s -> <:expr< Some $mlexpr_of_string s$ >>
+ | GramNonTerminal (loc,nt,_,sopt) -> <:expr< None >>
-let mlexpr_terminals_of_grammar_production = function
- | TacTerm s -> <:expr< Some $mlexpr_of_string s$ >>
- | TacNonTerm (loc,nt,g,sopt) -> <:expr< None >>
+let make_prod_item = function
+ | GramTerminal s -> <:expr< Egrammar.GramTerminal $str:s$ >>
+ | GramNonTerminal (loc,nt,g,sopt) ->
+ <:expr< Egrammar.GramNonTerminal $default_loc$ $mlexpr_of_argtype loc nt$
+ $mlexpr_of_prod_entry_key g$ $mlexpr_of_option mlexpr_of_ident sopt$ >>
let mlexpr_of_clause =
- mlexpr_of_list (fun (a,b) -> mlexpr_of_list mlexpr_of_grammar_production a)
+ mlexpr_of_list (fun (a,b) -> mlexpr_of_list make_prod_item a)
let rec make_tags loc = function
| [] -> <:expr< [] >>
- | TacNonTerm(loc',t,_,Some p)::l ->
+ | GramNonTerminal(loc',t,_,Some p)::l ->
let l = make_tags loc l in
let loc = join_loc loc' loc in
let t = mlexpr_of_argtype loc' t in
@@ -120,7 +125,7 @@ let rec make_tags loc = function
let make_one_printing_rule se (pt,e) =
let level = mlexpr_of_int 0 in (* only level 0 supported here *)
let loc = MLast.loc_of_expr e in
- let prods = mlexpr_of_list mlexpr_terminals_of_grammar_production pt in
+ let prods = mlexpr_of_list mlexpr_terminals_of_grammar_tactic_prod_item_expr pt in
<:expr< ($se$, $make_tags loc pt$, ($level$, $prods$)) >>
let make_printing_rule se = mlexpr_of_list (make_one_printing_rule se)
@@ -133,10 +138,10 @@ let rec contains_epsilon = function
| ExtraArgType("hintbases") -> true
| _ -> false
let is_atomic = function
- | TacTerm s :: l when
+ | GramTerminal s :: l when
List.for_all (function
- TacTerm _ -> false
- | TacNonTerm(_,t,_,_) -> contains_epsilon t) l
+ GramTerminal _ -> false
+ | GramNonTerminal(_,t,_,_) -> contains_epsilon t) l
-> [s]
| _ -> []
@@ -162,6 +167,7 @@ let declare_tactic loc s cl =
<:str_item<
declare
open Pcoq;
+ open Extrawit;
declare $list:hidden$ end;
try
let _=Tacinterp.add_tactic $se$ (fun [ $list:make_clauses s cl$ ]) in
@@ -189,7 +195,7 @@ EXTEND
tacrule:
[ [ "["; l = LIST1 tacargs; "]"; "->"; "["; e = Pcaml.expr; "]"
->
- if match List.hd l with TacNonTerm _ -> true | _ -> false then
+ if match List.hd l with GramNonTerminal _ -> true | _ -> false then
(* En attendant la syntaxe de tacticielles *)
failwith "Tactic syntax must start with an identifier";
(l,e)
@@ -197,14 +203,14 @@ EXTEND
;
tacargs:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = Q_util.interp_entry_name loc e "" in
- TacNonTerm (loc, t, g, Some s)
+ let t, g = interp_entry_name None e "" in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = Q_util.interp_entry_name loc e sep in
- TacNonTerm (loc, t, g, Some s)
+ let t, g = interp_entry_name None e sep in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| s = STRING ->
if s = "" then Util.user_err_loc (loc,"",Pp.str "Empty terminal.");
- TacTerm s
+ GramTerminal s
] ]
;
END
diff --git a/parsing/vernacextend.ml4 b/parsing/vernacextend.ml4
index dd6b9e8bf..be9e0e422 100644
--- a/parsing/vernacextend.ml4
+++ b/parsing/vernacextend.ml4
@@ -15,28 +15,14 @@ open Genarg
open Q_util
open Q_coqast
open Argextend
-
-type grammar_tactic_production_expr =
- | VernacTerm of string
- | VernacNonTerm of Util.loc * Genarg.argument_type * MLast.expr * string option
-let rec make_patt = function
- | [] -> <:patt< [] >>
- | VernacNonTerm(_,_,_,Some p)::l ->
- <:patt< [ $lid:p$ :: $make_patt l$ ] >>
- | _::l -> make_patt l
-
-let rec make_when loc = function
- | [] -> <:expr< True >>
- | VernacNonTerm(loc',t,_,Some p)::l ->
- let l = make_when loc l in
- let loc = join_loc loc' loc in
- let t = mlexpr_of_argtype loc' t in
- <:expr< Genarg.genarg_tag $lid:p$ = $t$ && $l$ >>
- | _::l -> make_when loc l
+open Tacextend
+open Pcoq
+open Egrammar
let rec make_let e = function
| [] -> e
- | VernacNonTerm(loc,t,_,Some p)::l ->
+ | GramNonTerminal(loc,t,_,Some p)::l ->
+ let p = Names.string_of_id p in
let loc = join_loc loc (MLast.loc_of_expr e) in
let e = make_let e l in
<:expr< let $lid:p$ = Genarg.out_gen $make_rawwit loc t$ $lid:p$ in $e$ >>
@@ -47,11 +33,6 @@ let add_clause s (_,pt,e) l =
let w = Some (make_when (MLast.loc_of_expr e) pt) in
(p, w, make_let e pt)::l
-let rec extract_signature = function
- | [] -> []
- | VernacNonTerm (_,t,_,_) :: l -> t :: extract_signature l
- | _::l -> extract_signature l
-
let check_unicity s l =
let l' = List.map (fun (_,l,_) -> extract_signature l) l in
if not (Util.list_distinct l') then
@@ -65,22 +46,9 @@ let make_clauses s l =
(<:patt< _ >>,None,<:expr< failwith "Vernac extension: cannot occur" >>) in
List.fold_right (add_clause s) l [default]
-let rec make_fun e = function
- | [] -> e
- | VernacNonTerm(loc,_,_,Some p)::l ->
- <:expr< fun $lid:p$ -> $make_fun e l$ >>
- | _::l -> make_fun e l
-
-let mlexpr_of_grammar_production = function
- | VernacTerm s ->
- <:expr< Egrammar.TacTerm $mlexpr_of_string s$ >>
- | VernacNonTerm (loc,nt,g,sopt) ->
- <:expr< Egrammar.TacNonTerm $default_loc$ ($g$,$mlexpr_of_argtype loc nt$) $mlexpr_of_option mlexpr_of_string sopt$ >>
-
let mlexpr_of_clause =
mlexpr_of_list
- (fun (a,b,c) ->
- mlexpr_of_list mlexpr_of_grammar_production (VernacTerm a::b))
+ (fun (a,b,c) -> mlexpr_of_list make_prod_item (GramTerminal a::b))
let declare_command loc s cl =
let gl = mlexpr_of_clause cl in
@@ -88,6 +56,7 @@ let declare_command loc s cl =
<:str_item<
declare
open Pcoq;
+ open Extrawit;
try Vernacinterp.vinterp_add $mlexpr_of_string s$ (fun [ $list:icl$ ])
with e -> Pp.pp (Cerrors.explain_exn e);
Egrammar.extend_vernac_command_grammar $mlexpr_of_string s$ $gl$;
@@ -113,13 +82,13 @@ EXTEND
;
args:
[ [ e = LIDENT; "("; s = LIDENT; ")" ->
- let t, g = Q_util.interp_entry_name loc e "" in
- VernacNonTerm (loc, t, g, Some s)
+ let t, g = interp_entry_name None e "" in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| e = LIDENT; "("; s = LIDENT; ","; sep = STRING; ")" ->
- let t, g = Q_util.interp_entry_name loc e sep in
- VernacNonTerm (loc, t, g, Some s)
+ let t, g = interp_entry_name None e sep in
+ GramNonTerminal (loc, t, g, Some (Names.id_of_string s))
| s = STRING ->
- VernacTerm s
+ GramTerminal s
] ]
;
END
diff --git a/plugins/interface/debug_tac.ml4 b/plugins/interface/debug_tac.ml4
index aad3a765d..79c5fe8a8 100644
--- a/plugins/interface/debug_tac.ml4
+++ b/plugins/interface/debug_tac.ml4
@@ -9,6 +9,7 @@ open Util;;
open Proof_type;;
open Tacexpr;;
open Genarg;;
+open Extrawit;;
let pr_glob_tactic = Pptactic.pr_glob_tactic (Global.env())
@@ -239,9 +240,9 @@ and checked_then: report_holder -> glob_tactic_expr -> glob_tactic_expr -> tacti
by the list of integers given as extra arguments.
*)
-let rawwit_main_tactic = Pcoq.rawwit_tactic Pcoq.tactic_main_level
-let globwit_main_tactic = Pcoq.globwit_tactic Pcoq.tactic_main_level
-let wit_main_tactic = Pcoq.wit_tactic Pcoq.tactic_main_level
+let rawwit_main_tactic = rawwit_tactic tactic_main_level
+let globwit_main_tactic = globwit_tactic tactic_main_level
+let wit_main_tactic = wit_tactic tactic_main_level
let on_then = function [t1;t2;l] ->
diff --git a/plugins/interface/xlate.ml b/plugins/interface/xlate.ml
index 64a9b5c8c..d1e2b03ef 100644
--- a/plugins/interface/xlate.ml
+++ b/plugins/interface/xlate.ml
@@ -694,7 +694,7 @@ let xlate_with_names = function
None -> CT_coerce_ID_OPT_to_INTRO_PATT_OPT ctv_ID_OPT_NONE
| Some fp -> CT_coerce_INTRO_PATT_to_INTRO_PATT_OPT (xlate_intro_pattern fp)
-let rawwit_main_tactic = Pcoq.rawwit_tactic Pcoq.tactic_main_level
+let rawwit_main_tactic = Extrawit.rawwit_tactic Extrawit.tactic_main_level
let rec (xlate_tacarg:raw_tactic_arg -> ct_TACTIC_ARG) =
function
@@ -1342,9 +1342,9 @@ and coerce_genarg_to_TARG x =
(CT_coerce_FORMULA_to_SCOMMENT_CONTENT(xlate_formula
(snd (out_gen
(rawwit_open_constr_gen b) x))))
- | ExtraArgType s as y when Pcoq.is_tactic_genarg y ->
- let n = Option.get (Pcoq.tactic_genarg_level s) in
- let t = xlate_tactic (out_gen (Pcoq.rawwit_tactic n) x) in
+ | ExtraArgType s as y when Extrawit.is_tactic_genarg y ->
+ let n = Option.get (Extrawit.tactic_genarg_level s) in
+ let t = xlate_tactic (out_gen (Extrawit.rawwit_tactic n) x) in
CT_coerce_TACTIC_COM_to_TARG t
| ConstrWithBindingsArgType -> xlate_error "TODO: generic constr with bindings"
| BindingsArgType -> xlate_error "TODO: generic with bindings"
@@ -1437,9 +1437,9 @@ let coerce_genarg_to_VARG x =
(CT_coerce_FORMULA_to_FORMULA_OPT (xlate_formula (out_gen rawwit_constr x)))
| ConstrMayEvalArgType -> xlate_error"TODO: generic constr-may-eval argument"
| QuantHypArgType ->xlate_error"TODO: generic quantified hypothesis argument"
- | ExtraArgType s as y when Pcoq.is_tactic_genarg y ->
- let n = Option.get (Pcoq.tactic_genarg_level s) in
- let t = xlate_tactic (out_gen (Pcoq.rawwit_tactic n) x) in
+ | ExtraArgType s as y when Extrawit.is_tactic_genarg y ->
+ let n = Option.get (Extrawit.tactic_genarg_level s) in
+ let t = xlate_tactic (out_gen (Extrawit.rawwit_tactic n) x) in
CT_coerce_TACTIC_OPT_to_VARG (CT_coerce_TACTIC_COM_to_TACTIC_OPT t)
| OpenConstrArgType _ -> xlate_error "TODO: generic open constr"
| ConstrWithBindingsArgType -> xlate_error "TODO: generic constr with bindings"
@@ -1576,24 +1576,24 @@ let xlate_level = function
| Extend.NextLevel -> CT_next_level;;
let xlate_syntax_modifier = function
- Extend.SetItemLevel((s::sl), level) ->
+ SetItemLevel((s::sl), level) ->
CT_set_item_level
(CT_id_ne_list(CT_ident s, List.map (fun s -> CT_ident s) sl),
xlate_level level)
- | Extend.SetItemLevel([], _) -> assert false
- | Extend.SetLevel level -> CT_set_level (CT_int level)
- | Extend.SetAssoc Gramext.LeftA -> CT_lefta
- | Extend.SetAssoc Gramext.RightA -> CT_righta
- | Extend.SetAssoc Gramext.NonA -> CT_nona
- | Extend.SetEntryType(x,typ) ->
+ | SetItemLevel([], _) -> assert false
+ | SetLevel level -> CT_set_level (CT_int level)
+ | SetAssoc Gramext.LeftA -> CT_lefta
+ | SetAssoc Gramext.RightA -> CT_righta
+ | SetAssoc Gramext.NonA -> CT_nona
+ | SetEntryType(x,typ) ->
CT_entry_type(CT_ident x,
match typ with
Extend.ETName -> CT_ident "ident"
| Extend.ETReference -> CT_ident "global"
| Extend.ETBigint -> CT_ident "bigint"
| _ -> xlate_error "syntax_type not parsed")
- | Extend.SetOnlyParsing -> CT_only_parsing
- | Extend.SetFormat(_,s) -> CT_format(CT_string s);;
+ | SetOnlyParsing -> CT_only_parsing
+ | SetFormat(_,s) -> CT_format(CT_string s);;
let rec xlate_module_type = function
diff --git a/tactics/tacinterp.ml b/tactics/tacinterp.ml
index da7ae038a..5342f961d 100644
--- a/tactics/tacinterp.ml
+++ b/tactics/tacinterp.ml
@@ -46,6 +46,7 @@ open Inductiveops
open Syntax_def
open Pretyping
open Pretyping.Default
+open Extrawit
open Pcoq
let safe_msgnl s =
@@ -1659,6 +1660,10 @@ let interp_message ist l =
are raised now and not at printing time *)
prlist (fun x -> spc () ++ x) (List.map (interp_message_token ist) l)
+let intro_pattern_list_of_Vlist loc env = function
+ | VList l -> List.map (fun a -> loc,coerce_to_intro_pattern env a) l
+ | _ -> raise Not_found
+
let rec interp_intro_pattern ist gl = function
| loc, IntroOrAndPattern l ->
loc, IntroOrAndPattern (interp_or_and_intro_pattern ist gl l)
@@ -1670,7 +1675,14 @@ let rec interp_intro_pattern ist gl = function
as x -> x
and interp_or_and_intro_pattern ist gl =
- List.map (List.map (interp_intro_pattern ist gl))
+ List.map (interp_intro_pattern_list_as_list ist gl)
+
+and interp_intro_pattern_list_as_list ist gl = function
+ | [loc,IntroIdentifier id] as l ->
+ (try intro_pattern_list_of_Vlist loc (pf_env gl) (List.assoc id ist.lfun)
+ with Not_found | CannotCoerceTo _ ->
+ List.map (interp_intro_pattern ist gl) l)
+ | l -> List.map (interp_intro_pattern ist gl) l
let interp_in_hyp_as ist gl (id,ipat) =
(interp_hyp ist gl id,Option.map (interp_intro_pattern ist gl) ipat)
@@ -2216,7 +2228,7 @@ and interp_tactic ist tac gl =
and interp_atomic ist gl = function
(* Basic tactics *)
| TacIntroPattern l ->
- h_intro_patterns (List.map (interp_intro_pattern ist gl) l)
+ h_intro_patterns (interp_intro_pattern_list_as_list ist gl l)
| TacIntrosUntil hyp ->
h_intros_until (interp_quantified_hypothesis ist hyp)
| TacIntroMove (ido,hto) ->
@@ -2374,9 +2386,8 @@ and interp_atomic ist gl = function
VIntroPattern
(snd (interp_intro_pattern ist gl (out_gen globwit_intro_pattern x)))
| IdentArgType b ->
- VIntroPattern
- (IntroIdentifier
- (interp_fresh_ident ist gl (out_gen (globwit_ident_gen b) x)))
+ value_of_ident (interp_fresh_ident ist gl
+ (out_gen (globwit_ident_gen b) x))
| VarArgType ->
mk_hyp_value ist gl (out_gen globwit_var x)
| RefArgType ->
@@ -2405,6 +2416,10 @@ and interp_atomic ist gl = function
| List0ArgType IntOrVarArgType ->
let wit = wit_list0 globwit_int_or_var in
VList (List.map (mk_int_or_var_value ist) (out_gen wit x))
+ | List0ArgType (IdentArgType b) ->
+ let wit = wit_list0 (globwit_ident_gen b) in
+ let mk_ident x = value_of_ident (interp_fresh_ident ist gl x) in
+ VList (List.map mk_ident (out_gen wit x))
| List1ArgType ConstrArgType ->
let wit = wit_list1 globwit_constr in
VList (List.map (mk_constr_value ist gl) (out_gen wit x))
@@ -2417,6 +2432,10 @@ and interp_atomic ist gl = function
| List1ArgType IntOrVarArgType ->
let wit = wit_list1 globwit_int_or_var in
VList (List.map (mk_int_or_var_value ist) (out_gen wit x))
+ | List1ArgType (IdentArgType b) ->
+ let wit = wit_list1 (globwit_ident_gen b) in
+ let mk_ident x = value_of_ident (interp_fresh_ident ist gl x) in
+ VList (List.map mk_ident (out_gen wit x))
| StringArgType | BoolArgType
| QuantHypArgType | RedExprArgType
| OpenConstrArgType _ | ConstrWithBindingsArgType
@@ -2840,7 +2859,7 @@ let make_absolute_name ident repl =
try
let id, kn =
if repl then None, Nametab.locate_tactic (snd (qualid_of_reference ident))
- else let id = Pcoq.coerce_global_to_id ident in
+ else let id = coerce_reference_to_id ident in
Some id, Lib.make_kn id
in
if Gmap.mem kn !mactab then
diff --git a/toplevel/command.ml b/toplevel/command.ml
index ed21213ef..4fb56dfd6 100644
--- a/toplevel/command.ml
+++ b/toplevel/command.ml
@@ -939,7 +939,7 @@ in
| InSet -> "_rec_nodep"
| InType -> "_rect_nodep")
) in
- let newid = (string_of_id (Pcoq.coerce_global_to_id y))^suffix in
+ let newid = (string_of_id (coerce_reference_to_id y))^suffix in
let newref = (dummy_loc,id_of_string newid) in
((newref,x,y,z)::l1),l2
| EqualityScheme x -> l1,(x::l2)
diff --git a/toplevel/metasyntax.ml b/toplevel/metasyntax.ml
index c0105c8b3..09b76d3f3 100644
--- a/toplevel/metasyntax.ml
+++ b/toplevel/metasyntax.ml
@@ -28,7 +28,7 @@ open Notation
(**********************************************************************)
(* Tokens *)
-let cache_token (_,s) = Compat.using Pcoq.lexer ("", s)
+let cache_token (_,s) = add_token ("", s)
let (inToken, outToken) =
declare_object {(default_object "TOKEN") with
@@ -43,15 +43,20 @@ let add_token_obj s = Lib.add_anonymous_leaf (inToken s)
(**********************************************************************)
(* Tactic Notation *)
+let interp_prod_item lev = function
+ | TacTerm s -> GramTerminal s
+ | TacNonTerm (loc, nt, po) ->
+ let sep = match po with Some (_,sep) -> sep | _ -> "" in
+ let (etyp, e) = interp_entry_name (Some lev) nt sep in
+ GramNonTerminal (loc, etyp, e, Option.map fst po)
+
let make_terminal_status = function
- | VTerm s -> Some s
- | VNonTerm _ -> None
-
-let rec make_tags lev = function
- | VTerm s :: l -> make_tags lev l
- | VNonTerm (loc, nt, po) :: l ->
- let (etyp, _) = Egrammar.interp_entry_name lev nt in
- etyp :: make_tags lev l
+ | GramTerminal s -> Some s
+ | GramNonTerminal _ -> None
+
+let rec make_tags = function
+ | GramTerminal s :: l -> make_tags l
+ | GramNonTerminal (loc, etyp, _, po) :: l -> etyp :: make_tags l
| [] -> []
let cache_tactic_notation (_,(pa,pp)) =
@@ -73,11 +78,11 @@ let (inTacticGrammar, outTacticGrammar) =
export_function = (fun x -> Some x)}
let cons_production_parameter l = function
- | VTerm _ -> l
- | VNonTerm (_,_,ido) -> Option.List.cons ido l
+ | GramTerminal _ -> l
+ | GramNonTerminal (_,_,_,ido) -> Option.List.cons ido l
let rec tactic_notation_key = function
- | VTerm id :: _ -> id
+ | GramTerminal id :: _ -> id
| _ :: l -> tactic_notation_key l
| [] -> "terminal_free_notation"
@@ -86,7 +91,8 @@ let rec next_key_away key t =
else key
let add_tactic_notation (n,prods,e) =
- let tags = make_tags n prods in
+ let prods = List.map (interp_prod_item n) prods in
+ let tags = make_tags prods in
let key = next_key_away (tactic_notation_key prods) tags in
let pprule = (key,tags,(n,List.map make_terminal_status prods)) in
let ids = List.fold_left cons_production_parameter [] prods in
@@ -570,19 +576,19 @@ let is_not_small_constr = function
| _ -> false
let rec define_keywords_aux = function
- NonTerm(_,Some(_,e)) as n1 :: Term("IDENT",k) :: l
+ GramConstrNonTerminal(e,Some _) as n1 :: GramConstrTerminal("IDENT",k) :: l
when is_not_small_constr e ->
message ("Defining '"^k^"' as keyword");
Lexer.add_token("",k);
- n1 :: Term("",k) :: define_keywords_aux l
+ n1 :: GramConstrTerminal("",k) :: define_keywords_aux l
| n :: l -> n :: define_keywords_aux l
| [] -> []
let define_keywords = function
- Term("IDENT",k)::l ->
+ GramConstrTerminal("IDENT",k)::l ->
message ("Defining '"^k^"' as keyword");
Lexer.add_token("",k);
- Term("",k) :: define_keywords_aux l
+ GramConstrTerminal("",k) :: define_keywords_aux l
| l -> define_keywords_aux l
let make_production etyps symbols =
@@ -591,9 +597,9 @@ let make_production etyps symbols =
(fun t l -> match t with
| NonTerminal m ->
let typ = List.assoc m etyps in
- NonTerm (typ, Some (m,typ)) :: l
+ GramConstrNonTerminal (typ, Some m) :: l
| Terminal s ->
- Term (terminal s) :: l
+ GramConstrTerminal (terminal s) :: l
| Break _ ->
l
| SProdList (x,sl) ->
@@ -606,7 +612,7 @@ let make_production etyps symbols =
| _ ->
error "Component of recursive patterns in notation must be constr." in
let typ = ETConstrList (y,sl) in
- NonTerm (typ, Some (x,typ)) :: l)
+ GramConstrNonTerminal (typ, Some x) :: l)
symbols [] in
define_keywords prod
diff --git a/toplevel/metasyntax.mli b/toplevel/metasyntax.mli
index d4b61eb00..4973cdfe6 100644
--- a/toplevel/metasyntax.mli
+++ b/toplevel/metasyntax.mli
@@ -24,7 +24,7 @@ val add_token_obj : string -> unit
(* Adding a tactic notation in the environment *)
val add_tactic_notation :
- int * grammar_production list * raw_tactic_expr -> unit
+ int * grammar_tactic_prod_item_expr list * raw_tactic_expr -> unit
(* Adding a (constr) notation in the environment*)
diff --git a/toplevel/vernacexpr.ml b/toplevel/vernacexpr.ml
index 94ebce9ea..47b36ede0 100644
--- a/toplevel/vernacexpr.ml
+++ b/toplevel/vernacexpr.ml
@@ -171,9 +171,17 @@ type inductive_expr =
type module_binder = bool option * lident list * module_type_ast
-type grammar_production =
- | VTerm of string
- | VNonTerm of loc * string * Names.identifier option
+type grammar_tactic_prod_item_expr =
+ | TacTerm of string
+ | TacNonTerm of loc * string * (Names.identifier * string) option
+
+type syntax_modifier =
+ | SetItemLevel of string list * production_level
+ | SetLevel of int
+ | SetAssoc of Gramext.g_assoc
+ | SetEntryType of string * simple_constr_prod_entry_key
+ | SetOnlyParsing
+ | SetFormat of string located
type proof_end =
| Admitted
@@ -191,7 +199,7 @@ type vernac_expr =
| VernacTimeout of int * vernac_expr
(* Syntax *)
- | VernacTacticNotation of int * grammar_production list * raw_tactic_expr
+ | VernacTacticNotation of int * grammar_tactic_prod_item_expr list * raw_tactic_expr
| VernacSyntaxExtension of locality_flag * (lstring * syntax_modifier list)
| VernacOpenCloseScope of (locality_flag * bool * scope_name)
| VernacDelimiters of scope_name * lstring