1 (* Copyright (C) 2005, HELM Team.
3 * This file is part of HELM, an Hypertextual, Electronic
4 * Library of Mathematics, developed at the Computer Science
5 * Department, University of Bologna, Italy.
7 * HELM is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * HELM is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with HELM; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * For details, see the HELM World-Wide-Web page,
23 * http://helm.cs.unibo.it/
29 let set_callback f = out := f
31 module Ast = CicNotationPt
33 exception NoInclusionPerformed of string (* full path *)
35 type 'a localized_option =
37 | LNone of GrafiteAst.loc
40 (CicNotationPt.term, CicNotationPt.term,
41 CicNotationPt.term GrafiteAst.reduction,
42 CicNotationPt.term CicNotationPt.obj, string)
46 ?never_include:bool ->
47 include_paths:string list ->
48 LexiconEngine.status ->
49 LexiconEngine.status * ast_statement localized_option
51 type parser_status = {
53 term : CicNotationPt.term Grammar.Entry.e;
54 statement : statement Grammar.Entry.e;
57 let initial_parser () =
58 let grammar = CicNotationParser.level2_ast_grammar () in
59 let term = CicNotationParser.term () in
60 let statement = Grammar.Entry.create grammar "statement" in
61 { grammar = grammar; term = term; statement = statement }
64 let grafite_parser = ref (initial_parser ())
66 let add_raw_attribute ~text t = Ast.AttributedTerm (`Raw text, t)
68 let default_associativity = Gramext.NonA
70 let mk_rec_corec ind_kind defs loc =
71 (* In case of mutual definitions here we produce just
72 the syntax tree for the first one. The others will be
73 generated from the completely specified term just before
74 insertion in the environment. We use the flavour
75 `MutualDefinition to rememer this. *)
78 | (params,(Ast.Ident (name, None), Some ty),_,_) :: _ ->
81 (fun var ty -> Ast.Binder (`Pi,var,ty)
85 | (_,(Ast.Ident (name, None), None),_,_) :: _ ->
89 let body = Ast.Ident (name,None) in
91 if List.length defs = 1 then
96 GrafiteAst.Obj (loc, Ast.Theorem(flavour, name, ty,
97 Some (Ast.LetRec (ind_kind, defs, body))))
99 type by_continuation =
101 | BYC_weproved of CicNotationPt.term * string option * CicNotationPt.term option
102 | BYC_letsuchthat of string * CicNotationPt.term * string * CicNotationPt.term
103 | BYC_wehaveand of string * CicNotationPt.term * string * CicNotationPt.term
105 let initialize_parser () =
106 (* {{{ parser initialization *)
107 let term = !grafite_parser.term in
108 let statement = !grafite_parser.statement in
109 let let_defs = CicNotationParser.let_defs () in
110 let protected_binder_vars = CicNotationParser.protected_binder_vars () in
112 GLOBAL: term statement;
113 constructor: [ [ name = IDENT; SYMBOL ":"; typ = term -> (name, typ) ] ];
114 tactic_term: [ [ t = term LEVEL "90" -> t ] ];
116 [ id = IDENT -> Some id
117 | SYMBOL "_" -> None ]
119 ident_list0: [ [ LPAREN; idents = LIST0 new_name; RPAREN -> idents ] ];
121 [ tactic_terms = LIST1 tactic_term SEP SYMBOL "," -> tactic_terms ]
124 [ IDENT "normalize" -> `Normalize
125 | IDENT "simplify" -> `Simpl
126 | IDENT "unfold"; t = OPT tactic_term -> `Unfold t
127 | IDENT "whd" -> `Whd ]
129 sequent_pattern_spec: [
133 path = OPT [SYMBOL ":" ; path = tactic_term -> path ] ->
134 (id,match path with Some p -> p | None -> Ast.UserInput) ];
135 goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = tactic_term -> term ] ->
137 match goal_path, hyp_paths with
138 None, [] -> Some Ast.UserInput
140 | Some goal_path, _ -> Some goal_path
149 [ "match" ; wanted = tactic_term ;
150 sps = OPT [ "in"; sps = sequent_pattern_spec -> sps ] ->
152 | sps = sequent_pattern_spec ->
155 let wanted,hyp_paths,goal_path =
156 match wanted_and_sps with
157 wanted,None -> wanted, [], Some Ast.UserInput
158 | wanted,Some (hyp_paths,goal_path) -> wanted,hyp_paths,goal_path
160 wanted, hyp_paths, goal_path ] ->
162 None -> None,[],Some Ast.UserInput
166 [ SYMBOL ">" -> `LeftToRight
167 | SYMBOL "<" -> `RightToLeft ]
169 int: [ [ num = NUMBER -> int_of_string num ] ];
171 [ idents = OPT ident_list0 ->
172 match idents with None -> [] | Some idents -> idents
176 [ OPT [ IDENT "names" ];
177 num = OPT [ num = int -> num ];
178 idents = intros_names ->
182 using: [ [ using = OPT [ IDENT "using"; t = tactic_term -> t ] -> using ] ];
184 [ IDENT "napply"; t = tactic_term -> GrafiteAst.NApply (loc, t)
185 | IDENT "ncases"; what = tactic_term ; where = pattern_spec ->
186 GrafiteAst.NCases (loc, what, where)
187 | IDENT "nchange"; what = pattern_spec; "with"; with_what = tactic_term ->
188 GrafiteAst.NChange (loc, what, with_what)
189 | IDENT "nelim"; what = tactic_term ; where = pattern_spec ->
190 GrafiteAst.NElim (loc, what, where)
191 | SYMBOL "#"; n=IDENT -> GrafiteAst.NIntro (loc,n)
192 | SYMBOL "#"; SYMBOL "_" -> GrafiteAst.NIntro (loc,"_")
193 | SYMBOL "*" -> GrafiteAst.NCase1 (loc,"_")
194 | SYMBOL "*"; n=IDENT ->
195 GrafiteAst.NCase1 (loc,n)
199 [ IDENT "absurd"; t = tactic_term ->
200 GrafiteAst.Absurd (loc, t)
201 | IDENT "apply"; IDENT "rule"; t = tactic_term ->
202 GrafiteAst.ApplyRule (loc, t)
203 | IDENT "apply"; t = tactic_term ->
204 GrafiteAst.Apply (loc, t)
205 | IDENT "applyP"; t = tactic_term ->
206 GrafiteAst.ApplyP (loc, t)
207 | IDENT "applyS"; t = tactic_term ; params = auto_params ->
208 GrafiteAst.ApplyS (loc, t, params)
209 | IDENT "assumption" ->
210 GrafiteAst.Assumption loc
211 | IDENT "autobatch"; params = auto_params ->
212 GrafiteAst.AutoBatch (loc,params)
213 | IDENT "cases"; what = tactic_term;
214 pattern = OPT pattern_spec;
215 specs = intros_spec ->
216 let pattern = match pattern with
217 | None -> None, [], Some Ast.UserInput
218 | Some pattern -> pattern
220 GrafiteAst.Cases (loc, what, pattern, specs)
221 | IDENT "clear"; ids = LIST1 IDENT ->
222 GrafiteAst.Clear (loc, ids)
223 | IDENT "clearbody"; id = IDENT ->
224 GrafiteAst.ClearBody (loc,id)
225 | IDENT "change"; what = pattern_spec; "with"; t = tactic_term ->
226 GrafiteAst.Change (loc, what, t)
227 | IDENT "compose"; times = OPT int; t1 = tactic_term; t2 =
228 OPT [ "with"; t = tactic_term -> t ]; specs = intros_spec ->
229 let times = match times with None -> 1 | Some i -> i in
230 GrafiteAst.Compose (loc, t1, t2, times, specs)
231 | IDENT "constructor"; n = int ->
232 GrafiteAst.Constructor (loc, n)
233 | IDENT "contradiction" ->
234 GrafiteAst.Contradiction loc
235 | IDENT "cut"; t = tactic_term; ident = OPT [ "as"; id = IDENT -> id] ->
236 GrafiteAst.Cut (loc, ident, t)
237 | IDENT "decompose"; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
238 let idents = match idents with None -> [] | Some idents -> idents in
239 GrafiteAst.Decompose (loc, idents)
240 | IDENT "demodulate"; p = auto_params -> GrafiteAst.Demodulate (loc, p)
241 | IDENT "destruct"; xts = OPT [ ts = tactic_term_list1 -> ts ] ->
242 GrafiteAst.Destruct (loc, xts)
243 | IDENT "elim"; what = tactic_term; using = using;
244 pattern = OPT pattern_spec;
245 ispecs = intros_spec ->
246 let pattern = match pattern with
247 | None -> None, [], Some Ast.UserInput
248 | Some pattern -> pattern
250 GrafiteAst.Elim (loc, what, using, pattern, ispecs)
251 | IDENT "elimType"; what = tactic_term; using = using;
252 (num, idents) = intros_spec ->
253 GrafiteAst.ElimType (loc, what, using, (num, idents))
254 | IDENT "exact"; t = tactic_term ->
255 GrafiteAst.Exact (loc, t)
257 GrafiteAst.Exists loc
258 | IDENT "fail" -> GrafiteAst.Fail loc
259 | IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
262 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error
263 ("the pattern cannot specify the term to replace, only its"
264 ^ " paths in the hypotheses and in the conclusion")))
266 GrafiteAst.Fold (loc, kind, t, p)
268 GrafiteAst.Fourier loc
269 | IDENT "fwd"; hyp = IDENT; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
270 let idents = match idents with None -> [] | Some idents -> idents in
271 GrafiteAst.FwdSimpl (loc, hyp, idents)
272 | IDENT "generalize"; p=pattern_spec; id = OPT ["as" ; id = IDENT -> id] ->
273 GrafiteAst.Generalize (loc,p,id)
274 | IDENT "id" -> GrafiteAst.IdTac loc
275 | IDENT "intro"; ident = OPT IDENT ->
276 let idents = match ident with None -> [] | Some id -> [Some id] in
277 GrafiteAst.Intros (loc, (Some 1, idents))
278 | IDENT "intros"; specs = intros_spec ->
279 GrafiteAst.Intros (loc, specs)
280 | IDENT "inversion"; t = tactic_term ->
281 GrafiteAst.Inversion (loc, t)
283 linear = OPT [ IDENT "linear" ];
284 depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
286 to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
287 ident = OPT [ "as" ; ident = IDENT -> ident ] ->
288 let linear = match linear with None -> false | Some _ -> true in
289 let to_what = match to_what with None -> [] | Some to_what -> to_what in
290 GrafiteAst.LApply (loc, linear, depth, to_what, what, ident)
291 | IDENT "left" -> GrafiteAst.Left loc
292 | IDENT "letin"; where = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term ->
293 GrafiteAst.LetIn (loc, t, where)
294 | kind = reduction_kind; p = pattern_spec ->
295 GrafiteAst.Reduce (loc, kind, p)
296 | IDENT "reflexivity" ->
297 GrafiteAst.Reflexivity loc
298 | IDENT "replace"; p = pattern_spec; "with"; t = tactic_term ->
299 GrafiteAst.Replace (loc, p, t)
300 | IDENT "rewrite" ; d = direction; t = tactic_term ; p = pattern_spec;
301 xnames = OPT [ "as"; n = ident_list0 -> n ] ->
305 (HExtlib.Localized (loc,
306 (CicNotationParser.Parse_error
307 "the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion")))
309 let n = match xnames with None -> [] | Some names -> names in
310 GrafiteAst.Rewrite (loc, d, t, p, n)
317 | IDENT "symmetry" ->
318 GrafiteAst.Symmetry loc
319 | IDENT "transitivity"; t = tactic_term ->
320 GrafiteAst.Transitivity (loc, t)
321 (* Produzioni Aggiunte *)
322 | IDENT "assume" ; id = IDENT ; SYMBOL ":" ; t = tactic_term ->
323 GrafiteAst.Assume (loc, id, t)
324 | IDENT "suppose" ; t = tactic_term ; LPAREN ; id = IDENT ; RPAREN ;
325 t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ;
326 t' = tactic_term -> t']->
327 GrafiteAst.Suppose (loc, t, id, t1)
328 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
329 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
330 id2 = IDENT ; RPAREN ->
331 GrafiteAst.ExistsElim (loc, `Auto ([],[]), id1, t1, id2, t2)
333 [ IDENT "using"; t=tactic_term -> `Term t
334 | params = auto_params -> `Auto params] ;
335 cont=by_continuation ->
337 BYC_done -> GrafiteAst.Bydone (loc, just)
338 | BYC_weproved (ty,id,t1) ->
339 GrafiteAst.By_just_we_proved(loc, just, ty, id, t1)
340 | BYC_letsuchthat (id1,t1,id2,t2) ->
341 GrafiteAst.ExistsElim (loc, just, id1, t1, id2, t2)
342 | BYC_wehaveand (id1,t1,id2,t2) ->
343 GrafiteAst.AndElim (loc, just, id1, t1, id2, t2))
344 | IDENT "we" ; IDENT "need" ; "to" ; IDENT "prove" ; t = tactic_term ; id = OPT [ LPAREN ; id = IDENT ; RPAREN -> id ] ; t1 = OPT [IDENT "or" ; IDENT "equivalently"; t' = tactic_term -> t']->
345 GrafiteAst.We_need_to_prove (loc, t, id, t1)
346 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "cases" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
347 GrafiteAst.We_proceed_by_cases_on (loc, t, t1)
348 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "induction" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
349 GrafiteAst.We_proceed_by_induction_on (loc, t, t1)
350 | IDENT "by" ; IDENT "induction" ; IDENT "hypothesis" ; IDENT "we" ; IDENT "know" ; t=tactic_term ; LPAREN ; id = IDENT ; RPAREN ->
351 GrafiteAst.Byinduction(loc, t, id)
352 | IDENT "the" ; IDENT "thesis" ; IDENT "becomes" ; t=tactic_term ->
353 GrafiteAst.Thesisbecomes(loc, t)
354 | IDENT "case" ; id = IDENT ; params=LIST0[LPAREN ; i=IDENT ;
355 SYMBOL":" ; t=tactic_term ; RPAREN -> i,t] ->
356 GrafiteAst.Case(loc,id,params)
357 (* DO NOT FACTORIZE with the two following, camlp5 sucks*)
359 termine = tactic_term;
363 [ IDENT "using"; t=tactic_term -> `Term t
364 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
365 | IDENT "proof" -> `Proof
366 | params = auto_params -> `Auto params];
367 cont = rewriting_step_continuation ->
368 GrafiteAst.RewritingStep(loc, Some (None,termine), t1, t2, cont)
369 | IDENT "obtain" ; name = IDENT;
370 termine = tactic_term;
374 [ IDENT "using"; t=tactic_term -> `Term t
375 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
376 | IDENT "proof" -> `Proof
377 | params = auto_params -> `Auto params];
378 cont = rewriting_step_continuation ->
379 GrafiteAst.RewritingStep(loc, Some (Some name,termine), t1, t2, cont)
383 [ IDENT "using"; t=tactic_term -> `Term t
384 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
385 | IDENT "proof" -> `Proof
386 | params = auto_params -> `Auto params];
387 cont = rewriting_step_continuation ->
388 GrafiteAst.RewritingStep(loc, None, t1, t2, cont)
392 [ IDENT "paramodulation"
404 i = auto_fixed_param -> i,""
405 | i = auto_fixed_param ; SYMBOL "="; v = [ v = int ->
406 string_of_int v | v = IDENT -> v ] -> i,v ];
407 tl = OPT [ IDENT "by"; tl = tactic_term_list1 -> tl] ->
408 (match tl with Some l -> l | None -> []),
413 [ WEPROVED; ty = tactic_term ; LPAREN ; id = IDENT ; RPAREN ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] -> BYC_weproved (ty,Some id,t1)
414 | WEPROVED; ty = tactic_term ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] ;
415 "done" -> BYC_weproved (ty,None,t1)
417 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
418 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
419 id2 = IDENT ; RPAREN -> BYC_letsuchthat (id1,t1,id2,t2)
420 | WEHAVE; t1=tactic_term ; LPAREN ; id1=IDENT ; RPAREN ;"and" ; t2=tactic_term ; LPAREN ; id2=IDENT ; RPAREN ->
421 BYC_wehaveand (id1,t1,id2,t2)
424 rewriting_step_continuation : [
431 [ t1 = SELF; SYMBOL ";"; t2 = SELF ->
434 | GrafiteAst.Seq (_, l) -> l @ [ t2 ]
437 GrafiteAst.Seq (loc, ts)
440 [ tac = SELF; SYMBOL ";";
441 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
442 (GrafiteAst.Then (loc, tac, tacs))
445 [ IDENT "do"; count = int; tac = SELF ->
446 GrafiteAst.Do (loc, count, tac)
447 | IDENT "repeat"; tac = SELF -> GrafiteAst.Repeat (loc, tac)
451 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
452 GrafiteAst.First (loc, tacs)
453 | IDENT "try"; tac = SELF -> GrafiteAst.Try (loc, tac)
455 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
456 GrafiteAst.Solve (loc, tacs)
457 | IDENT "progress"; tac = SELF -> GrafiteAst.Progress (loc, tac)
458 | LPAREN; tac = SELF; RPAREN -> tac
459 | tac = tactic -> tac
462 punctuation_tactical:
464 [ SYMBOL "[" -> GrafiteAst.Branch loc
465 | SYMBOL "|" -> GrafiteAst.Shift loc
466 | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> GrafiteAst.Pos (loc, i)
467 | SYMBOL "*"; SYMBOL ":" -> GrafiteAst.Wildcard loc
468 | SYMBOL "]" -> GrafiteAst.Merge loc
469 | SYMBOL ";" -> GrafiteAst.Semicolon loc
470 | SYMBOL "." -> GrafiteAst.Dot loc
473 non_punctuation_tactical:
475 [ IDENT "focus"; goals = LIST1 int -> GrafiteAst.Focus (loc, goals)
476 | IDENT "unfocus" -> GrafiteAst.Unfocus loc
477 | IDENT "skip" -> GrafiteAst.Skip loc
481 [ [ IDENT "ntheorem" ] -> `Theorem
485 [ [ IDENT "definition" ] -> `Definition
486 | [ IDENT "fact" ] -> `Fact
487 | [ IDENT "lemma" ] -> `Lemma
488 | [ IDENT "remark" ] -> `Remark
489 | [ IDENT "theorem" ] -> `Theorem
493 [ attr = theorem_flavour -> attr
494 | [ IDENT "axiom" ] -> `Axiom
495 | [ IDENT "mutual" ] -> `MutualDefinition
500 params = LIST0 protected_binder_vars;
501 SYMBOL ":"; fst_typ = term; SYMBOL <:unicode<def>>; OPT SYMBOL "|";
502 fst_constructors = LIST0 constructor SEP SYMBOL "|";
505 name = IDENT; SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>;
506 OPT SYMBOL "|"; constructors = LIST0 constructor SEP SYMBOL "|" ->
507 (name, true, typ, constructors) ] SEP "with" -> types
511 (fun (names, typ) acc ->
512 (List.map (fun name -> (name, typ)) names) @ acc)
515 let fst_ind_type = (fst_name, true, fst_typ, fst_constructors) in
516 let tl_ind_types = match tl with None -> [] | Some types -> types in
517 let ind_types = fst_ind_type :: tl_ind_types in
523 params = LIST0 protected_binder_vars;
524 SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>; SYMBOL "{" ;
528 SYMBOL ":" -> false,0
529 | SYMBOL ":"; SYMBOL ">" -> true,0
530 | SYMBOL ":"; arity = int ; SYMBOL ">" -> true,arity
533 let b,n = coercion in
535 ] SEP SYMBOL ";"; SYMBOL "}" ->
538 (fun (names, typ) acc ->
539 (List.map (fun name -> (name, typ)) names) @ acc)
542 (params,name,typ,fields)
546 [ [ IDENT "check" ]; t = term ->
547 GrafiteAst.Check (loc, t)
548 | [ IDENT "eval" ]; kind = reduction_kind; "on"; t = tactic_term ->
549 GrafiteAst.Eval (loc, kind, t)
551 style = OPT [ IDENT "procedural"; depth = OPT int -> depth ];
552 suri = QSTRING; prefix = OPT QSTRING;
553 flavour = OPT [ "as"; attr = inline_flavour -> attr ] ->
554 let style = match style with
555 | None -> GrafiteAst.Declarative
556 | Some depth -> GrafiteAst.Procedural depth
558 let prefix = match prefix with None -> "" | Some prefix -> prefix in
559 GrafiteAst.Inline (loc,style,suri,prefix, flavour)
560 | [ IDENT "hint" ]; rew = OPT (IDENT "rewrite") ->
561 if rew = None then GrafiteAst.Hint (loc, false) else GrafiteAst.Hint (loc,true)
562 | IDENT "auto"; params = auto_params ->
563 GrafiteAst.AutoInteractive (loc,params)
564 | [ IDENT "whelp"; "match" ] ; t = term ->
565 GrafiteAst.WMatch (loc,t)
566 | [ IDENT "whelp"; IDENT "instance" ] ; t = term ->
567 GrafiteAst.WInstance (loc,t)
568 | [ IDENT "whelp"; IDENT "locate" ] ; id = QSTRING ->
569 GrafiteAst.WLocate (loc,id)
570 | [ IDENT "whelp"; IDENT "elim" ] ; t = term ->
571 GrafiteAst.WElim (loc, t)
572 | [ IDENT "whelp"; IDENT "hint" ] ; t = term ->
573 GrafiteAst.WHint (loc,t)
577 [ IDENT "id"; id = QSTRING; SYMBOL "="; uri = QSTRING ->
578 let alpha = "[a-zA-Z]" in
579 let num = "[0-9]+" in
580 let ident_cont = "\\("^alpha^"\\|"^num^"\\|_\\|\\\\\\)" in
581 let decoration = "\\'" in
582 let ident = "\\("^alpha^ident_cont^"*"^decoration^"*\\|_"^ident_cont^"+"^decoration^"*\\)" in
583 let rex = Str.regexp ("^"^ident^"$") in
584 if Str.string_match rex id 0 then
585 if (try ignore (UriManager.uri_of_string uri); true
586 with UriManager.IllFormedUri _ -> false)
588 LexiconAst.Ident_alias (id, uri)
591 (HExtlib.Localized (loc, CicNotationParser.Parse_error (Printf.sprintf "Not a valid uri: %s" uri)))
593 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error (
594 Printf.sprintf "Not a valid identifier: %s" id)))
595 | IDENT "symbol"; symbol = QSTRING;
596 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
597 SYMBOL "="; dsc = QSTRING ->
599 match instance with Some i -> i | None -> 0
601 LexiconAst.Symbol_alias (symbol, instance, dsc)
603 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
604 SYMBOL "="; dsc = QSTRING ->
606 match instance with Some i -> i | None -> 0
608 LexiconAst.Number_alias (instance, dsc)
612 [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
614 Ast.IdentArg (List.length l, id)
618 [ IDENT "left"; IDENT "associative" -> Gramext.LeftA
619 | IDENT "right"; IDENT "associative" -> Gramext.RightA
620 | IDENT "non"; IDENT "associative" -> Gramext.NonA
624 [ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
627 [ dir = OPT direction; s = QSTRING;
628 assoc = OPT associativity; prec = precedence;
631 [ blob = UNPARSED_AST ->
632 add_raw_attribute ~text:(Printf.sprintf "@{%s}" blob)
633 (CicNotationParser.parse_level2_ast
634 (Ulexing.from_utf8_string blob))
635 | blob = UNPARSED_META ->
636 add_raw_attribute ~text:(Printf.sprintf "${%s}" blob)
637 (CicNotationParser.parse_level2_meta
638 (Ulexing.from_utf8_string blob))
642 | None -> default_associativity
643 | Some assoc -> assoc
646 add_raw_attribute ~text:s
647 (CicNotationParser.parse_level1_pattern prec
648 (Ulexing.from_utf8_string s))
650 (dir, p1, assoc, prec, p2)
654 [ u = URI -> Ast.UriPattern (UriManager.uri_of_string u)
655 | id = IDENT -> Ast.VarPattern id
656 | SYMBOL "_" -> Ast.ImplicitPattern
657 | LPAREN; terms = LIST1 SELF; RPAREN ->
661 | terms -> Ast.ApplPattern terms)
665 [ s = CSYMBOL; args = LIST0 argument; SYMBOL "="; t = level3_term ->
671 IDENT "include" ; path = QSTRING ->
672 loc,path,LexiconAst.WithPreferences
673 | IDENT "include'" ; path = QSTRING ->
674 loc,path,LexiconAst.WithoutPreferences
678 IDENT "set"; n = QSTRING; v = QSTRING ->
679 GrafiteAst.Set (loc, n, v)
680 | IDENT "drop" -> GrafiteAst.Drop loc
681 | IDENT "print"; s = IDENT -> GrafiteAst.Print (loc,s)
682 | IDENT "qed" -> GrafiteAst.Qed loc
683 | IDENT "variant" ; name = IDENT; SYMBOL ":";
684 typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
687 (`Variant,name,typ,Some (Ast.Ident (newname, None))))
688 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
689 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
690 GrafiteAst.NObj (loc, Ast.Theorem (nflavour, name, typ, body))
691 | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
692 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
693 GrafiteAst.Obj (loc, Ast.Theorem (flavour, name, typ, body))
694 | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
697 Ast.Theorem (flavour, name, Ast.Implicit, Some body))
698 | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
699 GrafiteAst.Obj (loc, Ast.Theorem (`Axiom, name, typ, None))
700 | LETCOREC ; defs = let_defs ->
701 mk_rec_corec `CoInductive defs loc
702 | LETREC ; defs = let_defs ->
703 mk_rec_corec `Inductive defs loc
704 | IDENT "inductive"; spec = inductive_spec ->
705 let (params, ind_types) = spec in
706 GrafiteAst.Obj (loc, Ast.Inductive (params, ind_types))
707 | IDENT "coinductive"; spec = inductive_spec ->
708 let (params, ind_types) = spec in
709 let ind_types = (* set inductive flags to false (coinductive) *)
710 List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
713 GrafiteAst.Obj (loc, Ast.Inductive (params, ind_types))
715 t = [ u = URI -> Ast.Uri (u,None) | t = tactic_term ; OPT "with" -> t ] ;
716 arity = OPT int ; saturations = OPT int;
717 composites = OPT (IDENT "nocomposites") ->
718 let arity = match arity with None -> 0 | Some x -> x in
719 let saturations = match saturations with None -> 0 | Some x -> x in
720 let composites = match composites with None -> true | Some _ -> false in
722 (loc, t, composites, arity, saturations)
723 | IDENT "prefer" ; IDENT "coercion"; t = tactic_term ->
724 GrafiteAst.PreferCoercion (loc, t)
725 | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
726 GrafiteAst.UnificationHint (loc, t, n)
727 | IDENT "record" ; (params,name,ty,fields) = record_spec ->
728 GrafiteAst.Obj (loc, Ast.Record (params,name,ty,fields))
729 | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
730 let uris = List.map UriManager.uri_of_string uris in
731 GrafiteAst.Default (loc,what,uris)
732 | IDENT "relation" ; aeq = tactic_term ; "on" ; a = tactic_term ;
733 refl = OPT [ IDENT "reflexivity" ; IDENT "proved" ; IDENT "by" ;
734 refl = tactic_term -> refl ] ;
735 sym = OPT [ IDENT "symmetry" ; IDENT "proved" ; IDENT "by" ;
736 sym = tactic_term -> sym ] ;
737 trans = OPT [ IDENT "transitivity" ; IDENT "proved" ; IDENT "by" ;
738 trans = tactic_term -> trans ] ;
740 GrafiteAst.Relation (loc,id,a,aeq,refl,sym,trans)
743 IDENT "alias" ; spec = alias_spec ->
744 LexiconAst.Alias (loc, spec)
745 | IDENT "notation"; (dir, l1, assoc, prec, l2) = notation ->
746 LexiconAst.Notation (loc, dir, l1, assoc, prec, l2)
747 | IDENT "interpretation"; id = QSTRING;
748 (symbol, args, l3) = interpretation ->
749 LexiconAst.Interpretation (loc, id, (symbol, args), l3)
752 [ cmd = grafite_command; SYMBOL "." -> GrafiteAst.Command (loc, cmd)
753 | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
754 GrafiteAst.Tactic (loc, Some tac, punct)
755 | punct = punctuation_tactical -> GrafiteAst.Tactic (loc, None, punct)
756 | tac = ntactic; punct = punctuation_tactical ->
757 GrafiteAst.NTactic (loc, tac, punct)
758 | SYMBOL "#" ; SYMBOL "#" ; punct = punctuation_tactical ->
759 GrafiteAst.NTactic (loc, GrafiteAst.NId loc, punct)
760 | tac = non_punctuation_tactical; punct = punctuation_tactical ->
761 GrafiteAst.NonPunctuationTactical (loc, tac, punct)
762 | mac = macro; SYMBOL "." -> GrafiteAst.Macro (loc, mac)
766 [ BEGINCOMMENT ; ex = executable ; ENDCOMMENT ->
767 GrafiteAst.Code (loc, ex)
769 GrafiteAst.Note (loc, str)
774 fun ?(never_include=false) ~include_paths status -> status,LSome(GrafiteAst.Executable (loc,ex))
776 fun ?(never_include=false) ~include_paths status ->
777 status,LSome (GrafiteAst.Comment (loc, com))
778 | (iloc,fname,mode) = include_command ; SYMBOL "." ->
780 fun ?(never_include=false) ~include_paths status ->
781 let _root, buri, fullpath, _rrelpath =
782 Librarian.baseuri_of_script ~include_paths fname
785 if never_include then raise (NoInclusionPerformed fullpath)
786 else LexiconEngine.eval_command status
787 (LexiconAst.Include (iloc,buri,mode,fullpath))
791 (GrafiteAst.Executable
792 (loc,GrafiteAst.Command
793 (loc,GrafiteAst.Include (iloc,buri))))
794 | scom = lexicon_command ; SYMBOL "." ->
795 fun ?(never_include=false) ~include_paths status ->
796 let status = LexiconEngine.eval_command status scom in
798 | EOI -> raise End_of_file
805 let _ = initialize_parser () ;;
807 let exc_located_wrapper f =
811 | Stdpp.Exc_located (_, End_of_file) -> raise End_of_file
812 | Stdpp.Exc_located (floc, Stream.Error msg) ->
813 raise (HExtlib.Localized (floc,CicNotationParser.Parse_error msg))
814 | Stdpp.Exc_located (floc, HExtlib.Localized(_,exn)) ->
816 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
817 | Stdpp.Exc_located (floc, exn) ->
819 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
821 let parse_statement lexbuf =
823 (fun () -> (Grammar.Entry.parse !grafite_parser.statement (Obj.magic lexbuf)))
825 let statement () = !grafite_parser.statement
827 let history = ref [] ;;
831 history := !grafite_parser :: !history;
832 grafite_parser := initial_parser ();
841 grafite_parser := gp;
845 (* vim:set foldmethod=marker: *)