]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/ocaml/cic_disambiguation/cicTextualParser2.ml
merged changes from the svn fork by me and Enrico
[helm.git] / helm / ocaml / cic_disambiguation / cicTextualParser2.ml
index d32302a131e11c2d67ce292c4744ec6e18d995c1..d7096ae79deeeb40e4fbd7e9e9949b76956a29c6 100644 (file)
@@ -65,12 +65,12 @@ let tactic = Grammar.Entry.create grammar "tactic"
 let tactical = Grammar.Entry.create grammar "tactical"
 let tactical0 = Grammar.Entry.create grammar "tactical0"
 let command = Grammar.Entry.create grammar "command"
+let alias_spec = Grammar.Entry.create grammar "alias_spec"
+let macro = Grammar.Entry.create grammar "macro"
 let script = Grammar.Entry.create grammar "script"
+let statement = Grammar.Entry.create grammar "statement"
 
 let return_term loc term = CicAst.AttributedTerm (`Loc loc, term)
-let return_tactic loc tactic = TacticAst.LocatedTactic (loc, tactic)
-let return_tactical loc tactical = TacticAst.LocatedTactical (loc, tactical)
-let return_command loc cmd = cmd  (* TODO ZACK FIXME uhm ... why we drop loc? *)
 
 let fail floc msg =
   let (x, y) = CicAst.loc_of_floc floc in
@@ -88,6 +88,12 @@ let int_opt = function
   | None -> None
   | Some lexeme -> Some (int_of_string lexeme)
 
+let int_of_string s =
+  try
+    Pervasives.int_of_string s
+  with Failure _ ->
+    failwith (sprintf "Lexer failure: string_of_int \"%s\" failed" s)
+
   (** the uri of an inductive type (a ".ind" uri) is not meaningful without an
   * xpointer. Still, it's likely that an user who wrote "cic:/blabla/foo.ind"
   * actually meant "cic:/blabla/foo.ind#xpointer(1/1)", i.e. the first inductive
@@ -110,7 +116,7 @@ let mk_binder_ast binder typ vars body =
     vars body
 
 EXTEND
-  GLOBAL: term term0 tactic tactical tactical0 command script;
+  GLOBAL: term term0 statement;
   int: [
     [ num = NUM ->
         try
@@ -318,132 +324,126 @@ EXTEND
     [ PAREN "["; idents = LIST1 IDENT SEP SYMBOL ";"; PAREN "]" -> idents ]
   ];
   reduction_kind: [
-    [ [ IDENT "reduce" | IDENT "Reduce" ] -> `Reduce
-    | [ IDENT "simplify" | IDENT "Simplify" ] -> `Simpl
-    | [ IDENT "whd" | IDENT "Whd" ] -> `Whd ]
+    [ [ IDENT "reduce" ] -> `Reduce
+    | [ IDENT "simplify" ] -> `Simpl
+    | [ IDENT "whd" ] -> `Whd ]
   ];
   tactic: [
-    [ [ IDENT "absurd" | IDENT "Absurd" ]; t = tactic_term ->
-        return_tactic loc (TacticAst.Absurd t)
-    | [ IDENT "apply" | IDENT "Apply" ]; t = tactic_term ->
-        return_tactic loc (TacticAst.Apply t)
-    | [ IDENT "assumption" | IDENT "Assumption" ] ->
-        return_tactic loc TacticAst.Assumption
-    | [ IDENT "auto" | IDENT "Auto" ] -> return_tactic loc TacticAst.Auto
-    | [ IDENT "change" | IDENT "Change" ];
+    [ [ IDENT "absurd" ]; t = tactic_term ->
+        TacticAst.Absurd (loc, t)
+    | [ IDENT "apply" ]; t = tactic_term ->
+        TacticAst.Apply (loc, t)
+    | [ IDENT "assumption" ] ->
+        TacticAst.Assumption loc
+    | [ IDENT "auto" ] -> TacticAst.Auto loc
+    | [ IDENT "change" ];
       t1 = tactic_term; "with"; t2 = tactic_term;
       where = tactic_where ->
-        return_tactic loc (TacticAst.Change (t1, t2, where))
+        TacticAst.Change (loc, t1, t2, where)
     (* TODO Change_pattern *)
-    | [ IDENT "contradiction" | IDENT "Contradiction" ] ->
-        return_tactic loc TacticAst.Contradiction
-    | [ IDENT "cut" | IDENT "Cut" ];
-      t = tactic_term -> return_tactic loc (TacticAst.Cut t)
-    | [ IDENT "decompose" | IDENT "Decompose" ];
+    | [ IDENT "contradiction" ] ->
+        TacticAst.Contradiction loc
+    | [ IDENT "cut" ];
+      t = tactic_term ->
+        TacticAst.Cut (loc, t)
+    | [ IDENT "decompose" ];
       principles = ident_list1; where = IDENT ->
-        return_tactic loc (TacticAst.Decompose (where, principles))
-    | [ IDENT "discriminate" | IDENT "Discriminate" ];
+        TacticAst.Decompose (loc, where, principles)
+    | [ IDENT "discriminate" ];
       hyp = IDENT ->
-        return_tactic loc (TacticAst.Discriminate hyp)
-    | [ IDENT "elimType" | IDENT "ElimType" ]; t = tactic_term ->
-        return_tactic loc (TacticAst.ElimType t)
-    | [ IDENT "elim" | IDENT "Elim" ];
+        TacticAst.Discriminate (loc, hyp)
+    | [ IDENT "elimType" ]; t = tactic_term ->
+        TacticAst.ElimType (loc, t)
+    | [ IDENT "elim" ];
       t1 = tactic_term;
       using = OPT [ "using"; using = tactic_term -> using ] ->
-        return_tactic loc (TacticAst.Elim (t1, using))
-    | [ IDENT "exact" | IDENT "Exact" ]; t = tactic_term ->
-        return_tactic loc (TacticAst.Exact t)
-    | [ IDENT "exists" | IDENT "Exists" ] ->
-        return_tactic loc TacticAst.Exists
-    | [ IDENT "fold" | IDENT "Fold" ];
+        TacticAst.Elim (loc, t1, using)
+    | [ IDENT "exact" ]; t = tactic_term ->
+        TacticAst.Exact (loc, t)
+    | [ IDENT "exists" ] ->
+        TacticAst.Exists loc
+    | [ IDENT "fold" ];
       kind = reduction_kind; t = tactic_term ->
-        return_tactic loc (TacticAst.Fold (kind, t))
-    | [ IDENT "fourier" | IDENT "Fourier" ] ->
-        return_tactic loc TacticAst.Fourier
-    | [ IDENT "hint" | IDENT "Hint" ] -> return_tactic loc TacticAst.Hint
-    | [ IDENT "injection" | IDENT "Injection" ]; ident = IDENT ->
-        return_tactic loc (TacticAst.Injection ident)
-    | [ IDENT "intros" | IDENT "Intros" ];
+        TacticAst.Fold (loc, kind, t)
+    | [ IDENT "fourier" ] ->
+        TacticAst.Fourier loc
+    | IDENT "goal"; n = NUM -> TacticAst.Goal (loc, int_of_string n)
+    | [ IDENT "hint" ] -> TacticAst.Hint loc
+    | [ IDENT "injection" ]; ident = IDENT ->
+        TacticAst.Injection (loc, ident)
+    | [ IDENT "intros" ];
       num = OPT [ num = int -> num ];
       idents = OPT ident_list0 ->
         let idents = match idents with None -> [] | Some idents -> idents in
-        return_tactic loc (TacticAst.Intros (num, idents))
-    | [ IDENT "intro" | IDENT "Intro" ] ->
-        return_tactic loc (TacticAst.Intros (None, []))
-    | [ IDENT "left" | IDENT "Left" ] -> return_tactic loc TacticAst.Left
+        TacticAst.Intros (loc, num, idents)
+    | [ IDENT "intro" ] ->
+        TacticAst.Intros (loc, None, [])
+    | [ IDENT "left" ] -> TacticAst.Left loc
     | [ "let" | "Let" ];
       t = tactic_term; "in"; where = IDENT ->
-        return_tactic loc (TacticAst.LetIn (t, where))
+        TacticAst.LetIn (loc, t, where)
     | kind = reduction_kind;
       pat = OPT [
         "in"; pat = [ IDENT "goal" -> `Goal | IDENT "hyp" -> `Everywhere ] ->
           pat
       ];
       terms = LIST0 term SEP SYMBOL "," ->
-        let tac =
-          (match (pat, terms) with
-          | None, [] -> TacticAst.Reduce (kind, None)
-          | None, terms -> TacticAst.Reduce (kind, Some (terms, `Goal))
-          | Some pat, [] -> TacticAst.Reduce (kind, Some ([], pat))
-          | Some pat, terms -> TacticAst.Reduce (kind, Some (terms, pat)))
-        in
-        return_tactic loc tac
-    | [ IDENT "reflexivity" | IDENT "Reflexivity" ] ->
-        return_tactic loc TacticAst.Reflexivity
-    | [ IDENT "replace" | IDENT "Replace" ];
+        (match (pat, terms) with
+        | None, [] -> TacticAst.Reduce (loc, kind, None)
+        | None, terms -> TacticAst.Reduce (loc, kind, Some (terms, `Goal))
+        | Some pat, [] -> TacticAst.Reduce (loc, kind, Some ([], pat))
+        | Some pat, terms -> TacticAst.Reduce (loc, kind, Some (terms, pat)))
+    | [ IDENT "reflexivity" ] ->
+        TacticAst.Reflexivity loc
+    | [ IDENT "replace" ];
       t1 = tactic_term; "with"; t2 = tactic_term ->
-        return_tactic loc (TacticAst.Replace (t1, t2))
+        TacticAst.Replace (loc, t1, t2)
     (* TODO Rewrite *)
     (* TODO Replace_pattern *)
-    | [ IDENT "right" | IDENT "Right" ] -> return_tactic loc TacticAst.Right
-    | [ IDENT "ring" | IDENT "Ring" ] -> return_tactic loc TacticAst.Ring
-    | [ IDENT "split" | IDENT "Split" ] -> return_tactic loc TacticAst.Split
-    | [ IDENT "symmetry" | IDENT "Symmetry" ] ->
-        return_tactic loc TacticAst.Symmetry
-    | [ IDENT "transitivity" | IDENT "Transitivity" ];
+    | [ IDENT "right" ] -> TacticAst.Right loc
+    | [ IDENT "ring" ] -> TacticAst.Ring loc
+    | [ IDENT "split" ] -> TacticAst.Split loc
+    | [ IDENT "symmetry" ] ->
+        TacticAst.Symmetry loc
+    | [ IDENT "transitivity" ];
       t = tactic_term ->
-        return_tactic loc (TacticAst.Transitivity t)
+        TacticAst.Transitivity (loc, t)
     ]
   ];
-  tactical0: [ [ t = tactical; SYMBOL "." -> return_tactical loc t ] ];
   tactical:
-    [ "command" NONA
-      [ cmd = command -> return_tactical loc (TacticAst.Command cmd) ]
-    | "sequence" LEFTA
-      [ tactics = LIST1 NEXT SEP SYMBOL ";" ->
-          (match tactics with
-          | [tactic] -> tactic
-          | _ -> return_tactical loc (TacticAst.Seq tactics))
+    [ "sequence" LEFTA
+      [ tacticals = LIST1 NEXT SEP SYMBOL ";" ->
+          TacticAst.Seq (loc, tacticals)
       ]
     | "then" NONA
       [ tac = tactical;
         PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
-          return_tactical loc (TacticAst.Then (tac, tacs))
+          (TacticAst.Then (loc, tac, tacs))
       ]
     | "loops" RIGHTA
-      [ [ IDENT "do" | IDENT "Do" ]; count = int; tac = tactical ->
-          return_tactical loc (TacticAst.Do (count, tac))
-      | [ IDENT "repeat" | IDENT "Repeat" ]; tac = tactical ->
-          return_tactical loc (TacticAst.Repeat tac)
+      [ [ IDENT "do" ]; count = int; tac = tactical ->
+          TacticAst.Do (loc, count, tac)
+      | [ IDENT "repeat" ]; tac = tactical ->
+          TacticAst.Repeat (loc, tac)
       ]
     | "simple" NONA
-      [ [ IDENT "tries" | IDENT "Tries" ];
+      [ IDENT "tries";
         PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
-          return_tactical loc (TacticAst.Tries tacs)
-      | [ IDENT "try" | IDENT "Try" ]; tac = NEXT ->
-          return_tactical loc (TacticAst.Try tac)
-      | [ IDENT "fail" | IDENT "Fail" ] -> return_tactical loc TacticAst.Fail
-      | [ IDENT "id" | IDENT "Id" ] -> return_tactical loc TacticAst.IdTac
-      | PAREN "("; tac = tactical; PAREN ")" -> return_tactical loc tac
-      | tac = tactic -> return_tactical loc (TacticAst.Tactic tac)
+          TacticAst.Tries (loc, tacs)
+      | IDENT "try"; tac = NEXT ->
+          TacticAst.Try (loc, tac)
+      | IDENT "fail" -> TacticAst.Fail loc
+      | IDENT "id" -> TacticAst.IdTac loc
+      | PAREN "("; tac = tactical; PAREN ")" -> tac
+      | tac = tactic -> TacticAst.Tactic (loc, tac)
       ]
     ];
-  theorem_flavour: [  (* all flavours but Goal *)
-    [ [ IDENT "definition"  | IDENT "Definition"  ] -> `Definition
-    | [ IDENT "fact"        | IDENT "Fact"        ] -> `Fact
-    | [ IDENT "lemma"       | IDENT "Lemma"       ] -> `Lemma
-    | [ IDENT "remark"      | IDENT "Remark"      ] -> `Remark
-    | [ IDENT "theorem"     | IDENT "Theorem"     ] -> `Theorem
+  theorem_flavour: [
+    [ [ IDENT "definition"  ] -> `Definition
+    | [ IDENT "fact"        ] -> `Fact
+    | [ IDENT "lemma"       ] -> `Lemma
+    | [ IDENT "remark"      ] -> `Remark
+    | [ IDENT "theorem"     ] -> `Theorem
     ]
   ];
   inductive_spec: [ [
@@ -469,27 +469,63 @@ EXTEND
       let ind_types = fst_ind_type :: tl_ind_types in
       (params, ind_types)
   ] ];
-  print_kind: [
-    [ [ IDENT "Env" | IDENT "env" | IDENT "Environment" | IDENT "environment" ]
-      -> `Env
-    | [ IDENT "Coer" | IDENT "coer" | IDENT "Coercions" | IDENT "coercions" ]
-      -> `Coer
-  ] ];
 
-  command: [
-    [ [ IDENT "abort" | IDENT "Abort" ] -> return_command loc TacticAst.Abort
-    | [ IDENT "proof" | IDENT "Proof" ] -> return_command loc TacticAst.Proof
-    | [ IDENT "quit"  | IDENT "Quit"  ] -> return_command loc TacticAst.Quit
-    | [ IDENT "qed"   | IDENT "Qed"   ] ->
-        return_command loc (TacticAst.Qed None)
-    | [ IDENT "print"   | IDENT "Print" ];
-      print_kind = print_kind ->
-            return_command loc (TacticAst.Print print_kind)
-    | [ IDENT "save"  | IDENT "Save"  ]; name = IDENT ->
-        return_command loc (TacticAst.Qed (Some name))
+  macro: [[
+      [ IDENT "abort" ] -> TacticAst.Abort loc
+    | [ IDENT "quit"  ] -> TacticAst.Quit loc
+    | [ IDENT "print" ]; name = QSTRING -> TacticAst.Print (loc, name)
+    | [ IDENT "undo"   ]; steps = OPT NUM ->
+        TacticAst.Undo (loc, int_opt steps)
+    | [ IDENT "redo"   ]; steps = OPT NUM ->
+        TacticAst.Redo (loc, int_opt steps)
+    | [ IDENT "check"   ]; t = term ->
+        TacticAst.Check (loc, t)
+    | [ IDENT "print" ]; name = QSTRING -> TacticAst.Print (loc, name)
+  ]];
+
+  alias_spec: [
+    [ IDENT "id"; id = QSTRING; SYMBOL "="; uri = QSTRING ->
+      let alpha = "[a-zA-Z]" in
+      let num = "[0-9]+" in
+      let ident_cont = "\\("^alpha^"\\|"^num^"\\|_\\|\\\\\\)" in
+      let ident = "\\("^alpha^ident_cont^"*\\|_"^ident_cont^"+\\)" in
+      let rex = Str.regexp ("^"^ident^"$") in
+      if Str.string_match rex id 0 then
+        let rex = Str.regexp 
+          ("^\\(cic:/\\|theory:/\\)"^ident^
+           "\\(/"^ident^"+\\)*\\(\\."^ident^"\\)+"^
+           "\\(#xpointer("^ num^"\\(/"^num^"\\)+)\\)?$") 
+        in
+        if Str.string_match rex uri 0 then
+          TacticAst.Ident_alias (id, uri)
+        else 
+          raise (Parse_error (loc,sprintf "Not a valid uri: %s" uri))
+      else
+        raise (Parse_error (loc,sprintf "Not a valid identifier: %s" id))
+    | IDENT "symbol"; symbol = QSTRING;
+      instance = OPT [ PAREN "("; IDENT "instance"; n = NUM; PAREN ")" -> n ];
+      SYMBOL "="; dsc = QSTRING ->
+        let instance =
+          match instance with Some i -> int_of_string i | None -> 0
+        in
+        TacticAst.Symbol_alias (symbol, instance, dsc)
+    | IDENT "num";
+      instance = OPT [ PAREN "("; IDENT "instance"; n = NUM; PAREN ")" -> n ];
+      SYMBOL "="; dsc = QSTRING ->
+        let instance =
+          match instance with Some i -> int_of_string i | None -> 0
+        in
+        TacticAst.Number_alias (instance, dsc)
+    ]
+  ];
+  
+  command: [[
+      [ IDENT "set"    ]; n = QSTRING; v = QSTRING ->
+        TacticAst.Set (loc, n, v)
+    | [ IDENT "qed"   ] -> TacticAst.Qed loc
     | flavour = theorem_flavour; name = OPT IDENT; SYMBOL ":"; typ = term;
       body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
-        return_command loc (TacticAst.Theorem (flavour, name, typ, body))
+        TacticAst.Theorem (loc, flavour, name, typ, body)
     | "let"; ind_kind = [ "corec" -> `CoInductive | "rec"-> `Inductive ];
         defs = let_defs -> 
           let name,ty = 
@@ -500,48 +536,33 @@ EXTEND
             | _ -> assert false 
           in
           let body = CicAst.Ident (name,None) in
-          TacticAst.Theorem(`Definition, Some name, ty,
+          TacticAst.Theorem(loc, `Definition, Some name, ty,
             Some (CicAst.LetRec (ind_kind, defs, body)))
           
-    | [ IDENT "inductive" | IDENT "Inductive" ]; spec = inductive_spec ->
+    | [ IDENT "inductive" ]; spec = inductive_spec ->
         let (params, ind_types) = spec in
-        return_command loc (TacticAst.Inductive (params, ind_types))
-    | [ IDENT "coinductive" | IDENT "CoInductive" ]; spec = inductive_spec ->
+        TacticAst.Inductive (loc, params, ind_types)
+    | [ IDENT "coinductive" ]; spec = inductive_spec ->
         let (params, ind_types) = spec in
         let ind_types = (* set inductive flags to false (coinductive) *)
           List.map (fun (name, _, term, ctors) -> (name, false, term, ctors))
             ind_types
         in
-        return_command loc (TacticAst.Inductive (params, ind_types))
-    | [ IDENT "coercion" | IDENT "Coercion" ] ; name = IDENT -> 
-        return_command loc (TacticAst.Coercion (CicAst.Ident (name,Some [])))
-    | [ IDENT "coercion" | IDENT "Coercion" ] ; name = URI -> 
-        return_command loc (TacticAst.Coercion (CicAst.Uri (name,Some [])))
-    | [ IDENT "goal" | IDENT "Goal" ]; typ = term;
-      body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
-        return_command loc (TacticAst.Theorem (`Goal, None, typ, body))
-    | [ IDENT "undo"   | IDENT "Undo" ]; steps = OPT NUM ->
-        return_command loc (TacticAst.Undo (int_opt steps))
-    | [ IDENT "redo"   | IDENT "Redo" ]; steps = OPT NUM ->
-        return_command loc (TacticAst.Redo (int_opt steps))
-    | [ IDENT "baseuri"   | IDENT "Baseuri" ]; uri = OPT QSTRING ->
-        return_command loc (TacticAst.Baseuri uri)
-    | [ IDENT "basedir"   | IDENT "Basedir" ]; uri = OPT QSTRING ->
-        return_command loc (TacticAst.Basedir uri)
-    | [ IDENT "check"   | IDENT "Check" ]; t = term ->
-        return_command loc (TacticAst.Check t)
-(*
-    | [ IDENT "alias"   | IDENT "Alias" ]; spec = alias_spec ->
-        return_command loc (TacticAst.Alias spec)
-*)
-    ]
-  ];
-  script_entry: [
-    [ cmd = tactical0 -> Command cmd
-(*     | s = COMMENT -> Comment (loc, s) *)
+        TacticAst.Inductive (loc, params, ind_types)
+    | [ IDENT "coercion" ] ; name = IDENT -> 
+        TacticAst.Coercion (loc, CicAst.Ident (name,Some []))
+    | [ IDENT "coercion" ] ; name = URI -> 
+        TacticAst.Coercion (loc, CicAst.Uri (name,Some []))
+    | [ IDENT "alias"   ]; spec = alias_spec ->
+        TacticAst.Alias (loc, spec)
+  ]];
+
+  statement: [
+    [ cmd = command; SYMBOL "." -> TacticAst.Command (loc, cmd)
+    | tac = tactical; SYMBOL "." -> TacticAst.Tactical (loc, tac)
+    | mac = macro; SYMBOL "." -> TacticAst.Macro (loc, mac)
     ]
   ];
-  script: [ [ entries = LIST0 script_entry; EOI -> (loc, entries) ] ];
 END
 
 let exc_located_wrapper f =
@@ -555,12 +576,8 @@ let exc_located_wrapper f =
 
 let parse_term stream =
   exc_located_wrapper (fun () -> (Grammar.Entry.parse term0 stream))
-let parse_tactic stream =
-  exc_located_wrapper (fun () -> (Grammar.Entry.parse tactic stream))
-let parse_tactical stream =
-  exc_located_wrapper (fun () -> (Grammar.Entry.parse tactical0 stream))
-let parse_script stream =
-  exc_located_wrapper (fun () -> (Grammar.Entry.parse script stream))
+let parse_statement stream =
+  exc_located_wrapper (fun () -> (Grammar.Entry.parse statement stream))
 
 (**/**)
 
@@ -581,12 +598,13 @@ module EnvironmentP3 =
           (fun domain_item (dsc, _) acc ->
             let s =
               match domain_item with
-              | Id id -> sprintf "alias id %s = %s" id dsc
-              | Symbol (symb, instance) ->
-                  sprintf "alias symbol \"%s\" (instance %d) = \"%s\""
-                    symb instance dsc
-              | Num instance ->
-                  sprintf "alias num (instance %d) = \"%s\"" instance dsc
+              | Id id ->
+                  TacticAstPp.pp_alias (TacticAst.Ident_alias (id, dsc)) ^ "."
+              | Symbol (symb, i) ->
+                  TacticAstPp.pp_alias (TacticAst.Symbol_alias (symb, i, dsc))
+                  ^ "."
+              | Num i ->
+                  TacticAstPp.pp_alias (TacticAst.Number_alias (i, dsc)) ^ "."
             in
             s :: acc)
           env []