diff --git a/Rechenmaschine.java b/Rechenmaschine.java index 23c35e0..84261b7 100644 --- a/Rechenmaschine.java +++ b/Rechenmaschine.java @@ -15,6 +15,8 @@ public class Rechenmaschine { private double result; + private int klammern; + public Rechenmaschine() { tokenlist = new List<>(); @@ -47,7 +49,7 @@ public class Rechenmaschine { public boolean scanne( String pEingabe ) { char[] eingabe = pEingabe.toCharArray(); - + klammern = 0; int state = 0; StringBuilder currentToken = new StringBuilder(); for(char buchstabe: eingabe){ @@ -70,6 +72,15 @@ public class Rechenmaschine { System.out.println("Der Term darf nicht mir mit dem Operator " + buchstabe + " beginnen."); return false; } + case '(' -> { + tokenlist.append(new Token("PARANTHESES",Character.toString(buchstabe))); + state = 6; + klammern++; + } + case ')' -> { + System.out.println("Der Term darf nicht mit ) beginnen"); + return false; + } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; @@ -78,6 +89,10 @@ public class Rechenmaschine { break; case 1: switch (buchstabe) { + case '0','1', '2', '3', '4', '5', '6', '7', '8', '9' -> { + System.out.println("Wenn eine 0 am anfang eines Operands ist, muss ein . folgen."); + return false; + } case '.' -> { currentToken.append(buchstabe); state = 3; @@ -88,6 +103,17 @@ public class Rechenmaschine { tokenlist.append(new Token("OPERATOR", Character.toString(buchstabe))); state = 5; } + case ')' -> { + tokenlist.append(new Token("OPERAND",currentToken.toString())); + currentToken = new StringBuilder(); + tokenlist.append(new Token("PARANTHESES",")")); + state = 7; + klammern--; + } + case '(' -> { + System.out.println("Mach einem Operand darf nicht unmittelbar ein ( folgen"); + return false; + } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; @@ -110,6 +136,17 @@ public class Rechenmaschine { tokenlist.append(new Token("OPERATOR", Character.toString(buchstabe))); state = 5; } + case ')' -> { + tokenlist.append(new Token("OPERAND",currentToken.toString())); + currentToken = new StringBuilder(); + tokenlist.append(new Token("PARANTHESES",")")); + state = 7; + klammern--; + } + case '(' -> { + System.out.println("Nach einem Operand darf nicht unmittelbar ein ( folgen."); + return false; + } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; @@ -122,8 +159,8 @@ public class Rechenmaschine { currentToken.append(buchstabe); state = 4; } - case '+', '-', '*', '/' -> { - System.out.println("Nach einem . darf kein Rechenoperator folgen"); + case '+', '-', '*', '/', '(', ')' -> { + System.out.println("Nach einem . darf kein Rechenoperator, oder eine Klammer folgen"); return false; } } @@ -144,6 +181,21 @@ public class Rechenmaschine { System.out.println("Eine Dezimalzahl kann nur ein . haben."); return false; } + case ')' -> { + tokenlist.append(new Token("OPERAND",currentToken.toString())); + currentToken = new StringBuilder(); + tokenlist.append(new Token("PARANTHESES",Character.toString(buchstabe))); + state = 7; + klammern--; + } + case '(' -> { + System.out.println("Nach einem Operand darf nicht unmittelbar ein ( folgen."); + return false; + } + default -> { + System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); + return false; + } } break; case 5: @@ -164,6 +216,59 @@ public class Rechenmaschine { System.out.println("Nach einem Operator darf nicht direkt ein weiterer Operator folgen."); return false; } + case '(' -> { + tokenlist.append(new Token("PARANTHESES","(")); + state = 6; + klammern++; + } + case ')' -> { + System.out.println("Nach einem Operator darf kein ) folgen."); + return false; + } + default -> { + System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); + return false; + } + } + break; + case 6: + switch(buchstabe) { + case '0' -> { + currentToken.append(buchstabe); + state = 1; + } + case '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { + currentToken.append(buchstabe); + state = 2; + } + case '+', '-', '*', '/' -> { + System.out.println("Unmittelbar nach ( darf kein Operator oder ) folgen."); + return false; + } + case '(' -> { + tokenlist.append(new Token("PARANTHESES",Character.toString(buchstabe))); + klammern++; + } + default -> { + System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); + return false; + } + } + break; + case 7: + switch(buchstabe) { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '(' -> { + System.out.println("Nach ) muss ein Operator folgen"); + return false; + } + case '+', '-', '*', '/' -> { + tokenlist.append(new Token("OPERATOR",Character.toString(buchstabe))); + state = 5; + } + case ')' -> { + tokenlist.append(new Token("PARANTHESES",Character.toString(buchstabe))); + klammern--; + } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; @@ -176,11 +281,21 @@ public class Rechenmaschine { if( state == 5 ) { fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht mit einem Operator enden!"; return false; - } else if (state == 3){ - fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht mit einem Operator enden!"; + } else if (state == 3){ + fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht mit einem . enden!"; + return false; + } else if (state ==6){ + fehler = "Fehler im Wort " +pEingabe+ ":\nDas Wort darf nicht mit ( enden!"; + return false; + } else if (klammern !=0){ + fehler = "Fehler im Wort " +pEingabe+ ":\nIm wort müssen alle Klammern geschlossen sein!"; return false; } else { - tokenlist.append(new Token("OPERAND", currentToken.toString())); + tokenlist.toLast(); + if(!tokenlist.getContent().getToken().equals(")")){ + tokenlist.append(new Token("OPERAND", currentToken.toString())); + return true; + } return true; } } @@ -201,6 +316,12 @@ public class Rechenmaschine { } else if( currentToken.getType().equals("OPERAND") ) { state = 1; break; + } else if( currentToken.getToken().equals("(")){ + state = 0; + break; + } else if( currentToken.getToken().equals(")")){ + state = 1; + break; } else { fehler = "Unbekanntes Token: "+currentToken.getType(); return false; @@ -213,8 +334,13 @@ public class Rechenmaschine { state = 0; break; } else if( currentToken.getType().equals("OPERAND") ) { - fehler = "Auf einen Operanden muss ein Operator folgen!"; + fehler = "Auf einen Operanden darf kein Operand folgen!"; return false; + } else if( currentToken.getToken().equals("(") ) { + fehler = "Auf einen Operanden kann kein ( folgen"; + return false; + } else if( currentToken.getToken().equals(")")) { + state = 1; } else { fehler = "Unbekanntes Token: "+currentToken.getType(); return false; @@ -248,55 +374,140 @@ public class Rechenmaschine { return true; } - public void punktVorStrich(){ - tokenlist.toFirst(); - while(tokenlist.hasAccess()){ - if(tokenlist.getContent().getToken().equals("*")){ - tokenlist.remove(); - Double a = Double.parseDouble(tokenlist.getContent().getToken()); + private void punktVorStrich(ListpList){ + pList.toFirst(); + while(pList.hasAccess()){ + if(pList.getContent().getToken().equals("*")){ + pList.remove(); + Double faktor1 = Double.parseDouble(pList.getContent().getToken()); - tokenlist.current=tokenlist.getPrevious(tokenlist.current); - Double b = Double.parseDouble(tokenlist.getContent().getToken()); + pList.current=pList.getPrevious(pList.current); + Double faktor2 = Double.parseDouble(pList.getContent().getToken()); - tokenlist.remove(); + pList.remove(); - tokenlist.getContent().setToken(String.valueOf(a*b)); - } else if(tokenlist.getContent().getToken().equals("/")){ - tokenlist.remove(); + pList.getContent().setToken(String.valueOf(faktor2*faktor1)); + } else if(pList.getContent().getToken().equals("/")){ + pList.remove(); - Double b = Double.parseDouble(tokenlist.getContent().getToken()); + Double divisor = Double.parseDouble(pList.getContent().getToken()); - //Previous muss gelöscht werden, tokenlist.getContent != null ist, + //Previous Token muss gelöscht werden, tokenlist.getContent != null ist, // wenn der 2. Token am ende des Termes ist. - tokenlist.current=tokenlist.getPrevious(tokenlist.current); - Double a = Double.parseDouble(tokenlist.getContent().getToken()); + pList.current=pList.getPrevious(pList.current); + Double dividend = Double.parseDouble(pList.getContent().getToken()); - tokenlist.remove(); + pList.remove(); - tokenlist.getContent().setToken(String.valueOf(a/b)); + pList.getContent().setToken(String.valueOf(dividend/divisor)); } - tokenlist.next(); + pList.next(); } } - public void run() { - result = 0; - punktVorStrich(); - tokenlist.toFirst(); + private void klammerRegel(ListpList){ + List newTokenlist= new List(); + pList.toFirst(); + double berechnet; + //Durchlaufe die Tokenliste + while(pList.hasAccess()){ + // Token gleich ( dann entferne ihn + if(pList.getContent().getToken().equals("(")){ + pList.remove(); + //anschließend durchlaufe solange, bis auf ) gestoßen wird + while(!pList.getContent().getToken().equals(")")){ + + + //wenn noch nicht am ende der tokenliste + if(pList.hasAccess()) { + //wenn ( erneutvorkommt + if (pList.getContent().getToken().equals("(") ) { + // rufe die methode mehrereKlammern auf und speicher das ergebnis als neues Token in newTokenlist + berechnet = mehrereKlammern(pList); + newTokenlist.append(new Token("OPERAND",String.valueOf(berechnet))); + } + //wenn der Token nicht ) ist dann soll dieser in newTokenlist eingefügt werden und anschließend entfernt werden + if (!pList.getContent().getToken().equals(")")) { + newTokenlist.append(pList.getContent()); + pList.remove(); + } + } + } + //wenn auf ) gestoßen wurde, soll ) entfernt werden + if(pList.getContent().getToken().equals(")")) pList.remove(); + //newTokenlist wird ausgerechnet + berechnet = berechne(newTokenlist); + //und in die Tokenliste eingefügt + pList.append(new Token("OPERAND", String.valueOf(berechnet))); + newTokenlist = new List(); + //hier wurde nun 1 klammer gelöst + } + //wenn die liste noch nicht zu ende ist, soll das nächste Element geprüft werden + pList.next(); + } + } + private double mehrereKlammern(ListpList){ + List newTokenlist= new List(); + double berechnet=0; + //wenn current ( ist + if(pList.getContent().getToken().equals("(")){ + //wird es entfernt + pList.remove(); + //anschließend wird die übergebene tokenliste solange durchlaufen, bis ) auftritt + while(!pList.getContent().getToken().equals(")")){ + + + + if(pList.hasAccess()) { + //wenn current ( ist dann wird diese methode nochmal ab current ausgeführt und anschließend + // das ergebnis in newTokenlist eingefügt + if (pList.getContent().getToken().equals("(") ) { + berechnet = mehrereKlammern(pList); + newTokenlist.append(new Token("OPERAND",String.valueOf(berechnet))); + } + // wenn current nich ) ist, dann wird es in newTokenlist gespeichert und aus der tokenliste entfernt + if (!pList.getContent().getToken().equals(")")) { + newTokenlist.append(pList.getContent()); + pList.remove(); + } + } + } + //wenn ) auftritt dann wird es entfernt und anschließend wird die berechnung von newTokenlist rückgegeben. + if(pList.getContent().getToken().equals(")")) pList.remove(); + berechnet = berechne(newTokenlist); + } + return berechnet; + + + } + + private double berechne(List pList){ + double result1 = 0; + punktVorStrich(pList); + pList.toFirst(); String previous=""; - while( tokenlist.hasAccess() ) { - Token currentToken = tokenlist.getContent(); + while( pList.hasAccess() ) { + Token currentToken = pList.getContent(); if(currentToken.getType().equals("OPERATOR")){ previous=currentToken.getToken(); } if( currentToken.getType().equals("OPERAND") ) { switch (previous) { - case "+", "" -> result += Double.parseDouble(currentToken.getToken()); - case "-" -> result -= Double.parseDouble(currentToken.getToken()); + case "+", "" -> result1 += Double.parseDouble(currentToken.getToken()); + case "-" -> result1 -= Double.parseDouble(currentToken.getToken()); } } - tokenlist.next(); + pList.next(); } + return result1; + } + + public void run() { + klammerRegel(tokenlist); + punktVorStrich(tokenlist); + result=berechne(tokenlist); + + } }