//Name: CELLEK Ramazan
//Matr.Nr: 0125188
//Bsp.Nr: 3166/ 396
//e-mail: rambo21@gmx.at
//Kategorie: Mathematik
//Klasse: schwer
/*Beschreibung: Variablen werden durch Berechnungen mit Werten belegt;
                der Wert einer dieser Variablen wird abgefragt.*/

import java.util.Hashtable;

public class Varcalc
{
  static int indizes;                         //Variablen werden festgelegt
  static String eingabe;
  static Hashtable variablen = new Hashtable(10);

  public static void main(String[] args)
  {
    int zaehler = 0;
    String temp;
    do
    {
      temp = EprogIO.readWord();
      while (Character.isLetter(temp.charAt(zaehler)))
        zaehler++;
      if (temp.charAt(zaehler) == '=')
        variablen.put(temp.substring(0, zaehler), new Float(rechne(temp.substring(++zaehler, temp.length()) + "|")));
      else
      {
        if (temp.charAt(0) == '?')  // ? beendet die Schleife v das Ende der Schleife
          break;
        fehler();
      }
      zaehler = 0;
    } while (true);

    EprogIO.printFixed(rechne(temp.substring(1, temp.length()) + "|"));
    EprogIO.println();
  }

  public static float rechne(String parameter)  //Hier werden die Parameter definiert
  {
    indizes = 0;
    eingabe = parameter;
    float ergebnis = ausdruck();
    if (indizes != eingabe.length() - 1)
      fehler();
    return ergebnis;
  }

  private static float ausdruck()
  {
    float ergebnis = term();                   //Addition
    if (eingabe.charAt(indizes) == '+')
    {
      indizes++;
      if (!istOp(eingabe.charAt(indizes)))
        ergebnis = ergebnis + ausdruck();
      else
        fehler();
    }
    else if (eingabe.charAt(indizes) == '-') // wenn nicht, dann Substraktion
    {
      indizes++;
      if (!istOp(eingabe.charAt(indizes)))
        ergebnis = ergebnis - ausdruck();
      else
        fehler();
    }
    return ergebnis;                           //Ergebnis wird Ausgegeben
  }

  private static float term()
  {
    float ergebnis = faktor();
    if (eingabe.charAt(indizes) == '*')      //Multiplikation
    {
      indizes++;
      if (!istOp(eingabe.charAt(indizes)))
        ergebnis = ergebnis * term();
      else
        fehler();
    }
    else if (eingabe.charAt(indizes) == '/') //Wenn nicht, dann Division
    {
      indizes++;
      if (!istOp(eingabe.charAt(indizes)))
        ergebnis = ergebnis / term();
      else
        fehler();
    }
    return ergebnis;                           //Ergebnis wird Ausgegeben
  }

  private static float faktor()
  {
    float ergebnis;

    if (eingabe.charAt(indizes) == '-')
    {
      indizes++;
      if (Character.isDigit(eingabe.charAt(indizes)))
        ergebnis = (-1) * wert();
      else if (eingabe.charAt(indizes) == '(')   //Klammern werden festgelegt
      {
        indizes++;
        ergebnis = (-1) * ausdruck();
        if (eingabe.charAt(indizes) != ')')
          fehler();
        indizes++;
      }
      else
        ergebnis = (-1) * variable();
    }
    else
    {
      if (Character.isDigit(eingabe.charAt(indizes)))
        ergebnis = wert();
      else if (eingabe.charAt(indizes) == '(')   //Klammern werden festgelegt
      {
        indizes++;
        ergebnis = ausdruck();
        if (eingabe.charAt(indizes) != ')')
          fehler();
        indizes++;
      }
      else
        ergebnis = variable();
    }

    return ergebnis;
  }

  private static float wert()
  {
    int zaehler = indizes;
    //Digit = Zahl -> hier wird Komma eingegeben, zB: 3.141 (auf 3 Nachkommastellen)
    while (Character.isDigit(eingabe.charAt(indizes)) || eingabe.charAt(indizes) == '.')
      indizes++;
    try
    {
      return Float.valueOf(eingabe.substring(zaehler, indizes)).floatValue();
    }
    catch (Exception e)
    {
      fehler();
    }
    return 5;                    // diese Zeile wird nie erreicht
  }

  private static float variable()
  {
    int zaehler = indizes;
    while (Character.isLetter(eingabe.charAt(indizes)))
      indizes++;
    Float ergebnis = (Float) variablen.get(eingabe.substring(zaehler, indizes));
    if (ergebnis != null)
      return ergebnis.floatValue();
    else
      fehler();

    return 5;                    // diese Zeile wird nie erreicht
  }

  public static boolean istOp(char buchstabe)
  {
    return (buchstabe == '+' || buchstabe == '-' || buchstabe == '/' || buchstabe == '*');
  }

  public static void fehler()         //Die Fehler-Methode: Bei falscher Eingabe, Fehlerausgabe
  {
    EprogIO.println("FALSCHE EINGABE");
    System.exit(0);
  }
}