CookBook/Parsing.thy
changeset 186 371e4375c994
parent 183 8bb4eaa2ec92
child 188 8939b8fd8603
equal deleted inserted replaced
185:043ef82000b4 186:371e4375c994
   616 text {*
   616 text {*
   617   For this we are going to use the parser:
   617   For this we are going to use the parser:
   618 *}
   618 *}
   619 
   619 
   620 ML %linenosgray{*val spec_parser = 
   620 ML %linenosgray{*val spec_parser = 
   621      OuterParse.opt_target --
       
   622      OuterParse.fixes -- 
   621      OuterParse.fixes -- 
   623      Scan.optional 
   622      Scan.optional 
   624        (OuterParse.$$$ "where" |--
   623        (OuterParse.$$$ "where" |--
   625           OuterParse.!!! 
   624           OuterParse.!!! 
   626             (OuterParse.enum1 "|" 
   625             (OuterParse.enum1 "|" 
   644       \"| evenS[intro]: \\\"odd n \<Longrightarrow> even (Suc n)\\\" \" ^ 
   643       \"| evenS[intro]: \\\"odd n \<Longrightarrow> even (Suc n)\\\" \" ^ 
   645       \"| oddS[intro]:  \\\"even n \<Longrightarrow> odd (Suc n)\\\"\")
   644       \"| oddS[intro]:  \\\"even n \<Longrightarrow> odd (Suc n)\\\"\")
   646 in
   645 in
   647   parse spec_parser input
   646   parse spec_parser input
   648 end"
   647 end"
   649 "(((NONE, [(even, NONE, NoSyn), (odd, NONE, NoSyn)]),
   648 "(([(even, NONE, NoSyn), (odd, NONE, NoSyn)],
   650      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   649      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   651       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^E\\^F\\^E\"),
   650       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^E\\^F\\^E\"),
   652       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"}
   651       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"}
   653 
   652 
   654   As you see, the result is a ``nested'' four-tuple consisting of an optional
   653   As you see, the result is a pair consisting of a list of
   655   locale (in this case @{ML NONE}); a list of variables with optional
   654   variables with optional type-annotation and syntax-annotation, and a list of
   656   type-annotation and syntax-annotation; and a list of rules where every rule
   655   rules where every rule has optionally a name and an attribute.
   657   has optionally a name and an attribute.
   656 
   658 
   657   The function @{ML OuterParse.fixes} in Line 2 of the parser reads an 
   659 
   658   \isacommand{and}-separated 
   660   In Line 2 of the parser, the function @{ML OuterParse.opt_target} reads a target 
       
   661   in order to indicate a locale in which the specification is made. For example
       
   662 
       
   663 @{ML_response [display,gray]
       
   664 "parse OuterParse.opt_target (filtered_input \"(in test)\")" "(SOME \"test\",[])"}
       
   665   
       
   666   returns the locale @{text [quotes] "test"}; if no target is given, like in  the
       
   667   case of @{text "even"} and @{text "odd"}, the function returns @{ML NONE}.
       
   668 
       
   669   The function @{ML OuterParse.fixes} in Line 3 reads an \isacommand{and}-separated 
       
   670   list of variables that can include optional type annotations and syntax translations. 
   659   list of variables that can include optional type annotations and syntax translations. 
   671   For example:\footnote{Note that in the code we need to write 
   660   For example:\footnote{Note that in the code we need to write 
   672   @{text "\\\"int \<Rightarrow> bool\\\""} in order to properly escape the double quotes
   661   @{text "\\\"int \<Rightarrow> bool\\\""} in order to properly escape the double quotes
   673   in the compound type.}
   662   in the compound type.}
   674 
   663 
   694 
   683 
   695   \begin{readmore}
   684   \begin{readmore}
   696   The datastructre for sytax annotations is defined in @{ML_file "Pure/Syntax/mixfix.ML"}.
   685   The datastructre for sytax annotations is defined in @{ML_file "Pure/Syntax/mixfix.ML"}.
   697   \end{readmore}
   686   \end{readmore}
   698 
   687 
   699   Lines 4 to 8 in the function @{ML spec_parser} implement the parser for a
   688   Lines 3 to 7 in the function @{ML spec_parser} implement the parser for a
   700   list of introduction rules, that is propositions with theorem
   689   list of introduction rules, that is propositions with theorem
   701   annotations. The introduction rules are propositions parsed by @{ML
   690   annotations. The introduction rules are propositions parsed by @{ML
   702   OuterParse.prop}. However, they can include an optional theorem name plus
   691   OuterParse.prop}. However, they can include an optional theorem name plus
   703   some attributes. For example
   692   some attributes. For example
   704 
   693 
   710 end" "(foo_lemma, [((\"intro\", []), \<dots>), ((\"dest\", [\<dots>]), \<dots>)])"}
   699 end" "(foo_lemma, [((\"intro\", []), \<dots>), ((\"dest\", [\<dots>]), \<dots>)])"}
   711  
   700  
   712   The function @{ML opt_thm_name in SpecParse} is the ``optional'' variant of
   701   The function @{ML opt_thm_name in SpecParse} is the ``optional'' variant of
   713   @{ML thm_name in SpecParse}. Theorem names can contain attributes. The name 
   702   @{ML thm_name in SpecParse}. Theorem names can contain attributes. The name 
   714   has to end with @{text [quotes] ":"}---see the argument of 
   703   has to end with @{text [quotes] ":"}---see the argument of 
   715   the function @{ML SpecParse.opt_thm_name} in Line 8.
   704   the function @{ML SpecParse.opt_thm_name} in Line 7.
   716 
   705 
   717   \begin{readmore}
   706   \begin{readmore}
   718   Attributes and arguments are implemented in the files @{ML_file "Pure/Isar/attrib.ML"} 
   707   Attributes and arguments are implemented in the files @{ML_file "Pure/Isar/attrib.ML"} 
   719   and @{ML_file "Pure/Isar/args.ML"}.
   708   and @{ML_file "Pure/Isar/args.ML"}.
   720   \end{readmore}
   709   \end{readmore}
   914   and then ``open up'' a proof in order to prove the proposition (for example
   903   and then ``open up'' a proof in order to prove the proposition (for example
   915   \isacommand{lemma}) or prove some other properties (for example
   904   \isacommand{lemma}) or prove some other properties (for example
   916   \isacommand{function}). To achieve this kind of behaviour, you have to use the kind
   905   \isacommand{function}). To achieve this kind of behaviour, you have to use the kind
   917   indicator @{ML thy_goal in OuterKeyword}.  Note, however, once you change the 
   906   indicator @{ML thy_goal in OuterKeyword}.  Note, however, once you change the 
   918   ``kind'' of a command from @{ML thy_decl in OuterKeyword} to @{ML thy_goal in OuterKeyword} 
   907   ``kind'' of a command from @{ML thy_decl in OuterKeyword} to @{ML thy_goal in OuterKeyword} 
   919   then the keyword file needs to be re-created.
   908   then the keyword file needs to be re-created!
   920 
   909 
   921   Below we change \isacommand{foobar} so that it takes a proposition as
   910   Below we change \isacommand{foobar} so that it takes a proposition as
   922   argument and then starts a proof in order to prove it. Therefore in Line 13, 
   911   argument and then starts a proof in order to prove it. Therefore in Line 13, 
   923   we set the kind indicator to @{ML thy_goal in OuterKeyword}.
   912   we set the kind indicator to @{ML thy_goal in OuterKeyword}.
   924 *}
   913 *}
   979 *}
   968 *}
   980 
   969 
   981 section {* Methods *}
   970 section {* Methods *}
   982 
   971 
   983 text {*
   972 text {*
   984   Methods are one central concept in Isabelle. Methods can be applied with the command
   973   Methods are a central concept in Isabelle. They are the ones you use for example
   985   \isacommand{apply}. To print out all currently known methods you can use the Isabelle
   974   in \isacommand{apply}. To print out all currently known methods you can use the 
   986   command. 
   975   Isabelle command. 
   987 *}
   976 *}
   988 
   977 
   989 print_methods
   978 print_methods
   990 
   979 
   991 text {*
   980 text {*
   996  {* Scan.succeed
   985  {* Scan.succeed
   997       (K (SIMPLE_METHOD ((etac @{thm conjE} THEN' rtac @{thm conjI}) 1))) *}
   986       (K (SIMPLE_METHOD ((etac @{thm conjE} THEN' rtac @{thm conjI}) 1))) *}
   998          "foobar method"
   987          "foobar method"
   999 
   988 
  1000 text {*
   989 text {*
  1001   It defines the method @{text foobar_meth} which takes no arguments and 
   990   It defines the method @{text foobar_meth}, which takes no arguments (therefore the
       
   991   parser @{ML Scan.succeed}) and 
  1002   only applies the tactic @{thm [source] conjE} and then @{thm [source] conjI}.
   992   only applies the tactic @{thm [source] conjE} and then @{thm [source] conjI}.
  1003   It can be applied in the following proof
   993   This method can be used in the following proof
  1004 *}
   994 *}
  1005 
   995 
  1006 lemma shows "A \<and> B \<Longrightarrow> C \<and> D"
   996 lemma shows "A \<and> B \<Longrightarrow> C \<and> D"
  1007 apply(foobar_meth)
   997 apply(foobar_meth)
  1008 txt {*
   998 txt {*
  1011   \begin{minipage}{\textwidth}
  1001   \begin{minipage}{\textwidth}
  1012   @{subgoals}
  1002   @{subgoals}
  1013   \end{minipage} *}
  1003   \end{minipage} *}
  1014 (*<*)oops(*>*)
  1004 (*<*)oops(*>*)
  1015 
  1005 
       
  1006 text {*
       
  1007   (FIXME: explain a version of rule-tac)
       
  1008 *}
  1016 
  1009 
  1017 (*<*)
  1010 (*<*)
  1018 
  1011 
  1019 chapter {* Parsing *}
  1012 chapter {* Parsing *}
  1020 
  1013