package de.fhro.inf.fp; import java.util.Map; import java.util.Stack; import java.util.StringTokenizer; public class Formula implements UnaryPredicate { /** erlaubte Operationen */ private final static int NOT = 0; private final static int AND = 1; private final static int OR = 2; private final static int PREDICATE = 3; private static int type(String tok) { if (tok.equals("NOT")) return NOT; else if (tok.equals("AND")) return AND; else if (tok.equals("OR")) return OR; else return PREDICATE; } private UnaryPredicate executable; /** * erzeugt ein unäres Prädikat, das beliebig oft ausgeführt werden kann * * @param frm eine Formel in Postfix-Form mit AND, OR und NOT * @param namespace ein Verzeichnis der Praedikate. Die Namen der Praedikate * sind die terminalen Symbole der Formel. */ public Formula(String frm, Map namespace) { executable = compile(frm, namespace); } /** * wendet das unäre Prädikat (die Formel) auf ein Objekt (die Eingabe) an */ public boolean execute(Object obj) { return executable.execute(obj); } /** * wandelt eine Formel in Postfix-Notation in ein unäres Prädikat um * * @return unäres Prädikat das der Formel entspricht */ private UnaryPredicate compile(String frm, Map namespace) { Stack stack = new Stack(); // Stack von unären Prädikaten // hier wuerden sich Generics fuer den Stack anbieten StringTokenizer s = new StringTokenizer(frm); while (s.hasMoreTokens()) { String token = s.nextToken(); switch (type(token)) { case PREDICATE: stack.push(namespace.get(token)); break; case NOT: stack.push(new UnaryNot((UnaryPredicate) stack.pop()) ); break; // break aus der switch anweisung? case AND: stack.push(new UnaryAnd((UnaryPredicate) stack.pop(), (UnaryPredicate) stack.pop()) ); break; case OR: stack.push(new UnaryOr((UnaryPredicate) stack.pop(), (UnaryPredicate) stack.pop()) ); break; } } executable = (UnaryPredicate) stack.pop(); // TODO richtiges return return executable; } }