Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file sedlex.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141(* 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. *)moduleCset=Sedlex_cset(* NFA *)typenode={id:int;mutableeps:nodelist;mutabletrans:(Cset.t*node)list;}(* Compilation regexp -> NFA *)typeregexp=node->nodeletcur_id=ref0letnew_node()=incrcur_id;{id=!cur_id;eps=[];trans=[]}letseqr1r2succ=r1(r2succ)letis_charsfinal=function|{eps=[];trans=[(c,f)]}whenf==final->Somec|_->Noneletcharscsucc=letn=new_node()inn.trans<-[(c,succ)];nletaltr1r2succ=letnr1=r1succandnr2=r2succinmatch(is_charssuccnr1,is_charssuccnr2)with|Somec1,Somec2->chars(Cset.unionc1c2)succ|_->letn=new_node()inn.eps<-[nr1;nr2];nletreprsucc=letn=new_node()inn.eps<-[rn;succ];nletplusrsucc=letn=new_node()inletnr=rninn.eps<-[nr;succ];nrletepssucc=succ(* eps for epsilon *)letcomplr=letn=new_node()inmatchis_charsn(rn)with|Somec->Some(chars(Cset.differenceCset.anyc))|_->Noneletpair_opfr0r1=(* Construct subtract or intersection *)letn=new_node()inletto_charsr=is_charsn(rn)inmatch(to_charsr0,to_charsr1)with|Somec0,Somec1->Some(chars(fc0c1))|_->Noneletsubtract=pair_opCset.differenceletintersection=pair_opCset.intersectionletcompile_rere=letfinal=new_node()in(refinal,final)(* Determinization *)typestate=nodelist(* A state of the DFA corresponds to a set of nodes in the NFA. *)letrecadd_nodestatenode=ifList.memqnodestatethenstateelseadd_nodes(node::state)node.epsandadd_nodesstatenodes=List.fold_leftadd_nodestatenodeslettransition(state:state)=(* Merge transition with the same target *)letrecnorm=function|(c1,n1)::((c2,n2)::qasl)->ifn1==n2thennorm((Cset.unionc1c2,n1)::q)else(c1,n1)::norml|l->linlett=List.concat(List.map(funn->n.trans)state)inlett=norm(List.sort(fun(_,n1)(_,n2)->n1.id-n2.id)t)in(* Split char sets so as to make them disjoint *)letsplit(all,t)(c0,n0)=lett=(Cset.differencec0all,[n0])::List.map(fun(c,ns)->(Cset.intersectioncc0,n0::ns))t@List.map(fun(c,ns)->(Cset.differencecc0,ns))tin(Cset.unionallc0,List.filter(fun(c,_)->not(Cset.is_emptyc))t)inlet_,t=List.fold_leftsplit(Cset.empty,[])tin(* Epsilon closure of targets *)lett=List.map(fun(c,ns)->(c,add_nodes[]ns))tin(* Canonical ordering *)lett=Array.of_listtinArray.sort(fun(c1,_)(c2,_)->comparec1c2)t;tletcompilers=letrs=Array.mapcompile_rersinletcounter=ref0inletstates=Hashtbl.create31inletstates_def=Hashtbl.create31inletrecauxstate=tryHashtbl.findstatesstatewithNot_found->leti=!counterinincrcounter;Hashtbl.addstatesstatei;lettrans=transitionstateinlettrans=Array.map(fun(p,t)->(p,auxt))transinletfinals=Array.map(fun(_,f)->List.memqfstate)rsinHashtbl.addstates_defi(trans,finals);iinletinit=ref[]inArray.iter(fun(i,_)->init:=add_node!initi)rs;leti=aux!initinassert(i=0);Array.init!counter(Hashtbl.findstates_def)