001package org.clafer.ast.analysis; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.Comparator; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009import org.clafer.ast.AstAbstractClafer; 010import org.clafer.ast.AstClafer; 011import org.clafer.ast.Card; 012 013/** 014 * 015 * @author jimmy 016 */ 017public class AbstractOffsetAnalyzer implements Analyzer { 018 019 @Override 020 public Analysis analyze(final Analysis analysis) { 021 Map<AstAbstractClafer, Offsets> offsetsMap = new HashMap<>(); 022 for (AstAbstractClafer abstractClafer : analysis.getAbstractClafers()) { 023 Map<AstClafer, Integer> offsets = new HashMap<>(); 024 List<AstClafer> reverseOffsets = new ArrayList<>(); 025 int offset = 0; 026 List<AstClafer> subs = new ArrayList<>(abstractClafer.getSubs()); 027 /* 028 * What is this optimization? 029 * 030 * This optimization is to put more "stable" Clafers near the 031 * beginning, to reduce the number of backtracking for LowGroups. 032 */ 033 Collections.sort(subs, new Comparator<AstClafer>() { 034 @Override 035 public int compare(AstClafer o1, AstClafer o2) { 036 Card card1 = analysis.getGlobalCard(o1); 037 Card card2 = analysis.getGlobalCard(o2); 038 double ratio1 = ((double) card1.getLow() + 1) / ((double) card1.getHigh() + 1); 039 double ratio2 = ((double) card2.getLow() + 1) / ((double) card2.getHigh() + 1); 040 return -Double.compare(ratio1, ratio2); 041 } 042 }); 043 for (AstClafer sub : subs) { 044 offsets.put(sub, offset); 045 int skip = analysis.getScope(sub); 046 for (int i = 0; i < skip; i++) { 047 reverseOffsets.add(sub); 048 } 049 offset += skip; 050 } 051 offsetsMap.put(abstractClafer, new Offsets(abstractClafer, offsets, reverseOffsets.toArray(new AstClafer[reverseOffsets.size()]))); 052 } 053 return analysis.setOffsetMap(offsetsMap); 054 } 055}