package janala.interpreters; import dk.brics.automaton.Automaton; import dk.brics.automaton.RegExp; import dk.brics.automaton.State; import dk.brics.automaton.Transition; import java.util.IdentityHashMap; import java.util.List; public class RegexpEncoder { public static Constraint getRegexpFormulaString(String regexp, String prefix, int length) { RegExp r = new RegExp(regexp); Automaton a = r.toAutomaton(); length--; if (length == -1) { if (a.getInitialState().isAccept()) { return SymbolicTrueConstraint.instance; } else { return SymbolicFalseConstraint.instance; } } else { return createFormula(a, prefix, length); } } public static Constraint getLengthFormulaString( String regexp, String prefix, int sym, boolean accept) { RegExp r = new RegExp(regexp); Automaton a = r.toAutomaton(); String example = a.getShortestExample(accept); if (example != null) return intCompare( prefix, sym, example.length(), COMPARISON_OPS.GE); else return intCompare(prefix, sym, 0, COMPARISON_OPS.GE); } public static Constraint createFormula(Automaton A, String prefix, int n) { State root = A.getInitialState(); if (n == 0) { if (root.isAccept()) { return SymbolicTrueConstraint.instance; } else { return SymbolicFalseConstraint.instance; } } else { Constraint ret = createFormula(root, prefix, 0, n); return ret == null ? SymbolicFalseConstraint.instance : ret; } } private static Constraint intCompare( String prefix, int sym, int constant, COMPARISON_OPS op) { return new SymbolicIntCompareConstraint(new SymOrInt(prefix + sym), new SymOrInt(constant), op); } private static Constraint andFormula(Constraint f1, Constraint f2) { if (f1 instanceof SymbolicAndConstraint) { return ((SymbolicAndConstraint) f1).AND(f2); } else if (f2 instanceof SymbolicAndConstraint) { return ((SymbolicAndConstraint) f2).AND(f1); } else { return (new SymbolicAndConstraint(f1)).AND(f2); } } private static Constraint orFormula(Constraint f1, Constraint f2) { if (f1 instanceof SymbolicOrConstraint) { return ((SymbolicOrConstraint) f1).OR(f2); } else if (f2 instanceof SymbolicOrConstraint) { return ((SymbolicOrConstraint) f2).OR(f1); } else { return (new SymbolicOrConstraint(f1)).OR(f2); } } public static Constraint createFormula(State root, String prefix, int i, int n) { IdentityHashMap<State, Constraint> ret = new IdentityHashMap<State, Constraint>(); Constraint collect = null; List<Transition> transitions = root.getSortedTransitions(false); for (Transition transition : transitions) { State next = transition.getDest(); Constraint tmp1 = andFormula( intCompare( prefix, i, transition.getMin(), COMPARISON_OPS.GE), intCompare( prefix, i, transition.getMax(), COMPARISON_OPS.LE)); Constraint tmp2 = ret.get(next); if (tmp2 != null) { Constraint tmp3 = orFormula(tmp2, tmp1); ret.put(next, tmp3); } else { ret.put(next, tmp1); } } if (i < n) { for (State next : ret.keySet()) { Constraint suffix = createFormula(next, prefix, i + 1, n); if (suffix != null) { Constraint tmp4 = andFormula(ret.get(next), suffix); if (collect == null) { collect = tmp4; } else { collect = orFormula(collect, tmp4); } } } } else { for (State next : ret.keySet()) { if (next.isAccept()) { if (collect == null) { collect = ret.get(next); } else { collect = orFormula(collect, ret.get(next)); } } } } return collect; } }