open Printf
+module Ast = CicNotationPt
+
+type statement =
+ (CicNotationPt.term, CicNotationPt.term, GrafiteAst.reduction,
+ GrafiteAst.obj, string)
+ GrafiteAst.statement
+
let grammar = CicNotationParser.level2_ast_grammar
let term = CicNotationParser.term
let statement = Grammar.Entry.create grammar "statement"
+let add_raw_attribute ~text t = Ast.AttributedTerm (`Raw text, t)
+
+let default_precedence = 50
+let default_associativity = Gramext.NonA
+
EXTEND
GLOBAL: term statement;
arg: [
[ LPAREN; names = LIST1 IDENT SEP SYMBOL ",";
SYMBOL ":"; ty = term; RPAREN -> names,ty
- | name = IDENT -> [name],CicNotationPt.Implicit
+ | name = IDENT -> [name],Ast.Implicit
]
];
constructor: [ [ name = IDENT; SYMBOL ":"; typ = term -> (name, typ) ] ];
- tactic_term: [ [ t = term -> t ] ];
- ident_list0: [
- [ SYMBOL "["; idents = LIST0 IDENT SEP SYMBOL ";"; SYMBOL "]" -> idents ]
- ];
+ tactic_term: [ [ t = term LEVEL "90N" -> t ] ];
+ ident_list0: [ [ LPAREN; idents = LIST0 IDENT; RPAREN -> idents ] ];
tactic_term_list1: [
[ tactic_terms = LIST1 tactic_term SEP SYMBOL "," -> tactic_terms ]
];
reduction_kind: [
- [ IDENT "reduce" -> `Reduce
+ [ IDENT "normalize" -> `Normalize
+ | IDENT "reduce" -> `Reduce
| IDENT "simplify" -> `Simpl
- | IDENT "whd" -> `Whd
- | IDENT "normalize" -> `Normalize ]
+ | IDENT "unfold"; t = OPT term -> `Unfold t
+ | IDENT "whd" -> `Whd ]
];
sequent_pattern_spec: [
[ hyp_paths =
LIST0
[ id = IDENT ;
- path = OPT [SYMBOL ":" ; path = term -> path ] ->
- (id,match path with Some p -> p | None -> CicNotationPt.UserInput) ]
- SEP SYMBOL ";";
- goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = term -> term ] ->
+ path = OPT [SYMBOL ":" ; path = tactic_term -> path ] ->
+ (id,match path with Some p -> p | None -> Ast.UserInput) ];
+ goal_path = OPT [ SYMBOL <:unicode<vdash>>; term = tactic_term -> term ] ->
let goal_path =
- match goal_path with
- None -> CicNotationPt.UserInput
- | Some goal_path -> goal_path
+ match goal_path, hyp_paths with
+ None, [] -> Ast.UserInput
+ | None, _::_ -> Ast.Implicit
+ | Some goal_path, _ -> goal_path
in
hyp_paths,goal_path
]
[ res = OPT [
"in";
wanted_and_sps =
- [ "match" ; wanted = term ;
+ [ "match" ; wanted = tactic_term ;
sps = OPT [ "in"; sps = sequent_pattern_spec -> sps ] ->
Some wanted,sps
| sps = sequent_pattern_spec ->
] ->
let wanted,hyp_paths,goal_path =
match wanted_and_sps with
- wanted,None -> wanted, [], CicNotationPt.UserInput
+ wanted,None -> wanted, [], Ast.UserInput
| wanted,Some (hyp_paths,goal_path) -> wanted,hyp_paths,goal_path
in
wanted, hyp_paths, goal_path ] ->
match res with
- None -> None,[],CicNotationPt.UserInput
+ None -> None,[],Ast.UserInput
| Some ps -> ps]
];
direction: [
| SYMBOL "<" -> `RightToLeft ]
];
int: [ [ num = NUMBER -> int_of_string num ] ];
+ intros_spec: [
+ [ num = OPT [ num = int -> num ]; idents = OPT ident_list0 ->
+ let idents = match idents with None -> [] | Some idents -> idents in
+ num, idents
+ ]
+ ];
+ using: [ [ using = OPT [ IDENT "using"; t = tactic_term -> t ] -> using ] ];
tactic: [
[ IDENT "absurd"; t = tactic_term ->
GrafiteAst.Absurd (loc, t)
GrafiteAst.Assumption loc
| IDENT "auto";
depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
- width = OPT [ IDENT "width"; SYMBOL "="; i = int -> i ] ->
- GrafiteAst.Auto (loc,depth,width)
+ width = OPT [ IDENT "width"; SYMBOL "="; i = int -> i ];
+ paramodulation = OPT [ IDENT "paramodulation" ];
+ full = OPT [ IDENT "full" ] -> (* ALB *)
+ GrafiteAst.Auto (loc,depth,width,paramodulation,full)
| IDENT "clear"; id = IDENT ->
GrafiteAst.Clear (loc,id)
| IDENT "clearbody"; id = IDENT ->
GrafiteAst.Cut (loc, ident, t)
| IDENT "decide"; IDENT "equality" ->
GrafiteAst.DecideEquality loc
- | IDENT "decompose"; where = tactic_term ->
- GrafiteAst.Decompose (loc, where)
+ | IDENT "decompose"; types = OPT ident_list0; what = IDENT;
+ (num, idents) = intros_spec ->
+ let types = match types with None -> [] | Some types -> types in
+ let to_spec id = GrafiteAst.Ident id in
+ GrafiteAst.Decompose (loc, List.rev_map to_spec types, what, idents)
| IDENT "discriminate"; t = tactic_term ->
GrafiteAst.Discriminate (loc, t)
- | IDENT "elim"; what = tactic_term;
- using = OPT [ "using"; using = tactic_term -> using ];
- OPT "names"; num = OPT [num = int -> num];
- idents = OPT ident_list0 ->
- let idents = match idents with None -> [] | Some idents -> idents in
+ | IDENT "elim"; what = tactic_term; using = using;
+ (num, idents) = intros_spec ->
GrafiteAst.Elim (loc, what, using, num, idents)
- | IDENT "elimType"; what = tactic_term;
- using = OPT [ "using"; using = tactic_term -> using ];
- OPT "names"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
- let idents = match idents with None -> [] | Some idents -> idents in
+ | IDENT "elimType"; what = tactic_term; using = using;
+ (num, idents) = intros_spec ->
GrafiteAst.ElimType (loc, what, using, num, idents)
| IDENT "exact"; t = tactic_term ->
GrafiteAst.Exact (loc, t)
| IDENT "fold"; kind = reduction_kind; t = tactic_term; p = pattern_spec ->
let (pt,_,_) = p in
if pt <> None then
- raise (CicNotationParser.Parse_error
- (loc, "the pattern cannot specify the term to replace, only its"
- ^ " paths in the hypotheses and in the conclusion"))
+ raise (HExtlib.Localized (loc, CicNotationParser.Parse_error
+ ("the pattern cannot specify the term to replace, only its"
+ ^ " paths in the hypotheses and in the conclusion")))
else
GrafiteAst.Fold (loc, kind, t, p)
| IDENT "fourier" ->
| IDENT "intro"; ident = OPT IDENT ->
let idents = match ident with None -> [] | Some id -> [id] in
GrafiteAst.Intros (loc, Some 1, idents)
- | IDENT "intros"; num = OPT [num = int -> num]; idents = OPT ident_list0 ->
- let idents = match idents with None -> [] | Some idents -> idents in
+ | IDENT "intros"; (num, idents) = intros_spec ->
GrafiteAst.Intros (loc, num, idents)
| IDENT "lapply";
depth = OPT [ IDENT "depth"; SYMBOL "="; i = int -> i ];
what = tactic_term;
to_what = OPT [ "to" ; t = tactic_term_list1 -> t ];
- ident = OPT [ "using" ; ident = IDENT -> ident ] ->
+ ident = OPT [ IDENT "using" ; ident = IDENT -> ident ] ->
let to_what = match to_what with None -> [] | Some to_what -> to_what in
GrafiteAst.LApply (loc, depth, to_what, what, ident)
| IDENT "left" -> GrafiteAst.Left loc
let (pt,_,_) = p in
if pt <> None then
raise
- (CicNotationParser.Parse_error
- (loc,"the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion"))
+ (HExtlib.Localized (loc,
+ (CicNotationParser.Parse_error
+ "the pattern cannot specify the term to rewrite, only its paths in the hypotheses and in the conclusion")))
else
GrafiteAst.Rewrite (loc, d, t, p)
| IDENT "right" ->
GrafiteAst.Transitivity (loc, t)
]
];
- tactical:
+ atomic_tactical:
[ "sequence" LEFTA
- [ tacticals = LIST1 NEXT SEP SYMBOL ";" ->
- match tacticals with
- [] -> assert false
- | [tac] -> tac
- | l -> GrafiteAst.Seq (loc, l)
+ [ t1 = SELF; SYMBOL ";"; t2 = SELF ->
+ let ts =
+ match t1 with
+ | GrafiteAst.Seq (_, l) -> l @ [ t2 ]
+ | _ -> [ t1; t2 ]
+ in
+ GrafiteAst.Seq (loc, ts)
]
| "then" NONA
- [ tac = tactical; SYMBOL ";";
- SYMBOL "["; tacs = LIST0 tactical SEP SYMBOL "|"; SYMBOL "]" ->
+ [ tac = SELF; SYMBOL ";";
+ SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
(GrafiteAst.Then (loc, tac, tacs))
]
| "loops" RIGHTA
- [ IDENT "do"; count = int; tac = tactical ->
+ [ IDENT "do"; count = int; tac = SELF; IDENT "end" ->
GrafiteAst.Do (loc, count, tac)
- | IDENT "repeat"; tac = tactical ->
- GrafiteAst.Repeat (loc, tac)
+ | IDENT "repeat"; tac = SELF; IDENT "end" -> GrafiteAst.Repeat (loc, tac)
]
| "simple" NONA
[ IDENT "first";
- SYMBOL "["; tacs = LIST0 tactical SEP SYMBOL "|"; SYMBOL "]" ->
+ SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
GrafiteAst.First (loc, tacs)
- | IDENT "try"; tac = NEXT ->
- GrafiteAst.Try (loc, tac)
+ | IDENT "try"; tac = SELF -> GrafiteAst.Try (loc, tac)
| IDENT "solve";
- SYMBOL "["; tacs = LIST0 tactical SEP SYMBOL "|"; SYMBOL "]" ->
+ SYMBOL "["; tacs = LIST0 SELF SEP SYMBOL "|"; SYMBOL "]"->
GrafiteAst.Solve (loc, tacs)
- | LPAREN; tac = tactical; RPAREN -> tac
+ | LPAREN; tac = SELF; RPAREN -> tac
| tac = tactic -> GrafiteAst.Tactic (loc, tac)
]
];
+ punctuation_tactical:
+ [
+ [ SYMBOL "[" -> GrafiteAst.Branch loc
+ | SYMBOL "|" -> GrafiteAst.Shift loc
+ | i = int; SYMBOL ":" -> GrafiteAst.Pos (loc, i)
+ | SYMBOL "]" -> GrafiteAst.Merge loc
+ | SYMBOL ";" -> GrafiteAst.Semicolon loc
+ | SYMBOL "." -> GrafiteAst.Dot loc
+ ]
+ ];
+ tactical:
+ [ "simple" NONA
+ [ IDENT "focus"; goals = LIST1 int -> GrafiteAst.Focus (loc, goals)
+ | IDENT "unfocus" -> GrafiteAst.Unfocus loc
+ | IDENT "skip" -> GrafiteAst.Skip loc
+ | tac = atomic_tactical LEVEL "loops" -> tac
+ ]
+ ];
theorem_flavour: [
[ [ IDENT "definition" ] -> `Definition
| [ IDENT "fact" ] -> `Fact
macro: [
[ [ IDENT "quit" ] -> GrafiteAst.Quit loc
(* | [ IDENT "abort" ] -> GrafiteAst.Abort loc *)
- | [ IDENT "print" ]; name = QSTRING -> GrafiteAst.Print (loc, name)
(* | [ IDENT "undo" ]; steps = OPT NUMBER ->
GrafiteAst.Undo (loc, int_opt steps)
| [ IDENT "redo" ]; steps = OPT NUMBER ->
then
GrafiteAst.Ident_alias (id, uri)
else
- raise (CicNotationParser.Parse_error (loc,sprintf "Not a valid uri: %s" uri))
+ raise
+ (HExtlib.Localized (loc, CicNotationParser.Parse_error (sprintf "Not a valid uri: %s" uri)))
else
- raise (CicNotationParser.Parse_error (loc,
- sprintf "Not a valid identifier: %s" id))
+ raise (HExtlib.Localized (loc, CicNotationParser.Parse_error (
+ sprintf "Not a valid identifier: %s" id)))
| IDENT "symbol"; symbol = QSTRING;
instance = OPT [ LPAREN; IDENT "instance"; n = int; RPAREN -> n ];
SYMBOL "="; dsc = QSTRING ->
]
];
argument: [
- [ id = IDENT -> CicNotationPt.IdentArg (0, id)
- | l = LIST1 [ SYMBOL <:unicode<eta>> (* η *) -> () ] SEP SYMBOL ".";
- SYMBOL "."; id = IDENT ->
- CicNotationPt.IdentArg (List.length l, id)
+ [ l = LIST0 [ SYMBOL <:unicode<eta>> (* η *); SYMBOL "." -> () ];
+ id = IDENT ->
+ Ast.IdentArg (List.length l, id)
]
];
associativity: [
[ "with"; IDENT "precedence"; n = NUMBER -> int_of_string n ]
];
notation: [
- [ s = QSTRING;
+ [ dir = OPT direction; s = QSTRING;
assoc = OPT associativity; prec = OPT precedence;
IDENT "for";
p2 =
[ blob = UNPARSED_AST ->
- CicNotationParser.parse_level2_ast (Stream.of_string blob)
+ add_raw_attribute ~text:(sprintf "@{%s}" blob)
+ (CicNotationParser.parse_level2_ast
+ (Ulexing.from_utf8_string blob))
| blob = UNPARSED_META ->
- CicNotationParser.parse_level2_meta (Stream.of_string blob) ]
- ->
- (CicNotationParser.parse_level1_pattern (Stream.of_string s), assoc, prec, p2)
+ add_raw_attribute ~text:(sprintf "${%s}" blob)
+ (CicNotationParser.parse_level2_meta
+ (Ulexing.from_utf8_string blob))
+ ] ->
+ let assoc =
+ match assoc with
+ | None -> default_associativity
+ | Some assoc -> assoc
+ in
+ let prec =
+ match prec with
+ | None -> default_precedence
+ | Some prec -> prec
+ in
+ let p1 =
+ add_raw_attribute ~text:s
+ (CicNotationParser.parse_level1_pattern
+ (Ulexing.from_utf8_string s))
+ in
+ (dir, p1, assoc, prec, p2)
]
];
level3_term: [
- [ u = URI -> CicNotationPt.UriPattern (UriManager.uri_of_string u)
- | id = IDENT -> CicNotationPt.VarPattern id
- | SYMBOL "_" -> CicNotationPt.ImplicitPattern
+ [ u = URI -> Ast.UriPattern (UriManager.uri_of_string u)
+ | id = IDENT -> Ast.VarPattern id
+ | SYMBOL "_" -> Ast.ImplicitPattern
| LPAREN; terms = LIST1 SELF; RPAREN ->
(match terms with
| [] -> assert false
| [term] -> term
- | terms -> CicNotationPt.ApplPattern terms)
+ | terms -> Ast.ApplPattern terms)
]
];
interpretation: [
- [ s = CSYMBOL; args = LIST1 argument; SYMBOL "="; t = level3_term ->
+ [ s = CSYMBOL; args = LIST0 argument; SYMBOL "="; t = level3_term ->
(s, args, t)
]
];
typ = term; SYMBOL <:unicode<def>> ; newname = IDENT ->
GrafiteAst.Obj (loc,
GrafiteAst.Theorem
- (`Variant,name,typ,Some (CicNotationPt.Ident (newname, None))))
+ (`Variant,name,typ,Some (Ast.Ident (newname, None))))
| flavour = theorem_flavour; name = IDENT; SYMBOL ":"; typ = term;
body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
GrafiteAst.Obj (loc,GrafiteAst.Theorem (flavour, name, typ, body))
- | flavour = theorem_flavour; name = IDENT;
- body = OPT [ SYMBOL <:unicode<def>> (* ≝ *); body = term -> body ] ->
+ | flavour = theorem_flavour; name = IDENT; SYMBOL <:unicode<def>> (* ≝ *);
+ body = term ->
GrafiteAst.Obj (loc,
- GrafiteAst.Theorem (flavour, name, CicNotationPt.Implicit, body))
+ GrafiteAst.Theorem (flavour, name, Ast.Implicit, Some body))
| "let"; ind_kind = [ "corec" -> `CoInductive | "rec"-> `Inductive ];
defs = CicNotationParser.let_defs ->
let name,ty =
match defs with
- | ((CicNotationPt.Ident (name, None), Some ty),_,_) :: _ -> name,ty
- | ((CicNotationPt.Ident (name, None), None),_,_) :: _ ->
- name, CicNotationPt.Implicit
+ | ((Ast.Ident (name, None), Some ty),_,_) :: _ -> name,ty
+ | ((Ast.Ident (name, None), None),_,_) :: _ ->
+ name, Ast.Implicit
| _ -> assert false
in
- let body = CicNotationPt.Ident (name,None) in
+ let body = Ast.Ident (name,None) in
GrafiteAst.Obj (loc,GrafiteAst.Theorem(`Definition, name, ty,
- Some (CicNotationPt.LetRec (ind_kind, defs, body))))
- | [ IDENT "inductive" ]; spec = inductive_spec ->
+ Some (Ast.LetRec (ind_kind, defs, body))))
+ | IDENT "inductive"; spec = inductive_spec ->
let (params, ind_types) = spec in
GrafiteAst.Obj (loc,GrafiteAst.Inductive (params, ind_types))
- | [ IDENT "coinductive" ]; spec = inductive_spec ->
+ | 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))
in
GrafiteAst.Obj (loc,GrafiteAst.Inductive (params, ind_types))
| IDENT "coercion" ; name = IDENT ->
- GrafiteAst.Coercion (loc, CicNotationPt.Ident (name,Some []))
+ GrafiteAst.Coercion (loc, Ast.Ident (name,Some []))
| IDENT "coercion" ; name = URI ->
- GrafiteAst.Coercion (loc, CicNotationPt.Uri (name,Some []))
+ GrafiteAst.Coercion (loc, Ast.Uri (name,Some []))
| IDENT "alias" ; spec = alias_spec ->
GrafiteAst.Alias (loc, spec)
| IDENT "record" ; (params,name,ty,fields) = record_spec ->
| IDENT "default" ; what = QSTRING ; uris = LIST1 URI ->
let uris = List.map UriManager.uri_of_string uris in
GrafiteAst.Default (loc,what,uris)
- | IDENT "notation"; (l1, assoc, prec, l2) = notation ->
- GrafiteAst.Notation (loc, l1, assoc, prec, l2)
+ | IDENT "notation"; (dir, l1, assoc, prec, l2) = notation ->
+ GrafiteAst.Notation (loc, dir, l1, assoc, prec, l2)
| IDENT "interpretation"; id = QSTRING;
(symbol, args, l3) = interpretation ->
GrafiteAst.Interpretation (loc, id, (symbol, args), l3)
+ | IDENT "metadata"; [ IDENT "dependency" | IDENT "baseuri" ] ; URI ->
+ (** metadata commands lives only in .moo, where they are in marshalled
+ * form *)
+ raise (HExtlib.Localized (loc,CicNotationParser.Parse_error "metadata not allowed here"))
| IDENT "dump" -> GrafiteAst.Dump loc
| IDENT "render"; u = URI ->
]];
executable: [
[ cmd = command; SYMBOL "." -> GrafiteAst.Command (loc, cmd)
- | tac = tactical; SYMBOL "." -> GrafiteAst.Tactical (loc, tac)
+ | tac = tactical; punct = punctuation_tactical ->
+ GrafiteAst.Tactical (loc, tac, Some punct)
+ | punct = punctuation_tactical -> GrafiteAst.Tactical (loc, punct, None)
| mac = macro; SYMBOL "." -> GrafiteAst.Macro (loc, mac)
]
];
with
| Stdpp.Exc_located (_, End_of_file) -> raise End_of_file
| Stdpp.Exc_located (floc, Stream.Error msg) ->
- raise (CicNotationParser.Parse_error (floc, msg))
+ raise (HExtlib.Localized (floc,CicNotationParser.Parse_error msg))
| Stdpp.Exc_located (floc, exn) ->
- raise (CicNotationParser.Parse_error (floc, (Printexc.to_string exn)))
+ raise
+ (HExtlib.Localized (floc,CicNotationParser.Parse_error (Printexc.to_string exn)))
+
+let parse_statement lexbuf =
+ exc_located_wrapper
+ (fun () -> (Grammar.Entry.parse statement (Obj.magic lexbuf)))
-let parse_statement stream =
- exc_located_wrapper (fun () -> (Grammar.Entry.parse statement stream))
+let parse_dependencies lexbuf =
+ let tok_stream,_ =
+ CicNotationLexer.level2_ast_lexer.Token.tok_func (Obj.magic lexbuf)
+ in
+ let rec parse acc =
+ (parser
+ | [< '("URI", u) >] ->
+ parse (GrafiteAst.UriDep (UriManager.uri_of_string u) :: acc)
+ | [< '("IDENT", "include"); '("QSTRING", fname) >] ->
+ parse (GrafiteAst.IncludeDep fname :: acc)
+ | [< '("IDENT", "set"); '("QSTRING", "baseuri"); '("QSTRING", baseuri) >] ->
+ parse (GrafiteAst.BaseuriDep baseuri :: acc)
+ | [< '("EOI", _) >] -> acc
+ | [< 'tok >] -> parse acc
+ | [< >] -> acc) tok_stream
+ in
+ List.rev (parse [])