// Matching (), [] and {} open System;; let argv = Environment.GetCommandLineArgs(); // argv[2] is first command line arg let input = argv[2] let rec matching(stack,index,errs) = if index>=input.Length then check_stack stack errs else match (stack,input[index]) with | (_, '(') -> matching(('(',index)::stack, index+1, errs) | (_, '[') -> matching(('[',index)::stack, index+1, errs) | (_, '{') -> matching(('{',index)::stack, index+1, errs) | (('(',_)::s, ')') | (('[',_)::s, ']') | (('{',_)::s, '}') -> matching(s,index+1,errs) | ((a,i)::b, ')') -> printfn "mismatched %c and ) at indices %d and %d" a i index matching(b,index+1,errs+1) | ((a,i)::b, ']') -> printfn "mismatched %c and ] at indices %d and %d" a i index matching(b,index+1,errs+1) | ((a,i)::b, '}') -> printfn "mismatched %c and } at indices %d and %d" a i index matching(b,index+1,errs+1) | ([], ')') -> printfn "unmatched ) at index %d" index matching([],index+1,errs+1) | ([], ']') -> printfn "unmatched ] at index %d" index matching([],index+1,errs+1) | ([], '}') -> printfn "unmatched } at index %d" index matching([],index+1,errs+1) | (_, x) -> matching(stack,index+1,errs) // skip all other chars and check_stack stack errs = match stack with | [] -> if errs=0 then printfn "All brackets match" else printfn "There were %d errors" errs | ('(',i)::s -> printfn "unmatched ( at index %d" i; check_stack s (errs+1) | ('[',i)::s -> printfn "unmatched [ at index %d" i; check_stack s (errs+1) | ('{',i)::s -> printfn "unmatched { at index %d" i; check_stack s (errs+1) | a::b -> check_stack b errs;; matching([],0,0)