From bdfd32c24a9956421ea96b2228c2b22f36599825 Mon Sep 17 00:00:00 2001 From: Jonas Neugebauer Date: Sat, 10 Apr 2021 18:05:52 +0200 Subject: [PATCH] Initial commit --- .gitignore | 25 ++++ List.java | 345 ++++++++++++++++++++++++++++++++++++++++++++ README.TXT | 6 + Rechenmaschine.java | 196 +++++++++++++++++++++++++ Token.java | 35 +++++ package.bluej | 52 +++++++ 6 files changed, 659 insertions(+) create mode 100644 .gitignore create mode 100755 List.java create mode 100644 README.TXT create mode 100644 Rechenmaschine.java create mode 100644 Token.java create mode 100644 package.bluej diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3fb81e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# ---> Java +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt +Dokumente* + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/List.java b/List.java new file mode 100755 index 0000000..8c82b92 --- /dev/null +++ b/List.java @@ -0,0 +1,345 @@ + /** + *

+ * Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018 + *

+ *

+ * Generische Klasse List + *

+ *

+ * Objekt der generischen Klasse List verwalten beliebig viele linear + * angeordnete Objekte vom Typ ContentType. Auf hoechstens ein Listenobjekt, + * aktuellesObjekt genannt, kann jeweils zugegriffen werden.
+ * Wenn eine Liste leer ist, vollstaendig durchlaufen wurde oder das aktuelle + * Objekt am Ende der Liste geloescht wurde, gibt es kein aktuelles Objekt.
+ * Das erste oder das letzte Objekt einer Liste koennen durch einen Auftrag zum + * aktuellen Objekt gemacht werden. Ausserdem kann das dem aktuellen Objekt + * folgende Listenobjekt zum neuen aktuellen Objekt werden.
+ * Das aktuelle Objekt kann gelesen, veraendert oder geloescht werden. Ausserdem + * kann vor dem aktuellen Objekt ein Listenobjekt eingefuegt werden. + *

+ * + * @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule + * @version Generisch_06 2015-10-25 + */ +public class List { + + /* --------- Anfang der privaten inneren Klasse -------------- */ + + private class ListNode { + + private ContentType contentObject; + private ListNode next; + + /** + * Ein neues Objekt wird erschaffen. Der Verweis ist leer. + * + * @param pContent das Inhaltsobjekt vom Typ ContentType + */ + private ListNode(ContentType pContent) { + contentObject = pContent; + next = null; + } + + /** + * Der Inhalt des Knotens wird zurueckgeliefert. + * + * @return das Inhaltsobjekt des Knotens + */ + public ContentType getContentObject() { + return contentObject; + } + + /** + * Der Inhalt dieses Kontens wird gesetzt. + * + * @param pContent das Inhaltsobjekt vom Typ ContentType + */ + public void setContentObject(ContentType pContent) { + contentObject = pContent; + } + + /** + * Der Nachfolgeknoten wird zurueckgeliefert. + * + * @return das Objekt, auf das der aktuelle Verweis zeigt + */ + public ListNode getNextNode() { + return this.next; + } + + /** + * Der Verweis wird auf das Objekt, das als Parameter uebergeben + * wird, gesetzt. + * + * @param pNext der Nachfolger des Knotens + */ + public void setNextNode(ListNode pNext) { + this.next = pNext; + } + + } + + /* ----------- Ende der privaten inneren Klasse -------------- */ + + // erstes Element der Liste + ListNode first; + + // letztes Element der Liste + ListNode last; + + // aktuelles Element der Liste + ListNode current; + + /** + * Eine leere Liste wird erzeugt. + */ + public List() { + first = null; + last = null; + current = null; + } + + /** + * Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthaelt, + * sonst liefert sie den Wert false. + * + * @return true, wenn die Liste leer ist, sonst false + */ + public boolean isEmpty() { + // Die Liste ist leer, wenn es kein erstes Element gibt. + return first == null; + } + + /** + * Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt, + * sonst liefert sie den Wert false. + * + * @return true, falls Zugriff moeglich, sonst false + */ + public boolean hasAccess() { + // Es gibt keinen Zugriff, wenn current auf kein Element verweist. + return current != null; + } + + /** + * Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses + * nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in + * der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach + * Ausfuehrung des Auftrags kein aktuelles Objekt, d.h. hasAccess() liefert + * den Wert false. + */ + public void next() { + if (this.hasAccess()) { + current = current.getNextNode(); + } + } + + /** + * Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles + * Objekt. Ist die Liste leer, geschieht nichts. + */ + public void toFirst() { + if (!isEmpty()) { + current = first; + } + } + + /** + * Falls die Liste nicht leer ist, wird das letzte Objekt der Liste + * aktuelles Objekt. Ist die Liste leer, geschieht nichts. + */ + public void toLast() { + if (!isEmpty()) { + current = last; + } + } + + /** + * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das + * aktuelle Objekt zurueckgegeben, andernfalls (hasAccess() == false) gibt + * die Anfrage den Wert null zurueck. + * + * @return das aktuelle Objekt (vom Typ ContentType) oder null, wenn es + * kein aktuelles Objekt gibt + */ + public ContentType getContent() { + if (this.hasAccess()) { + return current.getContentObject(); + } else { + return null; + } + } + + /** + * Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent + * ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst + * geschieht nichts. + * + * @param pContent + * das zu schreibende Objekt vom Typ ContentType + */ + public void setContent(ContentType pContent) { + // Nichts tun, wenn es keinen Inhalt oder kein aktuelles Element gibt. + if (pContent != null && this.hasAccess()) { + current.setContentObject(pContent); + } + } + + /** + * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues + * Objekt vor dem aktuellen Objekt in die Liste eingefuegt. Das aktuelle + * Objekt bleibt unveraendert.
+ * Wenn die Liste leer ist, wird pContent in die Liste eingefuegt und es + * gibt weiterhin kein aktuelles Objekt (hasAccess() == false).
+ * Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste + * nicht leer ist oder pContent gleich null ist, geschieht nichts. + * + * @param pContent + * das einzufuegende Objekt vom Typ ContentType + */ + public void insert(ContentType pContent) { + if (pContent != null) { // Nichts tun, wenn es keinen Inhalt gibt. + if (this.hasAccess()) { // Fall: Es gibt ein aktuelles Element. + + // Neuen Knoten erstellen. + ListNode newNode = new ListNode(pContent); + + if (current != first) { // Fall: Nicht an erster Stelle einfuegen. + ListNode previous = this.getPrevious(current); + newNode.setNextNode(previous.getNextNode()); + previous.setNextNode(newNode); + } else { // Fall: An erster Stelle einfuegen. + newNode.setNextNode(first); + first = newNode; + } + + } else { //Fall: Es gibt kein aktuelles Element. + + if (this.isEmpty()) { // Fall: In leere Liste einfuegen. + + // Neuen Knoten erstellen. + ListNode newNode = new ListNode(pContent); + + first = newNode; + last = newNode; + } + + } + } + } + + /** + * Falls pContent gleich null ist, geschieht nichts.
+ * Ansonsten wird ein neues Objekt pContent am Ende der Liste eingefuegt. + * Das aktuelle Objekt bleibt unveraendert.
+ * Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefuegt + * und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false). + * + * @param pContent + * das anzuhaengende Objekt vom Typ ContentType + */ + public void append(ContentType pContent) { + if (pContent != null) { // Nichts tun, wenn es keine Inhalt gibt. + + if (this.isEmpty()) { // Fall: An leere Liste anfuegen. + this.insert(pContent); + } else { // Fall: An nicht-leere Liste anfuegen. + + // Neuen Knoten erstellen. + ListNode newNode = new ListNode(pContent); + + last.setNextNode(newNode); + last = newNode; // Letzten Knoten aktualisieren. + } + + } + } + + /** + * Falls es sich bei der Liste und pList um dasselbe Objekt handelt, + * pList null oder eine leere Liste ist, geschieht nichts.
+ * Ansonsten wird die Liste pList an die aktuelle Liste angehaengt. + * Anschliessend wird pList eine leere Liste. Das aktuelle Objekt bleibt + * unveraendert. Insbesondere bleibt hasAccess identisch. + * + * @param pList + * die am Ende anzuhaengende Liste vom Typ List + */ + public void concat(List pList) { + if (pList != this && pList != null && !pList.isEmpty()) { // Nichts tun, + // wenn pList und this identisch, pList leer oder nicht existent. + + if (this.isEmpty()) { // Fall: An leere Liste anfuegen. + this.first = pList.first; + this.last = pList.last; + } else { // Fall: An nicht-leere Liste anfuegen. + this.last.setNextNode(pList.first); + this.last = pList.last; + } + + // Liste pList loeschen. + pList.first = null; + pList.last = null; + pList.current = null; + } + } + + /** + * Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess() + * == false), geschieht nichts.
+ * Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das + * aktuelle Objekt geloescht und das Objekt hinter dem geloeschten Objekt + * wird zum aktuellen Objekt.
+ * Wird das Objekt, das am Ende der Liste steht, geloescht, gibt es kein + * aktuelles Objekt mehr. + */ + public void remove() { + // Nichts tun, wenn es kein aktuelle Element gibt oder die Liste leer ist. + if (this.hasAccess() && !this.isEmpty()) { + + if (current == first) { + first = first.getNextNode(); + } else { + ListNode previous = this.getPrevious(current); + if (current == last) { + last = previous; + } + previous.setNextNode(current.getNextNode()); + } + + ListNode temp = current.getNextNode(); + current.setContentObject(null); + current.setNextNode(null); + current = temp; + + //Beim loeschen des letzten Elements last auf null setzen. + if (this.isEmpty()) { + last = null; + } + } + } + + /** + * Liefert den Vorgaengerknoten des Knotens pNode. Ist die Liste leer, pNode + * == null, pNode nicht in der Liste oder pNode der erste Knoten der Liste, + * wird null zurueckgegeben. + * + * @param pNode + * der Knoten, dessen Vorgaenger zurueckgegeben werden soll + * @return der Vorgaenger des Knotens pNode oder null, falls die Liste leer ist, + * pNode == null ist, pNode nicht in der Liste ist oder pNode der erste Knoten + * der Liste ist + */ + private ListNode getPrevious(ListNode pNode) { + if (pNode != null && pNode != first && !this.isEmpty()) { + ListNode temp = first; + while (temp != null && temp.getNextNode() != pNode) { + temp = temp.getNextNode(); + } + return temp; + } else { + return null; + } + } + +} diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..6bc8e68 --- /dev/null +++ b/README.TXT @@ -0,0 +1,6 @@ + 04 Rechenmaschine +=================== + +Autor: J. Neugebauer +Erstellt: 10.04.2021 +Version: 0.0.1 diff --git a/Rechenmaschine.java b/Rechenmaschine.java new file mode 100644 index 0000000..010d154 --- /dev/null +++ b/Rechenmaschine.java @@ -0,0 +1,196 @@ +import java.util.Scanner; + +/** + * Hauptklasse des Projekts + */ +public class Rechenmaschine { + + public static void main(String[] args) { + new Rechenmaschine(); + } + + private List tokenlist; + + private String fehler; + + private int result; + + public Rechenmaschine() { + tokenlist = new List<>(); + + Scanner input = new Scanner(System.in); + System.out.println("Gib einen Plusterm ein und bestätige mit ENTER: "); + String eingabe = input.nextLine(); + input.close(); + + if( !scanne(eingabe) ) { + System.out.println("Fehler bei der lexikalischen Analyse:"); + System.out.println(fehler); + return; + } + + if( !parse() ) { + System.out.println("Fehler bei der syntaktischen Analyse:"); + System.out.println(fehler); + return; + } + + run(); + System.out.println("Ergebnis der Ausführung: " + result); + } + + public boolean scanne( String pEingabe ) { + char[] eingabe = pEingabe.toCharArray(); + + int state = 0; + String currentToken = ""; + + for( char buchstabe: eingabe ) { + switch( state ) { + case 0: + switch( buchstabe ) { + case '0': + tokenlist.append(new Token("OPERAND", "0")); + state = 2; + break; + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + currentToken += buchstabe; + state = 1; + break; + + case '+': + fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht mit + beginnen!"; + return false; + + default: + fehler = "Fehler im Wort " +pEingabe+ ":\nDer Buchstabe " + buchstabe + " gehört nicht zur Sprache!"; + return false; + } + break; + + + case 1: + switch( buchstabe ) { + case '+': + tokenlist.append(new Token("OPERAND", currentToken)); + currentToken = ""; + tokenlist.append(new Token("OPERATOR")); + state = 0; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + currentToken += buchstabe; + state = 1; + break; + + default: + fehler = "Fehler im Wort " +pEingabe+ ":\nDer Buchstabe " + buchstabe + " gehört nicht zur Sprache!"; + return false; + } + break; + + + case 2: + switch( buchstabe ) { + case '+': + tokenlist.append(new Token("OPERATOR")); + state = 0; + break; + + default: + fehler = "Fehler im Wort " +pEingabe+ ":\nNach 0 am Anfang muss ein + folgen!"; + return false; + } + break; + } + } + + if( state == 0 ) { + fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht auf + enden!"; + return false; + } else { + tokenlist.append(new Token("OPERAND", currentToken)); + return true; + } + } + + public boolean parse() { + + int state = 0; + + tokenlist.toFirst(); + while( tokenlist.hasAccess() ) { + Token currentToken = tokenlist.getContent(); + + switch( state ) { + case 0: + if( currentToken.getType().equals("OPERATOR") ) { + fehler = "Rechenterm darf nicht mit einem Operator starten!"; + return false; + } else if( currentToken.getType().equals("OPERAND") ) { + state = 1; + } else { + fehler = "Unbekanntes Token: "+currentToken.getType(); + return false; + } + break; + + + case 1: + if( currentToken.getType().equals("OPERATOR") ) { + state = 0; + } else if( currentToken.getType().equals("OPERAND") ) { + fehler = "Auf einen Operanden muss ein Operator folgen!"; + return false; + } else { + fehler = "Unbekanntes Token: "+currentToken.getType(); + return false; + } + break; + } + + tokenlist.next(); + } + + if( state == 0 ) { + fehler = "Ein Rechenterm darf nicht auf einen Operator enden!"; + return false; + } else { + return true; + } + } + + public void run() { + result = 0; + + tokenlist.toFirst(); + while( tokenlist.hasAccess() ) { + Token currentToken = tokenlist.getContent(); + + if( currentToken.getType().equals("OPERAND") ) { + result += Integer.parseInt(currentToken.getToken()); + } + + tokenlist.next(); + } + } + +} diff --git a/Token.java b/Token.java new file mode 100644 index 0000000..1cb033b --- /dev/null +++ b/Token.java @@ -0,0 +1,35 @@ + + +public class Token { + + private String type; + + private String token; + + public Token(String pType) { + type = pType; + token = null; + } + + public Token(String pType, String pToken) { + type = pType; + token = pToken; + } + + public String getType() { + return type; + } + + public void setType(String pType) { + type = pType; + } + + public String getToken() { + return token; + } + + public void setToken(String pToken) { + token = pToken; + } + +} diff --git a/package.bluej b/package.bluej new file mode 100644 index 0000000..87ec5df --- /dev/null +++ b/package.bluej @@ -0,0 +1,52 @@ +#BlueJ package file +dependency1.from=Rechenmaschine +dependency1.to=List +dependency1.type=UsesDependency +dependency2.from=Rechenmaschine +dependency2.to=Token +dependency2.type=UsesDependency +editor.fx.0.height=738 +editor.fx.0.width=816 +editor.fx.0.x=466 +editor.fx.0.y=146 +objectbench.height=66 +objectbench.width=1256 +package.divider.horizontal=0.6 +package.divider.vertical=0.9099876695437731 +package.editor.height=731 +package.editor.width=1157 +package.editor.x=100 +package.editor.y=25 +package.frame.height=875 +package.frame.width=1296 +package.numDependencies=2 +package.numTargets=3 +package.showExtends=true +package.showUses=true +project.charset=UTF-8 +readme.height=58 +readme.name=@README +readme.width=47 +readme.x=10 +readme.y=10 +target1.height=50 +target1.name=List +target1.showInterface=false +target1.type=ClassTarget +target1.width=130 +target1.x=300 +target1.y=70 +target2.height=50 +target2.name=Token +target2.showInterface=false +target2.type=ClassTarget +target2.width=80 +target2.x=70 +target2.y=70 +target3.height=50 +target3.name=Rechenmaschine +target3.showInterface=false +target3.type=ClassTarget +target3.width=120 +target3.x=170 +target3.y=210