Commit d2864f20 authored by Falko Schumann's avatar Falko Schumann

Interpreter vereinfacht

*   `Handler` und `AbstractHandler` zusammengefasst.
*   Möglichkeiten von Java 7 und 8 genutzt.
*   `Literal` vereinfacht.
parent 27314d1b
/*
* BitCtrl-Funktionsbibliothek
* Copyright (C) 2015 BitCtrl Systems GmbH
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Contact Information:
* BitCtrl Systems GmbH
* Weißenfelser Straße 67
* 04229 Leipzig
* Phone: +49 341-490670
* mailto: info@bitctrl.de
*/
package de.bsvrz.sys.funclib.bitctrl.interpreter;
import java.util.Arrays;
import java.util.List;
/**
* Abstrakte Implementierung eines Handlers zur Ausführung von Operationen.
* Die Klasse implementiert einige Funktionen der Schnittstelle Handler um die
* Implementierung konkreter Handler-Klassen zu erleichtern.
*
* @author BitCtrl Systems GmbH, Peuker, Schumann
* @deprecated Defaultimplementierung und statische Methoden nach {@link Handler} verschoben.
*/
@Deprecated
public abstract class AbstractHandler implements Handler {
}
......@@ -26,9 +26,7 @@
package de.bsvrz.sys.funclib.bitctrl.interpreter;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
/**
* Basisklasse aller Symbole des Interpeters.
......@@ -38,63 +36,34 @@ import java.util.Set;
public interface Ausdruck<T> {
/**
* Behelfsklasse, um ein paar n&uuml;tzliche statische Methoden im Interface
* unterzubringen.
* Bestimmt Rekursiv die Menge der Termsymbole im Ausdruck, die
* Variablen darstellen.
*
* @author BitCtrl Systems GmbH, Schumann
* @param ausdruck
* Ein beliebiger Ausdruck
* @return Menge der Variablennamen
*/
final class Info {
/**
* Bestimmt Rekursiv die Menge der Termsymbole im Ausdruck, die
* Variablen darstellen.
*
* @param ausdruck
* Ein beliebiger Ausdruck
* @return Menge der Variablennamen
*/
public static Set<String> getVariablen(final Ausdruck<?> ausdruck) {
// TODO Als statische Methode von Ausdruck umformulieren
Set<String> variablen;
variablen = new HashSet<>();
if (ausdruck instanceof Variable) {
// Wir sind an einem Termsymbol angekommen, was Variable ist
variablen.add(((Variable) ausdruck).getName());
} else if (ausdruck.getNachfolger() != null) {
// Ausdruck ist kein Terminalsymbol
for (final Ausdruck<?> a : ausdruck.getNachfolger()) {
// Rekursion
variablen.addAll(getVariablen(a));
}
static Set<String> getVariablen(final Ausdruck<?> ausdruck) {
Set<String> variablen = new HashSet<>();
if (ausdruck instanceof Variable) {
variablen.add(((Variable) ausdruck).getName());
} else {
for (final Ausdruck<?> a : ausdruck.getNachfolger()) {
variablen.addAll(getVariablen(a));
}
return variablen;
}
/**
* Konstruktor.
*/
private Info() {
// privater Standardkonstruktor, wird nie verwendet
}
return variablen;
}
/**
* Gibt eine Liste der verschachtelten Ausdr&uuml;cke zur&uuml;ck.
* <p>
* <em>Hinweis:</em> Terminalsymbole liefern keine leere Liste sondern
* {@code null} zur&uuml;ck. Eine leere Liste ist demnach ein Hinweis auf
* einen unvollst&auml;ndigen Syntaxbaum.
*
* @return Liste der Ausdr&uuml;cke <em>direkt</em> unter diesen Ausdruck.
* Die Methode arbeiten im Gegensatz zu {@link #interpret(Kontext)}
* nicht rekursiv.
*/
default List<? extends Ausdruck<?>> getNachfolger() {
// TODO Literal#getNachfolger() sollte nicht null, sondern leere Liste für Terminalsymbole zurüchgeben, damit es sich neutral verhält!
return null;
return Collections.emptyList();
}
/**
......
......@@ -33,11 +33,11 @@ import java.util.*;
* implementieren. Statt jeder Operation eine eigene Klasse zu geben, werden mit
* Hilfe des Musters <em>Besucher</em> alle Operationen in einer Klasse
* geb&uuml;ndelt. Neue Operationen k&ouml;nnen durch implementieren dieser
* Schnittstelle definiert werden. Siehe auch {@link AbstractHandler}
* Schnittstelle definiert werden. Siehe auch {@link Handler}
*
* @author BitCtrl Systems GmbH, Schumann
*/
public interface Handler {
public abstract class Handler {
/**
* Liefert den n-ten Operanden aus einer Liste von Operanden.<br>
......@@ -50,7 +50,7 @@ public interface Handler {
* Der Index des gesuchten Operanden
* @return Den Operand oder {@code null}
*/
static Object getOperand(List<?> operanden, int index) {
public static Object getOperand(List<?> operanden, int index) {
Object ergebnis = null;
if ((operanden != null) && (operanden.size() > index)) {
......@@ -65,7 +65,7 @@ public interface Handler {
*
* @return Liste von Operatoren
*/
Operator[] getHandledOperators();
public abstract Operator[] getHandledOperators();
/**
* F&uuml;hrt eine Operation mit der Liste der Operanden aus. Die Liste der
......@@ -77,7 +77,7 @@ public interface Handler {
* Liste der Operanden
* @return Wert der Operation, abh&auml;ngig von Operator und Operanden
*/
Object perform(Operator operator, List<?> operanden);
public abstract Object perform(Operator operator, List<?> operanden);
/**
* F&uuml;hrt eine Operation mit dem Operanden aus.
......@@ -88,7 +88,7 @@ public interface Handler {
* Operandenliste
* @return Wert der Operation, abh&auml;ngig von Operator und Operand
*/
default Object perform(Operator operator, Object... operanden) {
public Object perform(Operator operator, Object... operanden) {
return perform(operator, Arrays.asList(operanden));
}
......@@ -102,9 +102,7 @@ public interface Handler {
* Liste von Operanden
* @return das Ergebnis der &Uuml;berpr&uuml;fung
*/
HandlerValidation validiereHandler(Operator operator, List<?> operanden);
// TODO Methode validierehandler() sollte nicht public sein, weil sie fehlschlägt bei verschachtelten Ausdrücken: UND(true, ODER(true, false); UND hat nicht zwei Booleans als Operanden
protected abstract HandlerValidation validiereHandler(Operator operator, List<?> operanden);
/**
* Pr&uuml;ft ob der Handler die angegebene Operation auf dem Operanden
......@@ -116,7 +114,7 @@ public interface Handler {
* Operandenliste
* @return das Ergebnis der &Uuml;berpr&uuml;fung
*/
default HandlerValidation validiereHandler(Operator operator, Object... operanden) {
protected HandlerValidation validiereHandler(Operator operator, Object... operanden) {
return validiereHandler(operator, Arrays.asList(operanden));
}
......
......@@ -32,21 +32,9 @@ package de.bsvrz.sys.funclib.bitctrl.interpreter;
* der Typsicherheit innerhalb der Softwareeinheit.
*
* @author BitCtrl Systems GmbH, Uwe Peuker
* @deprecated Das Interface hat keinen Wert und wird auch nicht verwendet.
*/
@Deprecated
public interface Literal<T> extends Ausdruck<T> {
/**
* Gibt den Wert des Literals zur&uuml;ck.
*
* @return Der Wert
* @deprecated Die Methode ist logisch identisch mit {@link #interpret(Kontext)}. Sie wird nie
* verwendet und ist immer <code>return interpret(null);</code> implementiert.
*/
@Deprecated
default T getWert() {
return interpret(null);
}
// tagging interface
}
......@@ -43,4 +43,5 @@ public interface Variable<T> extends Ausdruck<T> {
* @return den Name
*/
String getName();
}
......@@ -30,7 +30,7 @@ import java.util.List;
import com.bitctrl.i18n.Messages;
import de.bsvrz.sys.funclib.bitctrl.interpreter.AbstractHandler;
import de.bsvrz.sys.funclib.bitctrl.interpreter.Handler;
import de.bsvrz.sys.funclib.bitctrl.interpreter.HandlerValidation;
import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterException;
import de.bsvrz.sys.funclib.bitctrl.interpreter.InterpreterMessages;
......@@ -42,7 +42,7 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Operator;
*
* @author BitCtrl Systems GmbH, Schumann
*/
public class LogikHandler extends AbstractHandler {
public class LogikHandler extends Handler {
/** Konjunktion bzw. logisches "und" */
public static final Operator UND = Operator.getOperator("und");
......
......@@ -37,7 +37,7 @@ import de.bsvrz.sys.funclib.bitctrl.interpreter.Literal;
*
* @author BitCtrl Systems GmbH, Falko Schumann
*/
public class LogischesLiteral implements Literal {
public class LogischesLiteral implements Literal<LogischerWert> {
/**
* Repr&auml;sentiert den logischen Wert des Literals.
......@@ -82,28 +82,18 @@ public class LogischesLiteral implements Literal {
* Gibt immer {@code null} zur&uuml;ck, da dies ein Terminalsymbol ist.
*/
@Override
public List<Ausdruck> getNachfolger() {
public List<Ausdruck<?>> getNachfolger() {
return null;
}
/**
* Nennt den Wert des Terminalsymbols.
*
* @return Wert des Literal
*/
@Override
public LogischerWert getWert() {
return wert;
}
@Override
public Object interpret(final Kontext kontext) {
public LogischerWert interpret(final Kontext kontext) {
return wert;
}
@Override
public String toString() {
return getWert().toString();
return wert.toString();
}
}
......@@ -40,9 +40,9 @@ public final class TestInterpreter {
@Test
public void test() {
Ausdruck ausdruck = new Operation(UND,
Ausdruck<?> ausdruck = new Operation<>(UND,
new LogischesLiteral(true),
new Operation(ODER,
new Operation<>(ODER,
new LogischesLiteral(true),
new LogischesLiteral(false)
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment