Kompexe Mathematische Formeln

Status
Nicht offen für weitere Antworten.

Spin

Top Contributor
Hallo liebe Java Gemeinde, nachdem ich nun ein bischen Zeit für Java 2 D hatte , müssen wir nun einen Taschenrechner programmieren , der komplexe mathematische Formeln berechnet.


Nun frage ich mich , wie man dass am besten macht :
Bsp.: 3*5/4*6

Das ist noch nicht sehr komplex, aber immerhin schon mehr als nur 3-4 = 1;

Ich kenne JTextArea in der man mit der Funktion append() alles anzeigen lassen kann.
Oder auch setText() ...da überschreibt er aber immer dass, was vorher im JTextfeld war.

Kennt einer einen guten Link, oder ein Tutorial, wo ich einen Parser oder etwas änliches finde.

Ich habe es mal mit substring versucht, aber komme da nicht sehr weit mit.
Dann hatte ich mal was mit regulären ausdrücken gesehen , aber die sind mir ein wenig zu kompliziert.


Wie würdet ihr da ran gehen? Gibt es ein Framework welches man benutzen kann?

grüße
 
>Gibt es ein Framework welches man benutzen kann?

ANTLR zB
ANTLR Parser Generator
Object Computing, Inc. - Java News Brief - June*2008

siehe auch:
http://www.java-forum.org/allgemein...fuer-mathematische-funktionen.html#post512441

EDIT:
Die Grammatik von mir kann sogar Variablen erkennen. Im Netz findet man auch sehr viele einfache Grammatiken für simples Rechenen und hier in den FAQ hat Beni (?) mal ein Tutorial für einen einfachen Parser geschrieben

EDIT2:
jop...war beni
http://www.java-forum.org/java-faq-beitraege/12306-parser-fuer-mathematische-formeln.html
 
Zuletzt bearbeitet:
spannend find ich da weniger die Frage wie du das ganze mit der GUI löst, sondern wie sieht denn da dein Backend aus (sprich Parser, Auswertung der Ausdrücke etc). Hast dir da schon Gedanken gemacht!?

Du könntest, wenn die TextArea immer nur den neuen eingegebenen Wert anzeigen soll auch ein StringBuilder im Hintergrund nutzen, an dem du einfach alles ranhängst was eingegeben wird, dann hast schonmal deine ganze Formel in einem String vorhanden und kannst die dann in den Parser jagen.

Hm aber was genau nun Probleme bereiten wird, wird sich zeigen wenn du angefangen hast 🙂
 
Java:
public void actionPerformed(ActionEvent e)
   {
    Object obj = e.getSource();

    if(obj == beenden){
        System.exit(0);
    }
    else if(obj == one){
        area.append("1");
    }
    else if(obj == two){
        area.append("2");
    }
    else if(obj == plus){
        area.append("+");
    }
    else if(obj == gleich)
    {
        calculate();
    }
    }
    public void calculate(){

    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
 		ScriptEngine scriptEngine = (ScriptEngine) scriptEngineManager
 				.getEngineByName("JavaScript");

        String TA = area.getText();


 		try {
            
 			scriptEngine.eval(TA);
            double b =(Double) scriptEngine.get(TA);
            area.setText(String.valueOf(b));

 		}
        catch (ScriptException d) {
 			d.printStackTrace();
 	     }



Ich habe mir gedacht , dass ich es erstmal mit ARadauers Vorschlag probiere. Quasi mit dem Scrtpt ( Javascript.)

Nun sagt er mir Nullpointer Exception, mhh.


Ich habe mir ein Actionlistener gebaut , der mir per Knopfdruck alles in die TextArea setzt. Danach habe ich alles in ein String lesen lassen ....


und wollte es anschließend durch dieses Script berechnen lassen , weiterhin per setText zurückgeben.

Warum macht er das nicht? NullPointerException sagt mir ja , dass mein String auf nichts verweisst. Kann das sein das er irgendwie, also mein String , die eingabe im textfeld nicht bekommt?
 
Java:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at spezielleswingkomponenten.TRPanel.calculate(TR.java:113)
        at spezielleswingkomponenten.TRPanel.actionPerformed(TR.java:98)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
        at java.awt.Component.processMouseEvent(Component.java:6041)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3265)
        at java.awt.Component.processEvent(Component.java:5806)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
        at java.awt.Container.dispatchEventImpl(Container.java:2102)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)





Das ist meine Fehlermeldung: ausgelöst in Teile 113 :

Java:
double b =(Double) scriptEngine.get(TA);

mhh
 
kann aber nicht daran liegen, dass deine Nutzung von eval und get nicht dem Vorgehen von ARadauer entspricht!? Ich kenn mich zwar mit JavaScript nicht aus, aber das was du in die eval jagst ist definitiv versch. von dem was ARadauer da angibt. Er bindet das Ergebnis der Rechnung ebenfalls an eine Variable v, welche er dann im get einsetzt, um deren Wert abzufragen. Du gibst da nochmal dein String aus dem Textfeld rein.
 
Java:
import javax.script.ScriptException;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TR {

    public static void main(String[]args) 
    {
       TRFrame tr = new TRFrame();
       tr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       tr.setVisible(true);
       
 	}


}
    class TRFrame extends JFrame
    {
        public TRFrame()
        {
            setTitle("Calculator");
            TRPanel panel = new TRPanel();
            add(panel);
            pack();

        }
    }

    class TRPanel extends Panel implements ActionListener
    {
        JButton one = new JButton("1");
        JButton two = new JButton("2");
        JButton three = new JButton("3");
        JButton four = new JButton("4");
        JButton beenden = new JButton("beenden");
        JButton gleich = new JButton("=");
        JButton plus = new JButton("+");
        JTextArea area;
        JPanel panel;


        public TRPanel()
        {
            setLayout(new BorderLayout());
            area = new JTextArea("",2,5);
            add(area, BorderLayout.NORTH);

            panel = new JPanel();
            panel.setLayout(new GridLayout(4, 4));
            panel.add(one);
            one.addActionListener(this);
            panel.add(two);
            two.addActionListener(this);
            panel.add(three);
            panel.add(four);
            panel.add(beenden);
            beenden.addActionListener(this);
            panel.add(gleich);
            gleich.addActionListener(this);
            panel.add(plus);
            plus.addActionListener(this);
            add(panel, BorderLayout.CENTER);
        }

    public void actionPerformed(ActionEvent e)
   {
    Object obj = e.getSource();

    if(obj == beenden){
        System.exit(0);
    }
    else if(obj == one){
        area.append("1");
    }
    else if(obj == two){
        area.append("2");
    }
    else if(obj == plus){
        area.append("+");
    }
    else if(obj == gleich)
    {
        calculate();
    }
    }
    public void calculate(){

    ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
 		ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript");

        String TA = area.getText();


 		try {
            
 			scriptEngine.eval(TA);
            double b =(Double) scriptEngine.get(TA);
            area.setText(String.valueOf(b));

 		}
        catch (ScriptException d) {
 			d.printStackTrace();
 	     }



Java:
RhinoScriptEngine .....missing ;

Ich schätze es liegt wieder an mir 😉 Da ich kein JavaScript kann.
Ich weiß dass man da mit var x * stack.size() usw.

die variablen füllen kann , aber mehr auch nicht. Ich schätze
dass , was ich mit scriptEngine.eval(TA); hole ist richtig , doch kann JavaScript damit nichts anfangen.

Java:
engine.eval(”var v = eval(’”+formel+”‘)”);

Sind das Anführungszeichen incl Hochkomata?


EDIT :

Das müsste die eval sein auf die ich zugreifen möchte:

Java:
 public Object eval(Reader reader, ScriptContext context) 
            throws ScriptException{
     
        Context cx;
        Object retVal = null;
        RhinoNamespaceBridge oldSpace = rhinospace;
        String source = (get("javax.script.filename") != null) 
                ? get("javax.script.filename").toString() 
                : "<unknown>";
        
        try {
        	
            cx = Context.enter();
            cx.setGeneratingDebug(false);
            cx.setGeneratingSource(false);
            cx.setOptimizationLevel(-1);
            Scriptable sc = getScope(context);
            retVal = cx.evaluateReader(sc, reader, source, 0, null);
 
        } catch (JavaScriptException ex) {
            errorHandler(ex);
        } catch (IOException ioe) {
            errorHandler(ioe);
        } finally {
            rhinospace = oldSpace;
            Context.exit();
        }
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.

Zurück
Oben