/** * Returns a new automaton that accepts strings representing decimal non-negative integers in the * given interval. * * @param min minimal value of interval * @param max maximal value of inverval (both end points are included in the interval) * @param digits if >0, use fixed number of digits (strings must be prefixed by 0's to obtain the * right length) - otherwise, the number of digits is not fixed * @throws IllegalArgumentException if min>max or if numbers in the interval cannot be expressed * with the given fixed number of digits */ public static DefaultAutomaton makeInterval(int min, int max, int digits) throws IllegalArgumentException { DefaultAutomaton a = new DefaultAutomaton(); String x = Integer.toString(min); String y = Integer.toString(max); if (min > max || (digits > 0 && y.length() > digits)) throw new IllegalArgumentException(); int d; if (digits > 0) d = digits; else d = y.length(); StringBuilder bx = new StringBuilder(); for (int i = x.length(); i < d; i++) bx.append('0'); bx.append(x); x = bx.toString(); StringBuilder by = new StringBuilder(); for (int i = y.length(); i < d; i++) by.append('0'); by.append(y); y = by.toString(); Collection<State> initials = new ArrayList<State>(); a.initial = between(x, y, 0, initials, digits <= 0); if (digits <= 0) { ArrayList<StatePair> pairs = new ArrayList<StatePair>(); for (State p : initials) if (a.initial != p) pairs.add(new StatePair(a.initial, p)); addEpsilons(a, pairs); a.initial.addTransition(new Transition('0', a.initial)); a.deterministic = false; } else a.deterministic = true; a.checkMinimizeAlways(); return a; }
/** Returns a new (deterministic) automaton with the empty language. */ public static DefaultAutomaton makeEmpty() { DefaultAutomaton a = new DefaultAutomaton(); State s = new State(); a.initial = s; a.deterministic = true; return a; }
/** Returns a new (deterministic) automaton that accepts all strings. */ public static DefaultAutomaton makeAnyString() { DefaultAutomaton a = new DefaultAutomaton(); State s = new State(); a.initial = s; s.accept = true; s.transitions.add(new Transition(Character.MIN_VALUE, Character.MAX_VALUE, s)); a.deterministic = true; return a; }
/** * Returns a new (deterministic) automaton that accepts a single char whose value is in the given * interval (including both end points). */ public static DefaultAutomaton makeCharRange(char min, char max) { if (min == max) return makeChar(min); DefaultAutomaton a = new DefaultAutomaton(); State s1 = new State(); State s2 = new State(); a.initial = s1; s2.accept = true; if (min <= max) s1.transitions.add(new Transition(min, max, s2)); a.deterministic = true; return a; }
/** Returns a new (deterministic) automaton that accepts a single character in the given set. */ public static DefaultAutomaton makeCharSet(String set) { if (set.length() == 1) return makeChar(set.charAt(0)); DefaultAutomaton a = new DefaultAutomaton(); State s1 = new State(); State s2 = new State(); a.initial = s1; s2.accept = true; for (int i = 0; i < set.length(); i++) s1.transitions.add(new Transition(set.charAt(i), s2)); a.deterministic = true; a.reduce(); return a; }
/** Constructs deterministic automaton that matches strings that contain the given substring. */ public static DefaultAutomaton makeStringMatcher(String s) { DefaultAutomaton a = new DefaultAutomaton(); State[] states = new State[s.length() + 1]; states[0] = a.initial; for (int i = 0; i < s.length(); i++) states[i + 1] = new State(); State f = states[s.length()]; f.accept = true; f.transitions.add(new Transition(Character.MIN_VALUE, Character.MAX_VALUE, f)); for (int i = 0; i < s.length(); i++) { Set<Character> done = new HashSet<Character>(); char c = s.charAt(i); states[i].transitions.add(new Transition(c, states[i + 1])); done.add(c); for (int j = i; j >= 1; j--) { char d = s.charAt(j - 1); if (!done.contains(d) && s.substring(0, j - 1).equals(s.substring(i - j + 1, i))) { states[i].transitions.add(new Transition(d, states[j])); done.add(d); } } char[] da = new char[done.size()]; int h = 0; for (char w : done) da[h++] = w; Arrays.sort(da); int from = Character.MIN_VALUE; int k = 0; while (from <= Character.MAX_VALUE) { while (k < da.length && da[k] == from) { k++; from++; } if (from <= Character.MAX_VALUE) { int to = Character.MAX_VALUE; if (k < da.length) { to = da[k] - 1; k++; } states[i].transitions.add(new Transition((char) from, (char) to, states[0])); from = to + 2; } } } a.deterministic = true; return a; }
/** Returns a new (deterministic) automaton that accepts a single character of the given value. */ public static DefaultAutomaton makeChar(char c) { DefaultAutomaton a = new DefaultAutomaton(); a.singleton = Character.toString(c); a.deterministic = true; return a; }
/** Returns a new (deterministic) automaton that accepts only the empty string. */ public static DefaultAutomaton makeEmptyString() { DefaultAutomaton a = new DefaultAutomaton(); a.singleton = ""; a.deterministic = true; return a; }
/** Returns a new (deterministic) automaton that accepts the single given string. */ public static DefaultAutomaton makeString(String s) { DefaultAutomaton a = new DefaultAutomaton(); a.singleton = s; a.deterministic = true; return a; }