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 "nchange"; what = pattern_spec; "with"; with_what = tactic_term ->
186 GrafiteAst.NChange (loc, what, with_what)
187 | IDENT "nelim"; what = tactic_term ; where = pattern_spec ->
188 GrafiteAst.NElim (loc, what, where)
192 [ IDENT "absurd"; t = tactic_term ->
193 GrafiteAst.Absurd (loc, t)
194 | IDENT "apply"; IDENT "rule"; t = tactic_term ->
195 GrafiteAst.ApplyRule (loc, t)
196 | IDENT "apply"; t = tactic_term ->
197 GrafiteAst.Apply (loc, t)
198 | IDENT "applyP"; t = tactic_term ->
199 GrafiteAst.ApplyP (loc, t)
200 | IDENT "applyS"; t = tactic_term ; params = auto_params ->
201 GrafiteAst.ApplyS (loc, t, params)
202 | IDENT "assumption" ->
203 GrafiteAst.Assumption loc
204 | IDENT "autobatch"; params = auto_params ->
205 GrafiteAst.AutoBatch (loc,params)
206 | IDENT "cases"; what = tactic_term;
207 pattern = OPT pattern_spec;
208 specs = intros_spec ->
209 let pattern = match pattern with
210 | None -> None, [], Some Ast.UserInput
211 | Some pattern -> pattern
213 GrafiteAst.Cases (loc, what, pattern, specs)
214 | IDENT "clear"; ids = LIST1 IDENT ->
215 GrafiteAst.Clear (loc, ids)
216 | IDENT "clearbody"; id = IDENT ->
217 GrafiteAst.ClearBody (loc,id)
218 | IDENT "change"; what = pattern_spec; "with"; t = tactic_term ->
219 GrafiteAst.Change (loc, what, t)
220 | IDENT "compose"; times = OPT int; t1 = tactic_term; t2 =
221 OPT [ "with"; t = tactic_term -> t ]; specs = intros_spec ->
222 let times = match times with None -> 1 | Some i -> i in
223 GrafiteAst.Compose (loc, t1, t2, times, specs)
224 | IDENT "constructor"; n = int ->
225 GrafiteAst.Constructor (loc, n)
226 | IDENT "contradiction" ->
227 GrafiteAst.Contradiction loc
228 | IDENT "cut"; t = tactic_term; ident = OPT [ "as"; id = IDENT -> id] ->
229 GrafiteAst.Cut (loc, ident, t)
230 | IDENT "decompose"; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
231 let idents = match idents with None -> [] | Some idents -> idents in
232 GrafiteAst.Decompose (loc, idents)
233 | IDENT "demodulate"; p = auto_params -> GrafiteAst.Demodulate (loc, p)
234 | IDENT "destruct"; xts = OPT [ ts = tactic_term_list1 -> ts ] ->
235 GrafiteAst.Destruct (loc, xts)
236 | IDENT "elim"; what = tactic_term; using = using;
237 pattern = OPT pattern_spec;
238 ispecs = intros_spec ->
239 let pattern = match pattern with
240 | None -> None, [], Some Ast.UserInput
241 | Some pattern -> pattern
243 GrafiteAst.Elim (loc, what, using, pattern, ispecs)
244 | IDENT "elimType"; what = tactic_term; using = using;
245 (num, idents) = intros_spec ->
246 GrafiteAst.ElimType (loc, what, using, (num, idents))
247 | IDENT "exact"; t = tactic_term ->
248 GrafiteAst.Exact (loc, t)
250 GrafiteAst.Exists loc
251 | IDENT "fail" -> GrafiteAst.Fail loc
252 | IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
255 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error
256 ("the pattern cannot specify the term to replace, only its"
257 ^ " paths in the hypotheses and in the conclusion")))
259 GrafiteAst.Fold (loc, kind, t, p)
261 GrafiteAst.Fourier loc
262 | IDENT "fwd"; hyp = IDENT; idents = OPT [ "as"; idents = LIST1 new_name -> idents ] ->
263 let idents = match idents with None -> [] | Some idents -> idents in
264 GrafiteAst.FwdSimpl (loc, hyp, idents)
265 | IDENT "generalize"; p=pattern_spec; id = OPT ["as" ; id = IDENT -> id] ->
266 GrafiteAst.Generalize (loc,p,id)
267 | IDENT "id" -> GrafiteAst.IdTac loc
268 | IDENT "intro"; ident = OPT IDENT ->
269 let idents = match ident with None -> [] | Some id -> [Some id] in
270 GrafiteAst.Intros (loc, (Some 1, idents))
271 | IDENT "intros"; specs = intros_spec ->
272 GrafiteAst.Intros (loc, specs)
273 | IDENT "inversion"; t = tactic_term ->
274 GrafiteAst.Inversion (loc, t)
276 linear = OPT [ IDENT "linear" ];
277 depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
279 to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
280 ident = OPT [ "as" ; ident = IDENT -> ident ] ->
281 let linear = match linear with None -> false | Some _ -> true in
282 let to_what = match to_what with None -> [] | Some to_what -> to_what in
283 GrafiteAst.LApply (loc, linear, depth, to_what, what, ident)
284 | IDENT "left" -> GrafiteAst.Left loc
285 | IDENT "letin"; where = IDENT ; SYMBOL <:unicode<def>> ; t = tactic_term ->
286 GrafiteAst.LetIn (loc, t, where)
287 | kind = reduction_kind; p = pattern_spec ->
288 GrafiteAst.Reduce (loc, kind, p)
289 | IDENT "reflexivity" ->
290 GrafiteAst.Reflexivity loc
291 | IDENT "replace"; p = pattern_spec; "with"; t = tactic_term ->
292 GrafiteAst.Replace (loc, p, t)
293 | IDENT "rewrite" ; d = direction; t = tactic_term ; p = pattern_spec;
294 xnames = OPT [ "as"; n = ident_list0 -> n ] ->
298 (HExtlib.Localized (loc,
299 (CicNotationParser.Parse_error
300 "the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion")))
302 let n = match xnames with None -> [] | Some names -> names in
303 GrafiteAst.Rewrite (loc, d, t, p, n)
310 | IDENT "symmetry" ->
311 GrafiteAst.Symmetry loc
312 | IDENT "transitivity"; t = tactic_term ->
313 GrafiteAst.Transitivity (loc, t)
314 (* Produzioni Aggiunte *)
315 | IDENT "assume" ; id = IDENT ; SYMBOL ":" ; t = tactic_term ->
316 GrafiteAst.Assume (loc, id, t)
317 | IDENT "suppose" ; t = tactic_term ; LPAREN ; id = IDENT ; RPAREN ;
318 t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ;
319 t' = tactic_term -> t']->
320 GrafiteAst.Suppose (loc, t, id, t1)
321 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
322 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
323 id2 = IDENT ; RPAREN ->
324 GrafiteAst.ExistsElim (loc, `Auto ([],[]), id1, t1, id2, t2)
326 [ IDENT "using"; t=tactic_term -> `Term t
327 | params = auto_params -> `Auto params] ;
328 cont=by_continuation ->
330 BYC_done -> GrafiteAst.Bydone (loc, just)
331 | BYC_weproved (ty,id,t1) ->
332 GrafiteAst.By_just_we_proved(loc, just, ty, id, t1)
333 | BYC_letsuchthat (id1,t1,id2,t2) ->
334 GrafiteAst.ExistsElim (loc, just, id1, t1, id2, t2)
335 | BYC_wehaveand (id1,t1,id2,t2) ->
336 GrafiteAst.AndElim (loc, just, id1, t1, id2, t2))
337 | 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']->
338 GrafiteAst.We_need_to_prove (loc, t, id, t1)
339 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "cases" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
340 GrafiteAst.We_proceed_by_cases_on (loc, t, t1)
341 | IDENT "we" ; IDENT "proceed" ; IDENT "by" ; IDENT "induction" ; "on" ; t=tactic_term ; "to" ; IDENT "prove" ; t1=tactic_term ->
342 GrafiteAst.We_proceed_by_induction_on (loc, t, t1)
343 | IDENT "by" ; IDENT "induction" ; IDENT "hypothesis" ; IDENT "we" ; IDENT "know" ; t=tactic_term ; LPAREN ; id = IDENT ; RPAREN ->
344 GrafiteAst.Byinduction(loc, t, id)
345 | IDENT "the" ; IDENT "thesis" ; IDENT "becomes" ; t=tactic_term ->
346 GrafiteAst.Thesisbecomes(loc, t)
347 | IDENT "case" ; id = IDENT ; params=LIST0[LPAREN ; i=IDENT ;
348 SYMBOL":" ; t=tactic_term ; RPAREN -> i,t] ->
349 GrafiteAst.Case(loc,id,params)
350 (* DO NOT FACTORIZE with the two following, camlp5 sucks*)
352 termine = tactic_term;
356 [ IDENT "using"; t=tactic_term -> `Term t
357 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
358 | IDENT "proof" -> `Proof
359 | params = auto_params -> `Auto params];
360 cont = rewriting_step_continuation ->
361 GrafiteAst.RewritingStep(loc, Some (None,termine), t1, t2, cont)
362 | IDENT "obtain" ; name = IDENT;
363 termine = tactic_term;
367 [ IDENT "using"; t=tactic_term -> `Term t
368 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
369 | IDENT "proof" -> `Proof
370 | params = auto_params -> `Auto params];
371 cont = rewriting_step_continuation ->
372 GrafiteAst.RewritingStep(loc, Some (Some name,termine), t1, t2, cont)
376 [ IDENT "using"; t=tactic_term -> `Term t
377 | IDENT "using"; IDENT "once"; term=tactic_term -> `SolveWith term
378 | IDENT "proof" -> `Proof
379 | params = auto_params -> `Auto params];
380 cont = rewriting_step_continuation ->
381 GrafiteAst.RewritingStep(loc, None, t1, t2, cont)
385 [ IDENT "paramodulation"
397 i = auto_fixed_param -> i,""
398 | i = auto_fixed_param ; SYMBOL "="; v = [ v = int ->
399 string_of_int v | v = IDENT -> v ] -> i,v ];
400 tl = OPT [ IDENT "by"; tl = tactic_term_list1 -> tl] ->
401 (match tl with Some l -> l | None -> []),
406 [ 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)
407 | WEPROVED; ty = tactic_term ; t1 = OPT [IDENT "that" ; IDENT "is" ; IDENT "equivalent" ; "to" ; t2 = tactic_term -> t2] ;
408 "done" -> BYC_weproved (ty,None,t1)
410 | "let" ; id1 = IDENT ; SYMBOL ":" ; t1 = tactic_term ;
411 IDENT "such" ; IDENT "that" ; t2=tactic_term ; LPAREN ;
412 id2 = IDENT ; RPAREN -> BYC_letsuchthat (id1,t1,id2,t2)
413 | WEHAVE; t1=tactic_term ; LPAREN ; id1=IDENT ; RPAREN ;"and" ; t2=tactic_term ; LPAREN ; id2=IDENT ; RPAREN ->
414 BYC_wehaveand (id1,t1,id2,t2)
417 rewriting_step_continuation : [
424 [ t1 = SELF; SYMBOL ";"; t2 = SELF ->
427 | GrafiteAst.Seq (_, l) -> l @ [ t2 ]
430 GrafiteAst.Seq (loc, ts)
433 [ tac = SELF; SYMBOL ";";
434 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
435 (GrafiteAst.Then (loc, tac, tacs))
438 [ IDENT "do"; count = int; tac = SELF ->
439 GrafiteAst.Do (loc, count, tac)
440 | IDENT "repeat"; tac = SELF -> GrafiteAst.Repeat (loc, tac)
444 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
445 GrafiteAst.First (loc, tacs)
446 | IDENT "try"; tac = SELF -> GrafiteAst.Try (loc, tac)
448 SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
449 GrafiteAst.Solve (loc, tacs)
450 | IDENT "progress"; tac = SELF -> GrafiteAst.Progress (loc, tac)
451 | LPAREN; tac = SELF; RPAREN -> tac
452 | tac = tactic -> tac
455 punctuation_tactical:
457 [ SYMBOL "[" -> GrafiteAst.Branch loc
458 | SYMBOL "|" -> GrafiteAst.Shift loc
459 | i = LIST1 int SEP SYMBOL ","; SYMBOL ":" -> GrafiteAst.Pos (loc, i)
460 | SYMBOL "*"; SYMBOL ":" -> GrafiteAst.Wildcard loc
461 | SYMBOL "]" -> GrafiteAst.Merge loc
462 | SYMBOL ";" -> GrafiteAst.Semicolon loc
463 | SYMBOL "." -> GrafiteAst.Dot loc
466 non_punctuation_tactical:
468 [ IDENT "focus"; goals = LIST1 int -> GrafiteAst.Focus (loc, goals)
469 | IDENT "unfocus" -> GrafiteAst.Unfocus loc
470 | IDENT "skip" -> GrafiteAst.Skip loc
474 [ [ IDENT "ntheorem" ] -> `Theorem
478 [ [ IDENT "definition" ] -> `Definition
479 | [ IDENT "fact" ] -> `Fact
480 | [ IDENT "lemma" ] -> `Lemma
481 | [ IDENT "remark" ] -> `Remark
482 | [ IDENT "theorem" ] -> `Theorem
486 [ attr = theorem_flavour -> attr
487 | [ IDENT "axiom" ] -> `Axiom
488 | [ IDENT "mutual" ] -> `MutualDefinition
493 params = LIST0 protected_binder_vars;
494 SYMBOL ":"; fst_typ = term; SYMBOL <:unicode<def>>; OPT SYMBOL "|";
495 fst_constructors = LIST0 constructor SEP SYMBOL "|";
498 name = IDENT; SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>;
499 OPT SYMBOL "|"; constructors = LIST0 constructor SEP SYMBOL "|" ->
500 (name, true, typ, constructors) ] SEP "with" -> types
504 (fun (names, typ) acc ->
505 (List.map (fun name -> (name, typ)) names) @ acc)
508 let fst_ind_type = (fst_name, true, fst_typ, fst_constructors) in
509 let tl_ind_types = match tl with None -> [] | Some types -> types in
510 let ind_types = fst_ind_type :: tl_ind_types in
516 params = LIST0 protected_binder_vars;
517 SYMBOL ":"; typ = term; SYMBOL <:unicode<def>>; SYMBOL "{" ;
521 SYMBOL ":" -> false,0
522 | SYMBOL ":"; SYMBOL ">" -> true,0
523 | SYMBOL ":"; arity = int ; SYMBOL ">" -> true,arity
526 let b,n = coercion in
528 ] SEP SYMBOL ";"; SYMBOL "}" ->
531 (fun (names, typ) acc ->
532 (List.map (fun name -> (name, typ)) names) @ acc)
535 (params,name,typ,fields)
539 [ [ IDENT "check" ]; t = term ->
540 GrafiteAst.Check (loc, t)
541 | [ IDENT "eval" ]; kind = reduction_kind; "on"; t = tactic_term ->
542 GrafiteAst.Eval (loc, kind, t)
544 style = OPT [ IDENT "procedural"; depth = OPT int -> depth ];
545 suri = QSTRING; prefix = OPT QSTRING;
546 flavour = OPT [ "as"; attr = inline_flavour -> attr ] ->
547 let style = match style with
548 | None -> GrafiteAst.Declarative
549 | Some depth -> GrafiteAst.Procedural depth
551 let prefix = match prefix with None -> "" | Some prefix -> prefix in
552 GrafiteAst.Inline (loc,style,suri,prefix, flavour)
553 | [ IDENT "hint" ]; rew = OPT (IDENT "rewrite") ->
554 if rew = None then GrafiteAst.Hint (loc, false) else GrafiteAst.Hint (loc,true)
555 | IDENT "auto"; params = auto_params ->
556 GrafiteAst.AutoInteractive (loc,params)
557 | [ IDENT "whelp"; "match" ] ; t = term ->
558 GrafiteAst.WMatch (loc,t)
559 | [ IDENT "whelp"; IDENT "instance" ] ; t = term ->
560 GrafiteAst.WInstance (loc,t)
561 | [ IDENT "whelp"; IDENT "locate" ] ; id = QSTRING ->
562 GrafiteAst.WLocate (loc,id)
563 | [ IDENT "whelp"; IDENT "elim" ] ; t = term ->
564 GrafiteAst.WElim (loc, t)
565 | [ IDENT "whelp"; IDENT "hint" ] ; t = term ->
566 GrafiteAst.WHint (loc,t)
570 [ IDENT "id"; id = QSTRING; SYMBOL "="; uri = QSTRING ->
571 let alpha = "[a-zA-Z]" in
572 let num = "[0-9]+" in
573 let ident_cont = "\\("^alpha^"\\|"^num^"\\|_\\|\\\\\\)" in
574 let decoration = "\\'" in
575 let ident = "\\("^alpha^ident_cont^"*"^decoration^"*\\|_"^ident_cont^"+"^decoration^"*\\)" in
576 let rex = Str.regexp ("^"^ident^"$") in
577 if Str.string_match rex id 0 then
578 if (try ignore (UriManager.uri_of_string uri); true
579 with UriManager.IllFormedUri _ -> false)
581 LexiconAst.Ident_alias (id, uri)
584 (HExtlib.Localized (loc, CicNotationParser.Parse_error (Printf.sprintf "Not a valid uri: %s" uri)))
586 raise (HExtlib.Localized (loc, CicNotationParser.Parse_error (
587 Printf.sprintf "Not a valid identifier: %s" id)))
588 | IDENT "symbol"; symbol = QSTRING;
589 instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
590 SYMBOL "="; dsc = QSTRING ->
592 match instance with Some i -> i | None -> 0
594 LexiconAst.Symbol_alias (symbol, instance, dsc)
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.Number_alias (instance, dsc)
605 [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
607 Ast.IdentArg (List.length l, id)
611 [ IDENT "left"; IDENT "associative" -> Gramext.LeftA
612 | IDENT "right"; IDENT "associative" -> Gramext.RightA
613 | IDENT "non"; IDENT "associative" -> Gramext.NonA
617 [ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
620 [ dir = OPT direction; s = QSTRING;
621 assoc = OPT associativity; prec = precedence;
624 [ blob = UNPARSED_AST ->
625 add_raw_attribute ~text:(Printf.sprintf "@{%s}" blob)
626 (CicNotationParser.parse_level2_ast
627 (Ulexing.from_utf8_string blob))
628 | blob = UNPARSED_META ->
629 add_raw_attribute ~text:(Printf.sprintf "${%s}" blob)
630 (CicNotationParser.parse_level2_meta
631 (Ulexing.from_utf8_string blob))
635 | None -> default_associativity
636 | Some assoc -> assoc
639 add_raw_attribute ~text:s
640 (CicNotationParser.parse_level1_pattern prec
641 (Ulexing.from_utf8_string s))
643 (dir, p1, assoc, prec, p2)
647 [ u = URI -> Ast.UriPattern (UriManager.uri_of_string u)
648 | id = IDENT -> Ast.VarPattern id
649 | SYMBOL "_" -> Ast.ImplicitPattern
650 | LPAREN; terms = LIST1 SELF; RPAREN ->
654 | terms -> Ast.ApplPattern terms)
658 [ s = CSYMBOL; args = LIST0 argument; SYMBOL "="; t = level3_term ->
664 IDENT "include" ; path = QSTRING ->
665 loc,path,LexiconAst.WithPreferences
666 | IDENT "include'" ; path = QSTRING ->
667 loc,path,LexiconAst.WithoutPreferences
671 IDENT "set"; n = QSTRING; v = QSTRING ->
672 GrafiteAst.Set (loc, n, v)
673 | IDENT "drop" -> GrafiteAst.Drop loc
674 | IDENT "print"; s = IDENT -> GrafiteAst.Print (loc,s)
675 | IDENT "qed" -> GrafiteAst.Qed loc
676 | IDENT "variant" ; name = IDENT; SYMBOL ":";
677 typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
680 (`Variant,name,typ,Some (Ast.Ident (newname, None))))
681 | nflavour = ntheorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
682 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
683 GrafiteAst.NObj (loc, Ast.Theorem (nflavour, name, typ, body))
684 | flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
685 body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
686 GrafiteAst.Obj (loc, Ast.Theorem (flavour, name, typ, body))
687 | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
690 Ast.Theorem (flavour, name, Ast.Implicit, Some body))
691 | IDENT "axiom"; name = IDENT; SYMBOL ":"; typ = term ->
692 GrafiteAst.Obj (loc, Ast.Theorem (`Axiom, name, typ, None))
693 | LETCOREC ; defs = let_defs ->
694 mk_rec_corec `CoInductive defs loc
695 | LETREC ; defs = let_defs ->
696 mk_rec_corec `Inductive defs loc
697 | IDENT "inductive"; spec = inductive_spec ->
698 let (params, ind_types) = spec in
699 GrafiteAst.Obj (loc, Ast.Inductive (params, ind_types))
700 | IDENT "coinductive"; spec = inductive_spec ->
701 let (params, ind_types) = spec in
702 let ind_types = (* set inductive flags to false (coinductive) *)
703 List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
706 GrafiteAst.Obj (loc, Ast.Inductive (params, ind_types))
708 t = [ u = URI -> Ast.Uri (u,None) | t = tactic_term ; OPT "with" -> t ] ;
709 arity = OPT int ; saturations = OPT int;
710 composites = OPT (IDENT "nocomposites") ->
711 let arity = match arity with None -> 0 | Some x -> x in
712 let saturations = match saturations with None -> 0 | Some x -> x in
713 let composites = match composites with None -> true | Some _ -> false in
715 (loc, t, composites, arity, saturations)
716 | IDENT "prefer" ; IDENT "coercion"; t = tactic_term ->
717 GrafiteAst.PreferCoercion (loc, t)
718 | IDENT "unification"; IDENT "hint"; n = int; t = tactic_term ->
719 GrafiteAst.UnificationHint (loc, t, n)
720 | IDENT "record" ; (params,name,ty,fields) = record_spec ->
721 GrafiteAst.Obj (loc, Ast.Record (params,name,ty,fields))
722 | IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
723 let uris = List.map UriManager.uri_of_string uris in
724 GrafiteAst.Default (loc,what,uris)
725 | IDENT "relation" ; aeq = tactic_term ; "on" ; a = tactic_term ;
726 refl = OPT [ IDENT "reflexivity" ; IDENT "proved" ; IDENT "by" ;
727 refl = tactic_term -> refl ] ;
728 sym = OPT [ IDENT "symmetry" ; IDENT "proved" ; IDENT "by" ;
729 sym = tactic_term -> sym ] ;
730 trans = OPT [ IDENT "transitivity" ; IDENT "proved" ; IDENT "by" ;
731 trans = tactic_term -> trans ] ;
733 GrafiteAst.Relation (loc,id,a,aeq,refl,sym,trans)
736 IDENT "alias" ; spec = alias_spec ->
737 LexiconAst.Alias (loc, spec)
738 | IDENT "notation"; (dir, l1, assoc, prec, l2) = notation ->
739 LexiconAst.Notation (loc, dir, l1, assoc, prec, l2)
740 | IDENT "interpretation"; id = QSTRING;
741 (symbol, args, l3) = interpretation ->
742 LexiconAst.Interpretation (loc, id, (symbol, args), l3)
745 [ cmd = grafite_command; SYMBOL "." -> GrafiteAst.Command (loc, cmd)
746 | tac = atomic_tactical LEVEL "loops"; punct = punctuation_tactical ->
747 GrafiteAst.Tactic (loc, Some tac, punct)
748 | punct = punctuation_tactical -> GrafiteAst.Tactic (loc, None, punct)
749 | tac = ntactic; punct = punctuation_tactical ->
750 GrafiteAst.NTactic (loc, tac, punct)
751 | tac = non_punctuation_tactical; punct = punctuation_tactical ->
752 GrafiteAst.NonPunctuationTactical (loc, tac, punct)
753 | mac = macro; SYMBOL "." -> GrafiteAst.Macro (loc, mac)
757 [ BEGINCOMMENT ; ex = executable ; ENDCOMMENT ->
758 GrafiteAst.Code (loc, ex)
760 GrafiteAst.Note (loc, str)
765 fun ?(never_include=false) ~include_paths status -> status,LSome(GrafiteAst.Executable (loc,ex))
767 fun ?(never_include=false) ~include_paths status ->
768 status,LSome (GrafiteAst.Comment (loc, com))
769 | (iloc,fname,mode) = include_command ; SYMBOL "." ->
771 fun ?(never_include=false) ~include_paths status ->
772 let _root, buri, fullpath, _rrelpath =
773 Librarian.baseuri_of_script ~include_paths fname
776 if never_include then raise (NoInclusionPerformed fullpath)
777 else LexiconEngine.eval_command status
778 (LexiconAst.Include (iloc,buri,mode,fullpath))
782 (GrafiteAst.Executable
783 (loc,GrafiteAst.Command
784 (loc,GrafiteAst.Include (iloc,buri))))
785 | scom = lexicon_command ; SYMBOL "." ->
786 fun ?(never_include=false) ~include_paths status ->
787 let status = LexiconEngine.eval_command status scom in
789 | EOI -> raise End_of_file
796 let _ = initialize_parser () ;;
798 let exc_located_wrapper f =
802 | Stdpp.Exc_located (_, End_of_file) -> raise End_of_file
803 | Stdpp.Exc_located (floc, Stream.Error msg) ->
804 raise (HExtlib.Localized (floc,CicNotationParser.Parse_error msg))
805 | Stdpp.Exc_located (floc, HExtlib.Localized(_,exn)) ->
807 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
808 | Stdpp.Exc_located (floc, exn) ->
810 (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
812 let parse_statement lexbuf =
814 (fun () -> (Grammar.Entry.parse !grafite_parser.statement (Obj.magic lexbuf)))
816 let statement () = !grafite_parser.statement
818 let history = ref [] ;;
822 history := !grafite_parser :: !history;
823 grafite_parser := initial_parser ();
832 grafite_parser := gp;
836 (* vim:set foldmethod=marker: *)