ProgTutorial/Parsing.thy
changeset 514 7e25716c3744
parent 473 fea1b7ce5c4a
child 517 d8c376662bb4
equal deleted inserted replaced
513:f223f8223d4a 514:7e25716c3744
   473 *}
   473 *}
   474   
   474   
   475 ML{*type 'a parser = Token.T list -> 'a * Token.T list*}
   475 ML{*type 'a parser = Token.T list -> 'a * Token.T list*}
   476 
   476 
   477 text {*
   477 text {*
       
   478   {\bf REDO!!}
       
   479 
       
   480 
   478   The reason for using token parsers is that theory syntax, as well as the
   481   The reason for using token parsers is that theory syntax, as well as the
   479   parsers for the arguments of proof methods, use the type @{ML_type
   482   parsers for the arguments of proof methods, use the type @{ML_type
   480   Token.T}.
   483   Token.T}.
   481 
   484 
   482   \begin{readmore}
   485   \begin{readmore}
   504   produces three tokens where the first and the last are identifiers, since
   507   produces three tokens where the first and the last are identifiers, since
   505   @{text [quotes] "hello"} and @{text [quotes] "world"} do not match any
   508   @{text [quotes] "hello"} and @{text [quotes] "world"} do not match any
   506   other syntactic category. The second indicates a space.
   509   other syntactic category. The second indicates a space.
   507 
   510 
   508   We can easily change what is recognised as a keyword with the function
   511   We can easily change what is recognised as a keyword with the function
   509   @{ML_ind keyword in Keyword}. For example calling it with 
   512   @{ML_ind define in Keyword}. For example calling it with 
   510 *}
   513 *}
   511 
   514 
   512 ML{*val _ = Keyword.keyword "hello"*}
   515 ML{*val _ = Keyword.define ("hello", NONE) *}
   513 
   516 
   514 text {*
   517 text {*
   515   then lexing @{text [quotes] "hello world"} will produce
   518   then lexing @{text [quotes] "hello world"} will produce
   516 
   519 
   517   @{ML_response_fake [display,gray] "Outer_Syntax.scan Position.none \"hello world\"" 
   520   @{ML_response_fake [display,gray] "Outer_Syntax.scan Position.none \"hello world\"" 
   958 
   961 
   959 ML{*let
   962 ML{*let
   960   val do_nothing = Scan.succeed (Local_Theory.background_theory I)
   963   val do_nothing = Scan.succeed (Local_Theory.background_theory I)
   961   val kind = Keyword.thy_decl
   964   val kind = Keyword.thy_decl
   962 in
   965 in
   963   Outer_Syntax.local_theory "foobar" "description of foobar" kind do_nothing
   966   Outer_Syntax.local_theory ("foobar", kind) "description of foobar" do_nothing
   964 end *}
   967 end *}
   965 
   968 
   966 text {*
   969 text {*
   967   The crucial function @{ML_ind local_theory in Outer_Syntax} expects a name for the command, a
   970   The crucial function @{ML_ind local_theory in Outer_Syntax} expects a name for the command, a
   968   short description, a kind indicator (which we will explain later more thoroughly) and a
   971   short description, a kind indicator (which we will explain later more thoroughly) and a
   995   @{ML
   998   @{ML
   996 "let
   999 "let
   997   val do_nothing = Scan.succeed (Local_Theory.background_theory I)
  1000   val do_nothing = Scan.succeed (Local_Theory.background_theory I)
   998   val kind = Keyword.thy_decl
  1001   val kind = Keyword.thy_decl
   999 in
  1002 in
  1000   Outer_Syntax.local_theory \"foobar\" \"description of foobar\" kind do_nothing
  1003   Outer_Syntax.local_theory (\"foobar\", kind) \"description of foobar\" do_nothing
  1001 end"}\\
  1004 end"}\\
  1002   @{text "\<verbclose>"}\\
  1005   @{text "\<verbclose>"}\\
  1003   \isacommand{end}
  1006   \isacommand{end}
  1004   \end{graybox}
  1007   \end{graybox}
  1005   \caption{This file can be used to generate a log file. This log file in turn can
  1008   \caption{This file can be used to generate a log file. This log file in turn can
  1096 text {* 
  1099 text {* 
  1097   but you will not see any action as we chose to implement this command to do
  1100   but you will not see any action as we chose to implement this command to do
  1098   nothing. The point of this command is only to show the procedure of how
  1101   nothing. The point of this command is only to show the procedure of how
  1099   to interact with ProofGeneral. A similar procedure has to be done with any 
  1102   to interact with ProofGeneral. A similar procedure has to be done with any 
  1100   other new command, and also any new keyword that is introduced with 
  1103   other new command, and also any new keyword that is introduced with 
  1101   the function @{ML_ind keyword in Keyword}. For example:
  1104   the function @{ML_ind define in Keyword}. For example:
  1102 *}
  1105 *}
  1103 
  1106 
  1104 ML{*val _ = Keyword.keyword "blink" *}
  1107 ML{*val _ = Keyword.define ("blink", NONE) *}
  1105 
  1108 
  1106 text {*
  1109 text {*
  1107   At the moment the command \isacommand{foobar} is not very useful. Let us
  1110   At the moment the command \isacommand{foobar} is not very useful. Let us
  1108   refine it a bit next by letting it take a proposition as argument and
  1111   refine it a bit next by letting it take a proposition as argument and
  1109   printing this proposition inside the tracing buffer.
  1112   printing this proposition inside the tracing buffer.
  1122   fun trace_prop str = 
  1125   fun trace_prop str = 
  1123      Local_Theory.background_theory (fn ctxt => (tracing str; ctxt))
  1126      Local_Theory.background_theory (fn ctxt => (tracing str; ctxt))
  1124 
  1127 
  1125   val kind = Keyword.thy_decl
  1128   val kind = Keyword.thy_decl
  1126 in
  1129 in
  1127   Outer_Syntax.local_theory "foobar_trace" "traces a proposition" 
  1130   Outer_Syntax.local_theory ("foobar_trace", kind) "traces a proposition" 
  1128     kind (Parse.prop >> trace_prop)
  1131     (Parse.prop >> trace_prop)
  1129 end *}
  1132 end *}
  1130 
  1133 
  1131 text {*
  1134 text {*
  1132   The command is now \isacommand{foobar\_trace} and can be used to 
  1135   The command is now \isacommand{foobar\_trace} and can be used to 
  1133   see the proposition in the tracing buffer.  
  1136   see the proposition in the tracing buffer.  
  1164       Proof.theorem NONE (K I) [[(prop, [])]] lthy
  1167       Proof.theorem NONE (K I) [[(prop, [])]] lthy
  1165     end
  1168     end
  1166   
  1169   
  1167   val kind = Keyword.thy_goal
  1170   val kind = Keyword.thy_goal
  1168 in
  1171 in
  1169   Outer_Syntax.local_theory_to_proof "foobar_goal" "proves a proposition" 
  1172   Outer_Syntax.local_theory_to_proof ("foobar_goal", kind) "proves a proposition" 
  1170     kind (Parse.prop >> goal_prop)
  1173     (Parse.prop >> goal_prop)
  1171 end *}
  1174 end *}
  1172 
  1175 
  1173 text {*
  1176 text {*
  1174   The function @{text goal_prop} in Lines 2 to 7 takes a string (the proposition to be
  1177   The function @{text goal_prop} in Lines 2 to 7 takes a string (the proposition to be
  1175   proved) and a context as argument.  The context is necessary in order to be able to use
  1178   proved) and a context as argument.  The context is necessary in order to be able to use
  1223    end
  1226    end
  1224 
  1227 
  1225    val parser = Parse_Spec.opt_thm_name ":" -- Parse.ML_source
  1228    val parser = Parse_Spec.opt_thm_name ":" -- Parse.ML_source
  1226  
  1229  
  1227 in
  1230 in
  1228    Outer_Syntax.local_theory_to_proof "foobar_prove" "proving a proposition" 
  1231    Outer_Syntax.local_theory_to_proof ("foobar_prove", Keyword.thy_goal) 
  1229      Keyword.thy_goal (parser >> setup_proof)
  1232      "proving a proposition" 
       
  1233        (parser >> setup_proof)
  1230 end*}
  1234 end*}
  1231 
  1235 
  1232 (*
  1236 (*
  1233 foobar_prove test: {* @{prop "True"} *}
  1237 foobar_prove test: {* @{prop "True"} *}
  1234 apply(rule TrueI)
  1238 apply(rule TrueI)