let numberQ s = try (int_of_string s; true) with _ -> false;; let symbolQ s = true;; (* How should this be defined? *) let rec ae_Q a = match a with [] -> false | x::xs -> (if numberQ x then match xs with [] -> true | x::xs -> ((x = "+") & (ae_Q xs)) else false);;
type exp = Num of int | Var of string | App of exp*exp | Proc of string*exp;; exception ParserError of string;; let rec parse stream = match stream with [] -> raise (ParserError "Reached EOF unexpectedly") | token::stream -> let (result,stream) = parse_exp token stream in (match stream with [] -> result | _ -> raise (ParserError ("unexpected input" ^ token))) and parse_exp token stream = match token with x when (numberQ x) -> (Num (int_of_string token), stream) | "(" -> (match stream with | [] -> raise (ParserError "No closing paren") | token::stream -> if token = "lambda" then parse_proc stream else parse_app token stream) | x when (symbolQ x) -> (Var x, stream) | _ -> raise (ParserError "Unrgonised token") and parse_proc stream = match stream with bound_var::token::stream -> if symbolQ bound_var then let (body,rest) = parse_exp token stream in (match rest with ")"::stream -> (Proc (bound_var, body), stream) | _ -> raise (ParserError "Unexpected input at end of proc")) else raise (ParserError "Bad variable in lambda") and parse_app rator_first stream = let (rator, rest) = parse_exp rator_first stream in match stream with rand_first:: stream -> let (rand, rest) = parse_exp rand_first stream in (match stream with ")"::stream -> (App (rator, rand), stream) | _ -> raise (ParserError "Application too long")) (* Example: # parse ["(";"f";"1";")"];; - : exp = App (Var "f", Num 1) *)