123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869(******************************************************************************)(* *)(* Menhir *)(* *)(* Copyright Inria. All rights reserved. This file is distributed under *)(* the terms of the GNU Library General Public License version 2, with a *)(* special exception on linking, as described in the file LICENSE. *)(* *)(******************************************************************************)(* The [entry] array contains offsets into the [data] array. It has [n+1]
elements if the original (unencoded) array has [n] elements. The value
of [entry.(n)] is the length of the [data] array. This convention is
natural and allows avoiding a special case. *)type'at=(* data: *)'aarray*(* entry: *)intarrayletmake(a:'aarrayarray):'at=letn=Array.lengthain(* Build the entry array. *)letsize=ref0inletentry=Array.init(n+1)(funi->lets=!sizeinifi<nthensize:=s+Array.lengtha.(i);s)inassert(entry.(n)=!size);(* Build the data array. *)leti=ref0andj=ref0inletdata=Array.init!size(fun_->while!j=Array.lengtha.(!i)doi:=!i+1;j:=0;done;letx=a.(!i).(!j)inj:=!j+1;x)indata,entryletlength((_,entry):'at):int=Array.lengthentryletrow_length((_,entry):'at)i:int=entry.(i+1)-entry.(i)letread((data,entry)asla:'at)ij:'a=assert(0<=j&&j<row_lengthlai);data.(entry.(i)+j)letwrite((data,entry)asla:'at)ij(v:'a):unit=assert(0<=j&&j<row_lengthlai);data.(entry.(i)+j)<-vletrecread_interval_viaget_dataij=ifi=jthen[]elseget_datai::read_interval_viaget_data(i+1)jletread_row_viaget_dataget_entryi=read_interval_viaget_data(get_entryi)(get_entry(i+1))letread_row((data,entry):'at)i:'alist=read_row_via(Array.getdata)(Array.getentry)i