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 double 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; } if( !analyse() ) { System.out.println("Fehler bei der semantischen 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; StringBuilder currentToken = new StringBuilder(); for(char buchstabe: eingabe){ switch(state){ case 0: 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("Am anfang des Termes kann kein . stehen."); return false; } case '+', '-', '*', '/' -> { System.out.println("Der Term darf nicht mir mit dem Operator " + buchstabe + " beginnen."); return false; } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; } } break; case 1: switch (buchstabe) { case '.' -> { currentToken.append(buchstabe); state = 3; } case '+', '-', '*', '/' -> { tokenlist.append(new Token("OPERAND", currentToken.toString())); currentToken = new StringBuilder(); tokenlist.append(new Token("OPERATOR", Character.toString(buchstabe))); state = 5; } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; } } break; case 2: switch (buchstabe) { case '.' -> { currentToken.append(buchstabe); state = 3; } case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { currentToken.append(buchstabe); state = 2; } case '+', '-', '*', '/' -> { tokenlist.append(new Token("OPERAND", currentToken.toString())); currentToken = new StringBuilder(); tokenlist.append(new Token("OPERATOR", Character.toString(buchstabe))); state = 5; } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; } } break; case 3: switch (buchstabe) { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { currentToken.append(buchstabe); state = 4; } case '+', '-', '*', '/' -> { System.out.println("Nach einem . darf kein Rechenoperator folgen"); return false; } } break; case 4: switch (buchstabe) { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' -> { currentToken.append(buchstabe); state = 4; } case '+', '-', '*', '/' -> { tokenlist.append(new Token("OPERAND", currentToken.toString())); currentToken = new StringBuilder(); tokenlist.append(new Token("OPERATOR", Character.toString(buchstabe))); state = 5; } case '.' -> { System.out.println("Eine Dezimalzahl kann nur ein . haben."); return false; } } break; case 5: 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("Nach einem Operator kann kein . stehen."); return false; } case '+', '-', '*', '/' -> { System.out.println("Nach einem Operator darf nicht direkt ein weiterer Operator folgen."); return false; } default -> { System.out.println("Der Buchstabe " + buchstabe + " ist nicht in der Sprache vorhanden."); return false; } } break; } } 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!"; return false; } else { tokenlist.append(new Token("OPERAND", currentToken.toString())); 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; break; } else { fehler = "Unbekanntes Token: "+currentToken.getType(); return false; } case 1: if( currentToken.getType().equals("OPERATOR") ) { state = 0; break; } else if( currentToken.getType().equals("OPERAND") ) { fehler = "Auf einen Operanden muss ein Operator folgen!"; return false; } else { fehler = "Unbekanntes Token: "+currentToken.getType(); return false; } } tokenlist.next(); } if( state == 0 ) { fehler = "Ein Rechenterm darf nicht auf einen Operator enden!"; return false; } else { return true; } } public boolean analyse() { tokenlist.toFirst(); while(tokenlist.hasAccess()){ if(tokenlist.getContent().getToken().equals("/")){ tokenlist.next(); if(tokenlist.getContent().getToken().equals("0")){ fehler = "Es kann nicht durch 0 geteilt werden."; return false; } } tokenlist.next(); } return true; } public void run() { result = 0; tokenlist.toFirst(); String previous=""; while( tokenlist.hasAccess() ) { Token currentToken = tokenlist.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 "*" -> result *= Double.parseDouble(currentToken.getToken()); default -> result /= Double.parseDouble(currentToken.getToken()); } } tokenlist.next(); } } }