added example by Lukas Bulwahn
authorChristian Urban <urbanc@in.tum.de>
Tue, 17 Nov 2009 18:40:11 +0100
changeset 390 8ad407e77ea0
parent 389 4cc6df387ce9
child 391 ae2f0b40c840
added example by Lukas Bulwahn
ProgTutorial/Intro.thy
ProgTutorial/Parsing.thy
ProgTutorial/document/root.tex
progtutorial.pdf
--- a/ProgTutorial/Intro.thy	Sun Nov 15 13:47:31 2009 +0100
+++ b/ProgTutorial/Intro.thy	Tue Nov 17 18:40:11 2009 +0100
@@ -194,6 +194,7 @@
   \item @{text t}, @{text u}, @{text trm} for (raw) terms; ML-type: @{ML_type term}
   \item @{text ct}, @{text cu} for certified terms; ML-type: @{ML_type cterm}
   \item @{text "ty"}, @{text T}, @{text U} for (raw) types; ML-type: @{ML_type typ}
+  \item @{text "S"} for sorts; ML-type: @{ML_type sort}
   \item @{text th}, @{text thm} for theorems; ML-type: @{ML_type thm}
   \item @{text "foo_tac"} for tactics; ML-type: @{ML_type tactic}
   \item @{text thy} for theories; ML-type: @{ML_type theory}
@@ -226,6 +227,9 @@
   and helped with recipe \ref{rec:timing}. Parts of section \ref{sec:storing}
   are by him.
 
+  \item {\bf Lukas Bulwahn} made me aware of the problems with recursive
+  parsers.
+
   \item {\bf Jeremy Dawson} wrote the first version of the chapter
   about parsing.
 
@@ -255,6 +259,4 @@
   \input{pversion}
 *}
 
-
-
 end
--- a/ProgTutorial/Parsing.thy	Sun Nov 15 13:47:31 2009 +0100
+++ b/ProgTutorial/Parsing.thy	Tue Nov 17 18:40:11 2009 +0100
@@ -372,7 +372,70 @@
 "Scan.lift ($$ \"h\" -- $$ \"e\") (1, Symbol.explode \"hello\")"
 "((\"h\", \"e\"), (1, [\"l\", \"l\", \"o\"]))"}
 
-  (FIXME: In which situations is this useful? Give examples.) 
+  \footnote{\bf FIXME: In which situations is @{text "lift"} useful? Give examples.} 
+
+  Be aware of recursive parsers. Suppose you want to read strings
+  separated by commas and by parentheses into a tree. We assume 
+  the trees are represented by the datatype:
+*}
+
+ML{*datatype tree = 
+    Lf of string 
+  | Br of tree * tree*}
+
+text {*
+  Since nested parentheses should be treated in a meaningful way---for example
+  the string @{text [quotes] "((A))"} should be read into a single 
+  leaf---you might implement the following parser.
+*}
+
+ML{*fun parse_basic s = 
+  $$ s >> Lf 
+  || $$ "(" |-- parse_tree s --| $$ ")"  
+and parse_tree s = 
+  parse_basic s --| $$ "," -- parse_tree s >> Br 
+  || parse_basic s*}
+
+text {*
+  The parameter @{text "s"} is the string over which the tree is parsed. The
+  parser @{ML parse_basic} reads either a leaf or a tree enclosed in
+  parentheses. The parser @{ML parse_tree} reads either a pair of trees
+  separated by a comma, or acts like @{ML parse_basic}. Unfortunately,
+  because of the mutual recursion, this parser will immediately run into a
+  loop, even if it is called without any input. For example
+
+  @{ML_response_fake_both [display, gray]
+  "parse_tree \"A\""
+  "*** Exception- TOPLEVEL_ERROR raised"}
+
+  raises an exception indicating that the stack limit is reached. Such
+  looping parser are not useful at all, because of ML's strict evaluation of
+  arguments. Therefore we need to delay the execution of the
+  parser until an input is given. This can be done by adding the parsed
+  string as an explicit argument.
+*}
+
+ML{*fun parse_basic s xs = 
+  ($$ s >> Lf 
+   || $$ "(" |-- parse_tree s --| $$ ")") xs 
+and parse_tree s xs = 
+  (parse_basic s --| $$ "," -- parse_tree s >> Br 
+   || parse_basic s) xs*}
+
+text {*
+  While the type of the parser is unchanged by the addition, its behaviour 
+  changed: with this version of the parser the execution is delayed until 
+  some string is  applied for the argument @{text "xs"}. This gives us 
+  exactly the parser what we wanted. An example is as follows:
+
+  @{ML_response [display, gray]
+  "let
+  val input = Symbol.explode \"(A,((A))),A\"
+in
+  Scan.finite Symbol.stopper (parse_tree \"A\") input
+end"
+  "(Br (Br (Lf \"A\", Lf \"A\"), Lf \"A\"), [])"}
+
 
   \begin{exercise}\label{ex:scancmts}
   Write a parser that parses an input string so that any comment enclosed
--- a/ProgTutorial/document/root.tex	Sun Nov 15 13:47:31 2009 +0100
+++ b/ProgTutorial/document/root.tex	Tue Nov 17 18:40:11 2009 +0100
@@ -159,6 +159,7 @@
         Stefan & Berghofer\\
         Jasmin & Blanchette\\
         Sascha & Böhme\\
+        Lukas & Bulwahn\\
         Jeremy & Dawson\\
         Alexander & Krauss\\
         Christian & Sternagel\\ 
Binary file progtutorial.pdf has changed