questa è una classe che ho scritto tempo fa per analizzare espressioni aritmetiche con i quattro operatori +-*/ e una serie di costanti (cioè stringhe a cui è associato un valore) predefinite.
Sicuramente un esperto nel campo sorriderebbe a tutte le ingenuità che ho scritto, ma per quello che mi serviva ha sempre funzionato
Forse ti può essere utile...

codice:
/*
 *   Copyright (C) 2003  Lorenzo Blanco
 *
 *   Require JDK 1.3
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 *   Send questions or suggestions to webmaster@lorenzoblanco.it
 *
 */

import java.util.*;

/**
 * La classe AnalizzatoreEspressioni permette di calcolare delle
 * espressioni aritmetiche.
 *
 * @version 1.0
 * @author Lorenzo Blanco
 */
public class AnalizzatoreEspressioni {
    public static double risultEspressione(String espressione) throws EsprException {
        return risultEspressione(espressione,null);
    }

    public static double risultEspressione(String espressione, HashMap mappaCostanti) throws EsprException {

//        if (mappaCostanti != null) {
//
//            // stampa gli indirizzi IVN con gli indirizzi delle routine di servizio
//            Set set = mappaCostanti.entrySet();
//
//            Iterator i = set.iterator();
//
//            while (i.hasNext()) {
//                Map.Entry la = (Map.Entry) i.next();
//                System.out.println(la.getKey() + ": " + la.getValue());
//            }
//        }

        if (!veificaParentesi(espressione)) {
            throw new EsprException("Errore nelle parentesi");
        }

        // ad ogni coppia parentesi aperta/chiusa sostituisce il valore
        String daAnalizzare = espressione;
        int indiceAperta = daAnalizzare.indexOf('(');
        int indiceChiusa = daAnalizzare.indexOf(')');
        int indiceUCPDUA = ultimaChiusaPrimaDiUnaAperta(daAnalizzare);
        while (indiceAperta != -1) {

            daAnalizzare = daAnalizzare.substring(0,indiceUCPDUA) +
                           String.valueOf(risultEspressioneSenzaPar(
                                                   daAnalizzare.substring(indiceUCPDUA+1,indiceChiusa),
                                                   mappaCostanti)) +
                           daAnalizzare.substring(indiceChiusa+1);

            indiceAperta = daAnalizzare.indexOf('(');
            indiceChiusa = daAnalizzare.indexOf(')');
            indiceUCPDUA = ultimaChiusaPrimaDiUnaAperta(daAnalizzare);

//            System.out.println(daAnalizzare);

        }

        return risultEspressioneSenzaPar(daAnalizzare, mappaCostanti);
    }

    private static int ultimaChiusaPrimaDiUnaAperta(String dove) {
        int indiceCercato = -1;
        boolean trovata = false;
        boolean trovataTemp;
        for (int i = 0; !trovata && i < dove.length(); i++) {

            // se trova una '(' verifica che prima della prossima ')' non ci siano '('
            if (dove.charAt(i) == '(') {
                trovataTemp = true;

                for (int j = i+1; trovataTemp && j < dove.indexOf(')'); j++) {
                    if (dove.charAt(j) == '(') {
                        trovataTemp = false;
                    }

                }

                if (trovataTemp) {
                    indiceCercato = i;
                    trovata = true;
                }
            }
        }
        return indiceCercato;
    }

    // metodo che verifica che ci siano un numero uguale di parentesi chiuse e aperte
    private static boolean veificaParentesi(String dove) {
        int daChiudere = 0;;

        for (int i = 0; i < dove.length(); i++) {
            if (dove.charAt(i) == '(') {
                daChiudere++;
            } else if (dove.charAt(i) == ')') {
                daChiudere--;
            }

            if (daChiudere < 0) {
                return false;
            }
        }

        if (daChiudere == 0) {
            return true;
        } else {
            return false;
        }

    }

    private static double risultEspressioneSenzaPar(String espressione, HashMap mappaCostanti) throws EsprException {

//        System.out.println("\t"+espressione);

        if (espressione.length() < 1) {
            throw new EsprException("L'espressione è vuota");
        }

        // uso del '-' come cambio di segno
        if (espressione.startsWith("-")) {
            espressione = "0"+espressione;
        }

        int primoOperando, secondoOperando;
        int indicePrimoPiuOMeno = trovaPrimoPiuOMeno(espressione);
        int indicePrimoDiviso = trovaPrimoDiviso(espressione);
        int indicePrimoPer = trovaPrimoPer(espressione);


        // se non ci sono '+' o '-'
        if (indicePrimoPiuOMeno == -1) {

            // se non ci sono '*'
            if (indicePrimoPer == -1) {

                // se non ci sono '/'
                if (indicePrimoDiviso == -1) {

                    // è un numero puro, quindi lo restituisce
                    try {
                        // se non è disponibile la mappa delle costanti
                        if (mappaCostanti == null) {
                            return new Double(espressione).doubleValue();
                        } else {
                            if (mappaCostanti.containsKey(espressione)) {
                                Comando c = (Comando) mappaCostanti.get(espressione);

                                // se è una EQU
                                if (c.direttiva == 4) {
                                    return  (double) ((Long) c.argDirett.get(1)).longValue();
                                // altrimenti è una D*
                                } else {
                                    return  (double) ((Long) c.argDirett.get(2)).longValue();
                                }
                            } else {
                                return new Double(espressione).doubleValue();
                            }
                        }



                    } catch (NumberFormatException nfe) {
                        throw new EsprException("La costante "+espressione+" non è valida");
                    }

                // ci sono '/'
                } else {

                    return risultEspressioneSenzaPar(espressione.substring(0,indicePrimoDiviso), mappaCostanti) /
                           risultEspressioneSenzaPar(espressione.substring(indicePrimoDiviso+1), mappaCostanti);
                }

            // ci sono '*'
            } else {
                return risultEspressioneSenzaPar(espressione.substring(0,indicePrimoPer), mappaCostanti) *
                       risultEspressioneSenzaPar(espressione.substring(indicePrimoPer+1), mappaCostanti);
            }

        // c'è almeno un '+' o un '-'
        } else {
            double risultato = risultEspressioneSenzaPar(
                                        espressione.substring(0,trovaPrimoPiuOMeno(espressione)),
                                        mappaCostanti);
            String ancoraDaAnalizzare = espressione;
            int indPrimoPiuOMeno,indSecondoPiuOMeno;

            while (trovaPrimoPiuOMeno(ancoraDaAnalizzare) != -1) {

                indPrimoPiuOMeno = trovaPrimoPiuOMeno(ancoraDaAnalizzare);
                indSecondoPiuOMeno = trovaSecondoPiuOMeno(ancoraDaAnalizzare);

                //System.out.println(ancoraDaAnalizzare + " | " + indicePiuOMeno);
                if (ancoraDaAnalizzare.charAt(indPrimoPiuOMeno) == '+') {
                    risultato += risultEspressioneSenzaPar(
                                    ancoraDaAnalizzare.substring(indPrimoPiuOMeno+1,indSecondoPiuOMeno),
                                    mappaCostanti);
                } else if (ancoraDaAnalizzare.charAt(indPrimoPiuOMeno) == '-') {
                    risultato -= risultEspressioneSenzaPar(
                                    ancoraDaAnalizzare.substring(indPrimoPiuOMeno+1,indSecondoPiuOMeno),
                                    mappaCostanti);
                } else {
                    System.out.println("Questo non dovrebbe essere visualizzato (1)");
                }
                ancoraDaAnalizzare = ancoraDaAnalizzare.substring(indPrimoPiuOMeno+1);
//                System.out.println("\t\tris.int.: "+risultato);

            }

            return risultato;
        }
    }

    private static int trovaPrimoPiuOMeno(String dove) {
        for (int i = 0; i < dove.length(); i++) {
            if (dove.charAt(i) == '+' || dove.charAt(i) == '-') {
                return i;
            }
        }

        return -1;
    }

    private static int trovaSecondoPiuOMeno(String dove) {
        boolean trovatoPrimo = false;
        for (int i = 0; i < dove.length(); i++) {
            if (dove.charAt(i) == '+' || dove.charAt(i) == '-') {
                if (!trovatoPrimo) {
                    trovatoPrimo = true;
                } else {
                    return i;
                }
            }
        }

        return dove.length();
    }

    private static int trovaPrimoDiviso(String dove) {
        for (int i = 0; i < dove.length(); i++) {
            if (dove.charAt(i) == '/') {
                return i;
            }
        }

        return -1;
    }

    private static int trovaPrimoPer(String dove) {
        for (int i = 0; i < dove.length(); i++) {
            if (dove.charAt(i) == '*') {
                return i;
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        String test = "60/3*2+3+66/2*2";
        test = "(2+30*2/3)*3+((3+2)*3+300/(90+2*7))/2";
        // righe di codice del JPD132 al 28/4/2003
        test = "294+151+51+349+63+2965+391+203+69+138+35+1087+900+151+2604+42+316";

        try {
            System.out.println(risultEspressione(test));
        } catch (EsprException ee) {
            System.out.println(ee);
        }
//        System.out.println(veificaParentesi("( () () ( () () ) )"));
//        System.out.println(ultimaChiusaPrimaDiUnaAperta("( () () ( () () ) )"));

    }
}