open Scanf

type expr = Var of string        (* only lambda calculus, no ints *)
            | Fun of string * expr
            | Call of expr * expr

let skipspace() = scanf "%_[\t\011\012\r ]" ()

let rec term outer =         (* fun ... -> ... needs () unless outer *)
  skipspace();
  try scanf "(" ();
      let r = expr() in (
        skipspace();
        try scanf ")" (); r
        with End_of_file | Scan_failure _ -> failwith "missing )")
  with Scan_failure _ -> scanf "%[0-9A-Za-z_]" (fun s ->
    if s = "" then failwith "term expected"
    else if s <> "fun" then Var s
    else if outer then (skipspace (); 
                        scanf "%[0-9A-Za-z_]" (fun s ->
                          skipspace(); scanf "->" (); 
                          Fun (s, expr())))
    else failwith "need () around fun _ -> ...")
and expr() =
  let rec restexpr t =
    skipspace();
    scanf "%0c" (function '\n' | ')' -> t | _ -> restexpr (Call (t, term false)))
  in restexpr (term true)

let readexpr () = let e = expr() in scanf "\n" (); e

This document was generated using caml2html