+ tactic_where: [
+ [ where = OPT [ "in"; ident = IDENT -> ident ] -> where ]
+ ];
+ tactic_term: [
+ [ t = term -> t ]
+ ];
+ ident_list0: [
+ [ PAREN "["; idents = LIST0 IDENT SEP SYMBOL ";"; PAREN "]" -> idents ]
+ ];
+ ident_list1: [
+ [ PAREN "["; idents = LIST1 IDENT SEP SYMBOL ";"; PAREN "]" -> idents ]
+ ];
+ reduction_kind: [
+ [ "reduce" -> `Reduce
+ | "simpl" -> `Simpl
+ | "whd" -> `Whd ]
+ ];
+ tactic: [
+ [ IDENT "absurd" -> return_tactic loc TacticAst.Absurd
+ | IDENT "apply"; t = tactic_term -> return_tactic loc (TacticAst.Apply t)
+ | IDENT "assumption" -> return_tactic loc TacticAst.Assumption
+ | IDENT "change"; t1 = tactic_term; "with"; t2 = tactic_term;
+ where = tactic_where ->
+ return_tactic loc (TacticAst.Change (t1, t2, where))
+ (* TODO Change_pattern *)
+ | IDENT "contradiction" -> return_tactic loc TacticAst.Contradiction
+ | IDENT "cut"; t = tactic_term -> return_tactic loc (TacticAst.Cut t)
+ | IDENT "decompose"; principles = ident_list1; where = IDENT ->
+ return_tactic loc (TacticAst.Decompose (where, principles))
+ | IDENT "discriminate"; hyp = IDENT ->
+ return_tactic loc (TacticAst.Discriminate hyp)
+ | IDENT "elim"; IDENT "type"; t = tactic_term ->
+ return_tactic loc (TacticAst.ElimType t)
+ | IDENT "elim"; t1 = tactic_term;
+ using = OPT [ IDENT "using"; using = tactic_term -> using ] ->
+ return_tactic loc (TacticAst.Elim (t1, using))
+ | IDENT "exact"; t = tactic_term -> return_tactic loc (TacticAst.Exact t)
+ | IDENT "exists" -> return_tactic loc TacticAst.Exists
+ | IDENT "fold"; kind = reduction_kind; t = tactic_term ->
+ return_tactic loc (TacticAst.Fold (kind, t))
+ | IDENT "fourier" -> return_tactic loc TacticAst.Fourier
+ | IDENT "injection"; ident = IDENT ->
+ return_tactic loc (TacticAst.Injection 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 "left" -> return_tactic loc TacticAst.Left
+ | "let"; t = tactic_term; IDENT "in"; where = IDENT ->
+ return_tactic loc (TacticAst.LetIn (t, where))
+ (* TODO Reduce *)
+ | IDENT "reflexivity" -> return_tactic loc TacticAst.Reflexivity
+ | IDENT "replace"; t1 = tactic_term; "with"; t2 = tactic_term ->
+ return_tactic loc (TacticAst.Replace (t1, t2))
+ (* TODO Rewrite *)
+ (* TODO Replace_pattern *)
+ | IDENT "right" -> return_tactic loc TacticAst.Right
+ | IDENT "ring" -> return_tactic loc TacticAst.Ring
+ | IDENT "split" -> return_tactic loc TacticAst.Split
+ | IDENT "symmetry" -> return_tactic loc TacticAst.Symmetry
+ | IDENT "transitivity"; t = tactic_term ->
+ return_tactic loc (TacticAst.Transitivity t)
+ ]
+ ];
+ tactical0 : [ [ t = tactical; SYMBOL "." -> t ] ];
+ tactical: [
+ [ IDENT "fail" -> return_tactical loc TacticAst.Fail
+ | IDENT "do"; count = int; tac = tactical ->
+ return_tactical loc (TacticAst.Do (count, tac))
+ | IDENT "id" -> return_tactical loc TacticAst.IdTac
+ | IDENT "repeat"; tac = tactical ->
+ return_tactical loc (TacticAst.Repeat tac)
+ | tactics = LIST0 tactical SEP SYMBOL ";" ->
+ return_tactical loc (TacticAst.Seq tactics)
+ | tac = tactical;
+ PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
+ return_tactical loc (TacticAst.Then (tac, tacs))
+ | IDENT "tries";
+ PAREN "["; tacs = LIST0 tactical SEP SYMBOL ";"; PAREN "]" ->
+ return_tactical loc (TacticAst.Tries tacs)
+ | IDENT "try"; tac = tactical -> return_tactical loc (TacticAst.Try tac)
+ | tac = tactic -> return_tactical loc (TacticAst.Tactic tac)
+ | PAREN "("; tac = tactical; PAREN ")" -> return_tactical loc tac
+ ]
+ ];