UNPKG

tscc-compiler

Version:

An LALR(1) compiler compiler written in Typescript

96 lines (89 loc) 2.71 kB
export interface Table{ readonly rows: number; readonly columns: number; isEmpty(i: number,j: number): boolean; emptyCount(row: number): number; } function sorter(cmp: (a: RowEntry, b: RowEntry) => number){ var a: RowEntry[] = []; function insert(i,obj){ a.push(null); for(var j = a.length - 1;j > i;j--){ a[j] = a[j - 1]; } a[i] = obj; } return { add(b: RowEntry): void{ var i: number; for(i = 0;i < a.length;i++){ if((i === 0 || cmp(b,a[i - 1]) >= 0) && cmp(b,a[i]) <= 0){ break; } } insert(i,b); }, done(): RowEntry[]{ return a; } }; } class RowEntry{ public dp: number | null = 0; constructor(public emptyCount: number, public row: number){} } /** * implementation of double displacement first-fit-decreasing method */ export function compress(source: Table): { dps: number[], len: number }{ function empty(i: number, j: number): boolean{ j = j - sorted[i].dp; return j < 0 || j >= source.columns || source.isEmpty(sorted[i].row,j); } function fit(i: number, dp: number): boolean{ for(var j = 0;j < source.columns;j++){ if(!empty(i,j)){ for(var k = 0;k < i;k++){ if(!empty(k,j + dp)){ return false; } } } } return true; } function getFitdp(i: number): number{ var dp = 0; while(-dp < source.columns && source.isEmpty(sorted[i].row,-dp)){ dp--; } while(!fit(i,dp)){ dp++; } return dp; } var tmpsorted = sorter((a, b) => { return a.emptyCount < b.emptyCount ? -1 : a.emptyCount > b.emptyCount ? 1 : 0; }); for(var i = 0;i < source.rows;i++){ tmpsorted.add(new RowEntry(source.emptyCount(i),i)); } var sorted = tmpsorted.done(); //the row with least empty entries has displacement 0 var maxdp = 0, mindp = 0; var dps = new Array(source.rows); let initDp = 0; while(-initDp < source.columns && source.isEmpty(sorted[0].row, -initDp)){ initDp--; } dps[sorted[0].row] = sorted[0].dp = initDp; for(var i = 1;i < sorted.length;i++){ let row = sorted[i].row; let dp = getFitdp(i); dps[row] = sorted[i].dp = dp; dp > maxdp && (maxdp = dp); dp < mindp && (mindp = dp); } // for(var i = 0;i < dps.length;i++){ // dps[i] -= mindp; // } return { dps: dps, len: maxdp + source.columns// - mindp }; }