Dragosike 0 Newbie Poster

Could anyone point me in the right direction or provide a step-by-step process to create an expression evaluator in Java using StringTokenizer, Stacks, and Recursion? It would be appreciated. The method I need help with is "public float evaluator()" Here's the current code:

import structures.Stack;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;



public class Expression {

	/**
	 * Expression to be evaluated
	 */
	String expr;                
    
	/**
	 * Scalar symbols in the expression 
	 */
	ArrayList<ScalarSymbol> scalars;   
	
	/**
	 * Array symbols in the expression
	 */
	ArrayList<ArraySymbol> arrays;
    
	/**
	 * Positions of opening brackets
	 */
	ArrayList<Integer> openingBracketIndex; 
    
	/**
	 * Positions of closing brackets
	 */
	ArrayList<Integer> closingBracketIndex; 

    /**
     * String containing all delimiters (characters other than variables and constants), 
     * to be used with StringTokenizer
     */
    public static final String delims = " \t*+-/()[]";
    
    /**
     * Initializes this Expression object with an input expression. Sets all other
     * fields to null.
     * 
     * @param expr Expression
     */
    public Expression(String expr) {
        this.expr = expr;
        scalars = null;
        arrays = null;
        openingBracketIndex = null;
        closingBracketIndex = null;
    }

    /**
     * Matches parentheses and square brackets. Populates the openingBracketIndex and
     * closingBracketIndex array lists in such a way that closingBracketIndex[i] is
     * the position of the bracket in the expression that closes an opening bracket
     * at position openingBracketIndex[i]. For example, if the expression is:
     * <pre>
     *    (a+(b-c))*(d+A[4])
     * </pre>
     * then the method would return true, and the array lists would be set to:
     * <pre>
     *    openingBracketIndex: [0 3 10 14]
     *    closingBracketIndex: [8 7 17 16]
     * </pe>
     * 
     * @return True if brackets are matched correctly, false if not
     */
    public boolean isLegallyMatched() {
    	
    	Stack<String> tag = new Stack<String>();
    	
    	for(int i = 0; i < expr.length(); i++)
    	{
    		if(expr.charAt(i) == '[' || expr.charAt(i) == '(')
    		{
    			tag.push(expr.substring(i,i+1));
    			openingBracketIndex.add(new Integer(i));
    		}
    		else if(expr.charAt(i) == ']' || expr.charAt(i) == ')')
    		{
    			if(tag.peek().equals(expr.substring(i,i+1)))
    			{
    				closingBracketIndex.add(new Integer(i));
    				tag.pop(); 
    			}
    			else if(tag.peek().equals("") || !tag.peek().equals(expr.substring(i,i+1)))
    			{
    				return false;
    			}
    		}
    	}
    	return true;
    		
   /*if (open) {
    	 * 		count++;
    	 * 		push onto stack 1 open
    	 * 		push onto stack 2 count
    	 * 		add to array @ count the value of i
    	 * 	}
    	 * if (close) {
    	 * 		compare
    	 * 			if (is close to previous) {
    	 * 				pop stack 1
    	 * 				pop stack 2
    	 * 				add to array2 @ value from popped stack 2 value of i
    	 * 			}
    	 * 		else {
    	 * 			return false;
    	 * }}
    	 */
    }

    /**
     * Populates the scalars and arrays lists with symbols for scalar and array
     * variables in the expression. For every variable, a SINGLE symbol is created and stored,
     * even if it appears more than once in the expression.
     * At this time, values for all variables are set to
     * zero - they will be loaded from a file in the loadSymbolValues method.
     */
    public void buildSymbols() {
    	
    	String expression = expr;
		
    	for(int i = 0; i < expression.length(); i++)
		{	
    		if(!Character.isLetter(expression.charAt(i)) && expression.charAt(i) != '[')
    		{
    			ScalarSymbol add = new ScalarSymbol(expression.substring(0,i));
    			scalars.add(add);
    			expression = expression.substring(i+1);
    		}
    		else if(!Character.isLetter(expression.charAt(i)) && expression.charAt(i) == '[')
    		{
    			ArraySymbol add = new ArraySymbol(expression.substring(0,i));
    			arrays.add(add);
    			expression = expression.substring(i+1);
    		}
		}
    }
    
    /**
     * Loads values for symbols in the expression
     * 
     * @param br BufferedReader for values input
     * @throws IOException If there is a problem with the input 
     */
    public void loadSymbolValues(BufferedReader br) 
    throws IOException {
        String line;
        while ((line = br.readLine())!= null) {
            StringTokenizer st = new StringTokenizer(line);
            int numTokens = st.countTokens();
            String sym = st.nextToken();
            ScalarSymbol ssymbol = new ScalarSymbol(sym);
            ArraySymbol asymbol = new ArraySymbol(sym);
            int ssi = scalars.indexOf(ssymbol);
            int asi = arrays.indexOf(asymbol);
            if (ssi == -1 && asi == -1) {
            	continue;
            }
            int num = Integer.parseInt(st.nextToken());
            if (numTokens == 2) { // scalar symbol
                scalars.get(ssi).value = num;
            } else { // array symbol
            	asymbol = arrays.get(asi);
            	asymbol.values = new int[num];
                // following are (index,val) pairs
                while (st.hasMoreTokens()) {
                    String tok = st.nextToken();
                    StringTokenizer stt = new StringTokenizer(tok," (,)");
                    int index = Integer.parseInt(stt.nextToken());
                    int val = Integer.parseInt(stt.nextToken());
                    asymbol.values[index] = val;              
                }
            }
        }
    }
    
    /**
     * Evaluates the expression, using RECURSION to evaluate subexpressions and to evaluate array 
     * subscript expressions.
     * 
     * @return Result of evaluation
     */
    public float evaluate() 
    {
    	StringTokenizer solve = new StringTokenizer(expr,delims);
    	Stack<String> operator = new Stack<String>();
    	Stack<String> operand = new Stack<String>();
    	
    	if(solve.nextToken() == solve.nextToken(delims))
    	{
    		operator.push(solve.nextToken());
  		}
    	else
    	{
    		operand.push(solve.nextToken());
    	}
    	
        //um what now?
    	return 0;
    }

    /**
     * Prints the symbols in the scalars list
     */
    public void printScalars() {
        for (ScalarSymbol ss: scalars) {
            System.out.println(ss);
        }
    }
    
    /**
     * Prints the symbols in the arrays list
     */
    public void printArrays() {
    	for (ArraySymbol as: arrays) {
    		System.out.println(as);
    	}
    }
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.