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)
*)