(* Author: René Thiemann <rene.thiemann@uibk.ac.at> *) theory Example_Application imports Xmlt begin text ‹Let us consider inputs that consist of an optional number and a list of first order terms, where these terms use strings as function names and numbers for variables. We assume that we have a XML-document that describes these kinds of inputs and now want to parse them.› definition exampleInput where "exampleInput = STR ''<input> <magicNumber>42</magicNumber> <funapp> <!-- first term in list --> <symbol>fo<>bar</symbol> <var>1</var> <!-- first subterm --> <var>3</var> <!-- second subterm --> </funapp> <var>15</var> <!-- second term in list --> </input>''" datatype fo_term = Fun string "fo_term list" | Var int definition var :: "fo_term xmlt" where "var = xml_change (xml_int (STR ''var'')) (xml_return ∘ Var)" text ‹a recursive parser is best defined via partial-function. Note that the xml-argument should be provided, otherwise strict evalution languages will not terminate.› partial_function (sum_bot) parse_term :: "fo_term xmlt" where [code]: "parse_term xml = ( XMLdo (STR ''funapp'') { name ← xml_text (STR ''symbol''); args ←* parse_term; xml_return (Fun name args) } XMLor var) xml" text ‹for non-recursive parsers, we can eta-contract› definition parse_input :: "(int option × fo_term list) xmlt" where "parse_input = XMLdo (STR ''input'') { onum ←? xml_int (STR ''magicNumber''); terms ←* parse_term; xml_return (onum,terms) }" definition test where "test = parse_xml_string parse_input (String.explode exampleInput)" value test (* successfully parses the example input *) export_code test checking SML end