# Taschenrechner in Java



## Guest (19. Jun 2006)

Moin,

Ich bin gerade dabei einen Taschenrechner zu programmieren, an den nur sehr wenige Anforderungen gestellt sind. Dennoch komme ich an einem Punkt nicht weiter.

Grünsätzlich habe ich Zahlenbuttons und Operationsbuttons.
Die Berchnung von zwei Zahlen ist kein Problem, geht es jedoch an eine 3.Zahl und eine 2. Rechenoperation, wird es kompliziert.

Meine Frage also:
Wie schaffe ich es eine Gleichung wie "312*4+28" lösen zu lassen (alles vom User eingegeben)?
lediglich Zahl 1 und Zahl 2 sollten dabei multipliziert werden und Zahl 3 addiert werden.
Wie bekomme ich dabei Punkt-vor-Strich- und Kommaregeln miteinbezogen. [ggf. Klammern]

Hat jemand schonmal etwas ähnliches versucht und vll. sogar ein Quelltextbsp.?


----------



## Wildcard (19. Jun 2006)

Du brauchst auch für simple mathematische Formeln einen Parser. Diesen kann man entweder selbst schreiben, oder enschlägige Parser-Generatoren verwenden. Da Taschenrechner aber das Beispiel schlecht hin sind solltest du keine Probleme haben mit Google diverse Implementierungen/Pseudocodes zu finden.


----------



## Guest (19. Jun 2006)

Könnte mich mal bitte kurz jmd. in "Parser" unterweisen? Auf dem Gebiet habe ich GAR keine Ahnung.

PS. Google gibt nach meiner Suche nichts sinnvolles aus...  :cry:


----------



## André Uhres (20. Jun 2006)

Anonymous hat gesagt.:
			
		

> Könnte mich mal bitte kurz jmd. in "Parser" unterweisen? ..


Schau mal in die FAQ  :wink:


----------



## thE_29 (20. Jun 2006)

In die FAQs...

Wie könnte man da jemals draufkommen dort zuerst nachzusehen....

Wird ja nie wo drauf hingewiesen... (und o schelm, benutzt ja net die Forensuche, die könnte ja auch Hilfe bringen.. Aber schon gar nicht und niemals in die API schauen..)


Es wird von Tag zu Tag ärgerlicher, wie faul eigentlich alle werden..


----------



## Guest (21. Jun 2006)

Hast du n Problem?

[Ironiemode]Weil ich ja ach so dumm bin und mich nicht informieren kann, habe ich natürlich nicht sämtliche Googleseiten durchsucht. Natürlich muss JEDER aus dem Parser-Prog. von Beni in den FAQs schlau werden... es lohnt sich ja eig. gar net hier ÜBERHAUPT Themen zu eröffnen. [/Ironiemode]

Aber ich weiß... es ist immer einfacher zu meckern als zu helfen. (Aber auch so erhöht man seine Posts.. und sein "Ansehen" in einem Forum)


----------



## SebiB90 (21. Jun 2006)

Anonymous hat gesagt.:
			
		

> es ist immer einfacher zu meckern als zu helfen.


ja sicher und es ist auch einfacher rumzumeckern als sich mal näher damit zu beschäftigen, Benis parser in den FAQ ist sehr gut erklärt, aber es ist klar wenn man den Beitrag nur überfliegt kann man ihn nicht verstehen, man muss schon mal sich eine Beispielrechnung nehmen und im Kopf genau die Anweisungen, die im Thread stehen, befolgen, wenn man das mal gemacht hat versteht man auch wie der Parser funktioniert und bei welchen Situationen er wie weiter machen muss.

so schwer is das nicht, ich hatte vorher auch noch ka vom Parsen und hab dann geschaft Benis parser so zu erweitern das er auch mit Variablen rechnet also z.b. 5a+5b+2a=7a+5b und dabei werden rechenregel befolgt und klammern kann man auch benutzen, also: sich bischen intensiver damit beschäftigen dann klappt es auch.


----------



## thE_29 (22. Jun 2006)

Oh ja, ich muss mir ja ein höheres Ansehen (in einem Forum.. was bringt das überhaupt?!) und mehr Posts holen..

Weil das kann ich dann bei jedem Lebenslauf angeben..

hey ich hatte ansehen in nem Board und > 4500 Posts..

Jo, das wirds sein.. Genau deswegen mache ich das hier, nur um mich selbst zu "befriedigen" und nicht etwa weil ich mir Zeit nehme und Leuten helfe...

Aber nein man muss "euch" ja alles nachwerfen, zig mal erklären und was weiß ich noch, damit ihr euch mal zufrieden gebt..

Und selbst wenn es schon Beispiele gibt (die FAQ is ja net so klein) ist noch immer keiner zufrieden, weil am liebsten hätten ihr wahrscheinlich alle einen der euch jeden Befehl einzeln erklärt..

Oder hey, gleich das ganze Programm schicken und dem Professort sagt ihr dann, wenn er fragen hat, soll er hier fragen...




Wie wärs mal mit ein bißchen Eigeninitiative??!?

Glaubt ihr wir haben schon immer gut programmieren können??


----------



## Guest (23. Jun 2006)

Leute wie "wir" können Hilfe von "oben" immer gut gebrauchen.

Wenn mir allerdings vorgeworfen wird, dass ich mich damit nicht intensiv genug beschäftigt habe, tut es mir leid überhaupt gefragt zu haben. 
Posts wie "Guck in die FAQ's" oder "Benutze Google!" helfen mir nicht weiter, da ich DAS alles schon hinter mir hab. 

Wann bitte habe ich gesagt, dass ihr mir jeden Befehl einzeln vorkauen sollt? Und warum antwortest du so schnippisch? Fühlst du dich angegriffen?

Ich habe ledglich nach seichter Unterweisung im Thema "Parser" gebeten. SOLLTE das allerdings zu viel verlangt sein, tut es mir Leid "euch" belästigt zu haben.

Vll. könnte mir dennoch jmd. helfen, der sich nicht zu "denen" zählt.


----------



## Wildcard (23. Jun 2006)

Eine 'kurze Unterweisung' zum Thema Parser ist ziemlich unmöglich. Das ist eine der Königsdisziplinen der Informatik und erfordert sehr viel Theorie. 
Parser werden aufgrund ihrer Komplexität selten selbst geschrieben, sonder von Tools erzeugt.
Das ist übliche Vorgehen:
1. Erstellen einer kontextfreien (oft rechtsrekursiven) Grammatik
2. Anhand der Terminalsymbole der Grammatik einen Scanner erzeugen (mit Lex,JLex,Flex,Rex...)
3. Die Grammatik in einen Parsergenerator einpflegen und ihm den erzeugten Scanner übergeben (CUP, LARK,...)

Wie du siehst sprengt das den Rahmen einer kurzen Unterweisung erheblich, zumal jedes dieser Tools über eine eigene Syntax verfügt.


----------



## 0xdeadbeef (23. Jun 2006)

Wenn man mit Google nach "Java Parser Stack" sucht, findet man schon einiges.
Auch hier gibt es einige Erläuterungen:
http://de.wikipedia.org/wiki/Stapelspeicher

Ein einfacher mathematischer Parser ist kein Hexenwerk. Man muß sich aber halt ein paar Gedanken machen zu Priorität von Operationen, Klammerebenen usw.

Am einfachsten ist ein Parser für ungekehrt polnische Notation (RPN) zu schreiben, weil man denn quasi direkt auf einen Werte- und Kommandostack legen kann.
Wenn der gleiche Ausdruck oft berechnet werden soll (z.B. Skriptsprache oder Funktionsplotter), sollte man den Ausdruck in einen interne Struktur überführen (bei komplexeren Parsern Baumstruktur, bei einfachen Stack(s)), bevor man ihn berechnet.

Ein bekannter freier OS-Parser für Java ist JEP:
http://www.singularsys.com/jep/

bzw. JEPLite
http://sourceforge.net/projects/jeplite/

Es gibt da aber noch viel mehr. Einfach mal nach "java parser expression" googlen.


----------



## Guest (23. Jun 2006)

DANKE... 
allerdings versuche und versuche ich... aber es will nichts Gescheites bei rauskommen!

Ich beziehe mich jetzt mal DIREKT auf MEIN Bsp.


```
import java.awt.*;

public class Rechner extends Frame
{
  private Label lblUeberschrift=new Label ("Taschenrechner");
  private Label lblEingabe=new Label ("Eingabe"); //zahl 1 = Eingabe
  public Label lblErgebnis=new Label (" ");
  public TextField tfEingabe=new TextField (10);
  public Button btnBeenden=new Button ("Beenden");
  public Button btnAusgabe=new Button ("Ausgabe");
  public Button btnPlus=new Button ("+");
  public Button btnMinus=new Button ("-");
  public Button btnMal=new Button ("*");
  public Button btnDurch=new Button ("/");
  public Button btn1=new Button ("1");
  public Button btn2=new Button ("2");
  public Button btn3=new Button ("3");
  public Button btn4=new Button ("4");
  public Button btn5=new Button ("5");
  public Button btn6=new Button ("6");
  public Button btn7=new Button ("7");
  public Button btn8=new Button ("8");
  public Button btn9=new Button ("9");
  public Button btn0=new Button ("0");
  private Panel pnlNorth=new Panel();
  private Panel pnlCenter=new Panel(new GridLayout (7,0));
  private Panel pnlSouth=new Panel (new GridLayout (1,0));
  private Panel pnlCenterZeile1=new Panel (new FlowLayout (FlowLayout.CENTER));
  private Panel pnlCenterZeile2=new Panel (new FlowLayout (FlowLayout.CENTER));
  private Panel pnlCenterZeile3=new Panel (new FlowLayout (FlowLayout.CENTER));
  private Panel pnlCenterZeile4=new Panel (new FlowLayout (FlowLayout.CENTER));
  private Panel pnlCenterZeile5=new Panel (new FlowLayout (FlowLayout.CENTER));
  private MyActionListener2 myActionListener2=new MyActionListener2 (this);
  
  public Rechner()
  {
    super ("Rechner");
    this.lblUeberschrift.setFont (new Font (" ",Font.BOLD,16));
    this.pnlNorth.add(lblUeberschrift);
    this.pnlCenterZeile1.add(this.lblEingabe);
    this.pnlCenterZeile1.add(this.tfEingabe);
    this.pnlCenter.add(this.pnlCenterZeile1);
    this.pnlCenter.add(this.pnlCenterZeile2);
    this.pnlCenter.add(this.pnlCenterZeile3);
    this.pnlCenter.add(this.pnlCenterZeile4);
    this.pnlCenter.add(this.pnlCenterZeile5);
    this.pnlCenter.add(this.lblErgebnis);
    this.pnlSouth.add(this.btnAusgabe);
    this.pnlSouth.add(this.btnBeenden);
    this.pnlCenterZeile2.add(this.btn1);
    this.pnlCenterZeile2.add(this.btn2);
    this.pnlCenterZeile2.add(this.btn3);
    this.pnlCenterZeile2.add(this.btnPlus);
    this.pnlCenterZeile3.add(this.btn4);
    this.pnlCenterZeile3.add(this.btn5);
    this.pnlCenterZeile3.add(this.btn6);
    this.pnlCenterZeile3.add(this.btnMinus);
    this.pnlCenterZeile4.add(this.btn7);
    this.pnlCenterZeile4.add(this.btn8);
    this.pnlCenterZeile4.add(this.btn9);
    this.pnlCenterZeile4.add(this.btnMal);
    this.pnlCenterZeile5.add(this.btn0);
    this.pnlCenterZeile5.add(this.btnDurch);
    this.add(this.pnlNorth,BorderLayout.NORTH);
    this.add(this.pnlCenter,BorderLayout.CENTER);
    this.add(this.pnlSouth,BorderLayout.SOUTH);
    this.pack();
    this.setVisible(true);
    //this.addWindowListener(new MyWindowListener());
    this.btnAusgabe.addActionListener (myActionListener2);
    this.btnBeenden.addActionListener (myActionListener2);
    this.btn1.addActionListener (myActionListener2);
    this.btn2.addActionListener (myActionListener2);
    this.btn3.addActionListener (myActionListener2);
    this.btn4.addActionListener (myActionListener2);
    this.btn5.addActionListener (myActionListener2);
    this.btn6.addActionListener (myActionListener2);
    this.btn7.addActionListener (myActionListener2);
    this.btn8.addActionListener (myActionListener2);
    this.btn9.addActionListener (myActionListener2);
    this.btn0.addActionListener (myActionListener2);
    this.btnPlus.addActionListener (myActionListener2);
    this.btnMinus.addActionListener (myActionListener2);
    this.btnMal.addActionListener (myActionListener2);
    this.btnDurch.addActionListener (myActionListener2);
  }
  public static void main (String [] args)
  {
    Rechner f = new Rechner();
  }
}
```


```
import java.awt.event.*;
import java.text.*;

public class MyActionListener2 implements ActionListener
{
  public Rechner f;
  public MyActionListener2 (Rechner f)
  {
    this.f=f;
  }
  public void actionPerformed (ActionEvent e)
  {
    DecimalFormat df=new DecimalFormat ("#,##0.0");
    double ergebnis=0;
    double Eingabe=0;
    if(e.getSource()==f.btnBeenden) System.exit (0);
    //f.tfEingabe.setText ("0");
    try
    {
      if(e.getSource()==f.btn1) f.tfEingabe.setText (f.tfEingabe.getText()+"1");
      if(e.getSource()==f.btn2) f.tfEingabe.setText (f.tfEingabe.getText()+"2");
      if(e.getSource()==f.btn3) f.tfEingabe.setText (f.tfEingabe.getText()+"3");
      if(e.getSource()==f.btn4) f.tfEingabe.setText (f.tfEingabe.getText()+"4");
      if(e.getSource()==f.btn5) f.tfEingabe.setText (f.tfEingabe.getText()+"5");
      if(e.getSource()==f.btn6) f.tfEingabe.setText (f.tfEingabe.getText()+"6");
      if(e.getSource()==f.btn7) f.tfEingabe.setText (f.tfEingabe.getText()+"7");
      if(e.getSource()==f.btn8) f.tfEingabe.setText (f.tfEingabe.getText()+"8");
      if(e.getSource()==f.btn9) f.tfEingabe.setText (f.tfEingabe.getText()+"9");
      if(e.getSource()==f.btn0) f.tfEingabe.setText (f.tfEingabe.getText()+"0");
      
      if(e.getSource()==f.btnPlus) f.tfEingabe.setText (f.tfEingabe.getText()+"+");
      if(e.getSource()==f.btnMinus) f.tfEingabe.setText (f.tfEingabe.getText()+"-");
      if(e.getSource()==f.btnMal) f.tfEingabe.setText (f.tfEingabe.getText()+"*");
      if(e.getSource()==f.btnDurch) f.tfEingabe.setText (f.tfEingabe.getText()+"/");
      
      Eingabe=Double.parseDouble(f.tfEingabe.getText().replace(',','.'));
      
      if(e.getSource()==f.btnAusgabe) ergebnis=Eingabe;
      f.lblErgebnis.setText ("Ergebnis: " +df.format (ergebnis));
    }
    catch (NumberFormatException error)
    {
      f.lblErgebnis.setText ("Fehler bei Eingabefeld...");
    }
  }
}
```

Wie bitte schaffe ich es jetzt, einen String (der über die Nummern und Operationstasten eingegeben wurde) vom Pro. einlesen zu lassen, und berechnen zu lassen?

Danke.


----------



## 0xdeadbeef (23. Jun 2006)

Hast Du Dir JEPLite o.ä. zumindest mal angesehen?

Ansonsten hast Du ja außer der Oberfläche noch überhaupt nichts, und Deine Erwartungshaltung scheint zu sein, daß wir jetzt Dein Programm fertigschreiben, oder?


----------

