12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879(* The package sedlex is released under the terms of an MIT-like license. *)(* See the attached LICENSE file. *)(* Copyright 2005, 2013 by Alain Frisch and LexiFi. *)(* Character sets are represented as lists of intervals. The
intervals must be non-overlapping and not collapsable, and the list
must be ordered in increasing order. *)typet=(int*int)listletrecrange_to_seqabnext()=ifa=bthenSeq.Cons(a,next)elseSeq.Cons(a,range_to_seq(a+1)bnext)letrecto_seqx()=matchxwith[]->Seq.Nil|(a,b)::xs->range_to_seqab(to_seqxs)()letcheck_invariantl=letrecloopprev=function|[]->()|(a,b)::xs->ifa<prevthenfailwith(Printf.sprintf"Sedlex_cset.of_list: not in increasing order or overlapping. \
[_-%d]-[%d-%d]"prevab);ifa=prevthenfailwith(Printf.sprintf"Sedlex_cset.of_list: adjacent range. [_-%d]-[%d-%d]"prevab);ifa>bthenfailwith(Printf.sprintf"Sedlex_cset.of_list: malformed range. [%d-%d]"ab);loopbxsinloop(-1)lletof_listl=check_invariantl;lletto_listl=lletmax_code=0x10ffff(* must be < max_int *)letmin_code=-1letempty=[]letsingletoni=[(i,i)]letis_empty=function[]->true|_->falseletintervalij=ifi<=jthen[(i,j)]else[(j,i)]leteof=singleton(-1)letany=interval0max_codeletrecunionc1c2=match(c1,c2)with|[],_->c2|_,[]->c1|((i1,j1)ass1)::r1,(i2,j2)::r2->ifi1<=i2thenifj1+1<i2thens1::unionr1c2elseifj1<j2thenunionr1((i1,j2)::r2)elseunionc1r2elseunionc2c1letunion_list:tlist->t=function|[]->empty|[x]->x|l->List.concatl|>List.sort(funab->compareba)|>List.fold_left(fun(acc:t)(x:int*int)->union[x]acc)emptyletcomplementc=letrecauxstart=function|[]->ifstart<=max_codethen[(start,max_code)]else[]|(i,j)::l->(start,i-1)::aux(succj)linmatchcwith(-1,j)::l->aux(succj)l|l->aux(-1)lletintersectionc1c2=complement(union(complementc1)(complementc2))letdifferencec1c2=complement(union(complementc1)c2)