E -> T | T + E | T - E T -> F | F * T | F / T F -> id | (E) type token = Id of string | LParen | RParen | Times | Divide | Plus | Minus;; type e = E2T of t | PlusExp of (t*e) | MinusExp of (t*e) and t = T2F of f | MultExp of (f*t) | DivExp of (f*t) and f = I of string | ParenExp of e;; let rec e_parse tokens = match (t_parse tokens) with (term, tok_after_term) -> (match tok_after_term with Plus :: tok_after_plus -> (match (e_parse tok_after_plus) with (e, tok_after_e) -> (PlusExp (term, e), tok_after_e)) | Minus::tok_after_minus -> (match (e_parse tok_after_minus) with (e, tok_after_e) -> (MinusExp (term, e), tok_after_e)) | _ -> (E2T term, tok_after_term)) | _ -> failwith "Error 1" and t_parse tokens = match (f_parse tokens) with (f, tok_after_f) -> (match tok_after_f with Times :: tok_after_times -> (match (t_parse tok_after_times) with (t, tok_after_t) -> (MultExp (f, t), tok_after_t)) | Divide::tok_after_div -> (match (t_parse tok_after_div) with (t, tok_after_t) -> (DivExp (f, t), tok_after_t)) | _ -> (T2F f, tok_after_f)) | _ -> failwith "Error 2" and f_parse tokens = match tokens with Id s :: tok_after_id -> (I s, tok_after_id) | LParen::tok_after_lparen -> (match (e_parse tok_after_lparen) with (e, tok_after_e) -> (match tok_after_e with RParen::tok_after_rparen -> (ParenExp e, tok_after_rparen) | _ -> failwith "Error 3") | _ -> failwith "Error 4" ) | _ -> failwith "Error 5";; [LParen;Id "x"; Times; Id "y";RParen]