I'm trying to make the function which takes string and transforms it to boolean expression. For example:for input ((x10+~1)*x132)
it should give times(plus(var 10,compl 1),var 132)
, but it gives times(plus(var #,compl #),var 132)
. Where do hashtags come from??
datatype boolexp = zero
| one
| plus of boolexp * boolexp
| times of boolexp * boolexp
| var of int
| compl of boolexp
exception InvalidInput
(* takes the first n elements *)
fun take (_, 0) = nil
| take (nil, _) = raise InvalidInput
| take (h::t, n) = if n < 0
then raise InvalidInput
else h::take(t, n-1)
(* drops the frist n elements *)
fun drop (xs, 0) = xs
| drop (nil, _) = raise InvalidInput
| drop (h::t,n) = if n < 0
then raise InvalidInput
else drop (t, n-1)
(* converts string to integer *)
fun charlist_to_int (nil) = raise InvalidInput
| charlist_to_int (xs) =
let fun helper_int_rev (nil) = 0
| helper_int_rev (h::t) = if h >= #"0" andalso h <= #"9"
then helper_int_rev t * 10 + (ord h - ord #"0")
else raise InvalidInput
in helper_int_rev (rev xs) end;
(* finds the operator and its position *)
fun searchfor_oper (nil,_,_) = raise InvalidInput
| searchfor_oper (#"("::t, np, pos) = searchfor_oper (t, np+1, pos+1)
| searchfor_oper (#")"::t, np, pos) = searchfor_oper(t, np-1, pos+1)
| searchfor_oper (#"+"::t, 0, pos) = (pos, #"+")
| searchfor_oper (#"*"::t, 0, pos) = (pos, #"*")
| searchfor_oper (h::t, np, pos) = searchfor_oper (t, np, pos+1)
fun beparse_helper (nil) = raise InvalidInput
| beparse_helper (h::t) =
if h = #"x" then if hd(t)= #"0" then raise InvalidInput
else var (charlist_to_int (t))
else if h = #"0" then if t = nil then zero else raise InvalidInput
else if h = #"1" then if t = nil then one else raise InvalidInput
else if h = #"~" then compl(beparse_helper(t))
else if h = #"(" then
let
val lst = if hd (rev t)= #")" then take(t, length(t)-1) else raise InvalidInput
val (pos, oper) = searchfor_oper (lst, 0, 1)
in
if oper = (#"+")
then plus(beparse_helper(take(lst,pos-1)), beparse_helper(drop(lst,pos)))
else if oper = (#"*")
then times(beparse_helper(take(lst,pos-1)),beparse_helper(drop(lst,pos)))
else raise InvalidInput
end
else raise InvalidInput;
fun beparse(s) = beparse_helper(explode(s));
(*TESTING*)
beparse ("((x10+~1)*x132)");