CookBook/Parsing.thy
changeset 126 fcc0e6e54dca
parent 125 748d9c1a32fb
child 127 74846cb0fff9
equal deleted inserted replaced
125:748d9c1a32fb 126:fcc0e6e54dca
   525  Token ((\"bar\", ({line=8, end_line=8}, {line=8})), (Ident, \"bar\"), \<dots>)]"}
   525  Token ((\"bar\", ({line=8, end_line=8}, {line=8})), (Ident, \"bar\"), \<dots>)]"}
   526 
   526 
   527   in which the @{text [quotes] "\\n"} causes the second token to be in 
   527   in which the @{text [quotes] "\\n"} causes the second token to be in 
   528   line 8.
   528   line 8.
   529 
   529 
   530   Now by using the parser @{ML OuterParse.position} you can decode the positional
   530   By using the parser @{ML OuterParse.position} you can decode the positional
   531   information and return it as part of the parsed input. For example
   531   information and return it as part of the parsed input. For example
   532 
   532 
   533 @{ML_response_fake [display,gray]
   533 @{ML_response_fake [display,gray]
   534 "let
   534 "let
   535   val input = (filtered_input' \"where\")
   535   val input = (filtered_input' \"where\")
   561 "(\"\\^E\\^Ftoken\\^Efoo\\^E\\^F\\^E\", [])"}
   561 "(\"\\^E\\^Ftoken\\^Efoo\\^E\\^F\\^E\", [])"}
   562 
   562 
   563   The function @{ML OuterParse.prop} is similar, except that it gives a different
   563   The function @{ML OuterParse.prop} is similar, except that it gives a different
   564   error message, when parsing fails. Looking closer at the result string you will
   564   error message, when parsing fails. Looking closer at the result string you will
   565   have noticed that the parser not just returns the parsed string, but also some 
   565   have noticed that the parser not just returns the parsed string, but also some 
   566   encoded positional information. You can see this better if you replace 
   566   encoded information. You can see this better if you replace 
   567   @{ML Position.none} by @{ML "(Position.line 42)"}, say.
   567   @{ML Position.none} by @{ML "(Position.line 42)"}, say.
   568 
   568 
   569 @{ML_response [display,gray]
   569 @{ML_response [display,gray]
   570 "let 
   570 "let 
   571   val input = OuterSyntax.scan (Position.line 42) \"foo\"
   571   val input = OuterSyntax.scan (Position.line 42) \"foo\"
   572 in 
   572 in 
   573   OuterParse.term input
   573   OuterParse.term input
   574 end"
   574 end"
   575 "(\"\\^E\\^Ftoken\\^Fline=42\\^Fend_line=42\\^Efoo\\^E\\^F\\^E\", [])"}
   575 "(\"\\^E\\^Ftoken\\^Fline=42\\^Fend_line=42\\^Efoo\\^E\\^F\\^E\", [])"}
   576   
   576   
   577   The positional information is stored so that code called later will be
   577   The positional information is stored so that code called later on will be
   578   able to give more precise error messages. 
   578   able to give more precise error messages. 
   579 
   579 
   580 *}
   580 *}
   581 
   581 
   582 section {* Parsing Specifications\label{sec:parsingspecs} *}
   582 section {* Parsing Specifications\label{sec:parsingspecs} *}
   604 text {*
   604 text {*
   605   For this we are going to use the parser:
   605   For this we are going to use the parser:
   606 *}
   606 *}
   607 
   607 
   608 ML %linenosgray{*val spec_parser = 
   608 ML %linenosgray{*val spec_parser = 
   609     OuterParse.opt_target --
   609      OuterParse.opt_target --
   610     OuterParse.fixes -- 
   610      OuterParse.fixes -- 
   611     OuterParse.for_fixes --
   611      OuterParse.for_fixes --
   612     Scan.optional 
   612      Scan.optional 
   613       (OuterParse.$$$ "where" |--
   613        (OuterParse.$$$ "where" |--
   614          OuterParse.!!! 
   614           OuterParse.!!! 
   615            (OuterParse.enum1 "|" 
   615             (OuterParse.enum1 "|" 
   616               (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*}
   616                (SpecParse.opt_thm_name ":" -- OuterParse.prop))) []*}
   617 
   617 
   618 text {*
   618 text {*
   619   Note that the parser does not parse the ketword \simpleinductive. This 
   619   Note that the parser does not parse the keyword \simpleinductive, even if it is
   620   will be done by the infrastructure that will eventually call this parser.
   620   meant to process definitions as shown above. The parser of the keyword 
       
   621   will be given by the infrastructure that will eventually calls @{ML spec_parser}.
       
   622   
       
   623 
   621   To see what the parser returns, let us parse the string corresponding to the 
   624   To see what the parser returns, let us parse the string corresponding to the 
   622   definition of @{term even} and @{term odd}:
   625   definition of @{term even} and @{term odd}:
   623 
   626 
   624 @{ML_response [display,gray]
   627 @{ML_response [display,gray]
   625 "let
   628 "let
   636      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   639      [((even0,\<dots>), \"\\^E\\^Ftoken\\^Eeven 0\\^E\\^F\\^E\"),
   637       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^E\\^F\\^E\"),
   640       ((evenS,\<dots>), \"\\^E\\^Ftoken\\^Eodd n \<Longrightarrow> even (Suc n)\\^E\\^F\\^E\"),
   638       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"}
   641       ((oddS,\<dots>), \"\\^E\\^Ftoken\\^Eeven n \<Longrightarrow> odd (Suc n)\\^E\\^F\\^E\")]), [])"}
   639 
   642 
   640   As can be seen, the result is a ``nested'' four-tuple consisting of an 
   643   As can be seen, the result is a ``nested'' four-tuple consisting of an 
   641   optional locale; a list of variables with optional type-annotation and  
   644   optional locale (in this case @{ML NONE}); a list of variables with optional 
   642   syntax-annotation; a list of for-fixes (fixed variables); and a list of rules 
   645   type-annotation and syntax-annotation; a list of for-fixes (fixed variables; in this
   643   where each rule has optionally a name and an attribute.
   646   case there are none); and a list of rules where every rule has optionally a name and 
       
   647   an attribute.
   644 
   648 
   645   In Line 2 of the parser, the function @{ML OuterParse.opt_target} reads a target 
   649   In Line 2 of the parser, the function @{ML OuterParse.opt_target} reads a target 
   646   in order to indicate a locale in which the specification is made. For example
   650   in order to indicate a locale in which the specification is made. For example
   647 
   651 
   648 @{ML_response [display,gray]
   652 @{ML_response [display,gray]
   649 "parse OuterParse.opt_target (filtered_input \"(in test)\")" "(SOME \"test\",[])"}
   653 "parse OuterParse.opt_target (filtered_input \"(in test)\")" "(SOME \"test\",[])"}
   650   
   654   
   651   returns the locale @{text [quotes] "test"}; if no target is given' like in  the
   655   returns the locale @{text [quotes] "test"}; if no target is given, like in  the
   652   casde of @{text "even"} and @{text "odd"}, the function returns @{ML NONE}.
   656   case of @{text "even"} and @{text "odd"}, the function returns @{ML NONE}.
   653 
   657 
   654   The function @{ML OuterParse.fixes} in Line 3 reads an \isacommand{and}-separated 
   658   The function @{ML OuterParse.fixes} in Line 3 reads an \isacommand{and}-separated 
   655   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. 
   656   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 
   657   @{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
   669   (blonk, NONE, NoSyn)],[])"}  
   673   (blonk, NONE, NoSyn)],[])"}  
   670 *}
   674 *}
   671 
   675 
   672 text {*
   676 text {*
   673   Whenever types are given, they are stored in the @{ML SOME}s. Since types
   677   Whenever types are given, they are stored in the @{ML SOME}s. Since types
   674   are part of the inner syntax they are strings with some printing directives 
   678   are part of the inner syntax they are strings with some encoded information 
   675   (see previous section). 
   679   (see previous section). 
   676   If a syntax translation is present for a variable, then it is
   680   If a syntax translation is present for a variable, then it is
   677   stored in the @{ML Mixfix} datastructure; no syntax translation is
   681   stored in the @{ML Mixfix} datastructure; no syntax translation is
   678   indicated by @{ML NoSyn}.
   682   indicated by @{ML NoSyn}.
   679 
   683 
   699   val ((name, attrib), _) = parse (SpecParse.thm_name \":\") input 
   703   val ((name, attrib), _) = parse (SpecParse.thm_name \":\") input 
   700 in 
   704 in 
   701   (name, map Args.dest_src attrib)
   705   (name, map Args.dest_src attrib)
   702 end" "(foo_lemma, [((\"intro\", []), \<dots>), ((\"dest\", [\<dots>]), \<dots>)])"}
   706 end" "(foo_lemma, [((\"intro\", []), \<dots>), ((\"dest\", [\<dots>]), \<dots>)])"}
   703  
   707  
   704   A name of a theorem can be quite complicated, as it can include attrinutes.
       
   705   The function @{ML opt_thm_name in SpecParse} is the ``optional'' variant of
   708   The function @{ML opt_thm_name in SpecParse} is the ``optional'' variant of
   706   @{ML thm_name in SpecParse}. As can be seen each theorem name can contain some 
   709   @{ML thm_name in SpecParse}. As can be seen each theorem name can contain some 
   707   attributes. If you want to print out all currently known attributes a theorem 
   710   attributes. If you want to print out all currently known attributes a theorem 
   708   can have, you can use the function:
   711   can have, you can use the function:
   709 
   712 
   712 HOL.dest:  declaration of Classical destruction rule
   715 HOL.dest:  declaration of Classical destruction rule
   713 HOL.elim:  declaration of Classical elimination rule 
   716 HOL.elim:  declaration of Classical elimination rule 
   714 \<dots>"}
   717 \<dots>"}
   715 
   718 
   716 
   719 
   717   For the inductive definitions described above only, the attibutes @{text "[intro]"} and
   720   For the inductive definitions described above only the attibutes @{text "[intro]"} and
   718   @{text "[simp]"} make sense.
   721   @{text "[simp]"} make sense.
   719 
   722 
   720   \begin{readmore}
   723   \begin{readmore}
   721   Attributes and arguments are implemented in the files @{ML_file "Pure/Isar/attrib.ML"} 
   724   Attributes and arguments are implemented in the files @{ML_file "Pure/Isar/attrib.ML"} 
   722   and @{ML_file "Pure/Isar/args.ML"}.
   725   and @{ML_file "Pure/Isar/args.ML"}.