Nathaniel Schmeling
Nathaniel Schmeling

Reputation: 21

How to fix stack overflow in self-made parser?

I'm creating a parser for class. The user has to enter in the equation with a space between each element. Each element is then read into the same array in it's own index. I keep getting stack overflow. I think it's because only the last calling of the myCalculus function ever actually closes. Though, if this is the case, I'm not sure how to organize the code to avoid this. Thanks in advance for any help.

import java.util.Scanner;

public class InterpreterFour{
    public static void main(String []args){
    //read in the values as a string
    Scanner scan = new Scanner(System.in);
    String expressions = scan.nextLine();
    //save each token into the array
    String[] token = expressions.split("\\s+");

    int solved = 0;
    int o = 0;
    //call myCalculus function which will call the other functions
    System.out.println(myCalculus(token, 0, solved));
    }

    public static int myCalculus(String[] token, int o, int solved){
        while(o < token.length-1){
            if(token[o].equals("*")){
                multiply(token, o, solved);
            }
            else if(token[o].equals("+")){
                add(token, o, solved);
            }
            else if(token[o].equals("<")){
                compare(token, o, solved);
            }
            else if(token[o].equals("<=")){
                compare(token, o, solved);
            }
            else if(token[o].equals(">")){
                compare(token, o, solved);
            }
            else if(token[o].equals("<=")){
                compare(token, o, solved);
            }
            else if(token[o].equals("(")){
                myCalculus(token, o++, solved);
            }
            else{
                myCalculus(token, o++, solved);
            }
        }
        return solved;
    }

    public static void add(String[] token, int o, int solved){
        if(token[o++].matches("[-+]?\\d*\\.?\\d+")){
            solved = solved + Integer.parseInt(token[o--]) + Integer.parseInt(token[o++]);
            myCalculus(token, o++, solved);
        }
        else{
            myCalculus(token, o++, solved);
        }
    }

    public static void multiply(String[] token, int o, int solved){
        if(token[o++].matches("[-+]?\\d*\\.?\\d+")){
            solved = solved + Integer.parseInt(token[o--]) * Integer.parseInt(token[o++]);
            myCalculus(token, o++, solved);
        }
        else{
            myCalculus(token, o++, solved);
        }
    }

    public static void compare(String[] token, int o, int solved){
        if(token[o++].matches("[-+]?\\d*\\.?\\d+")){
            if(token[o].equals("<")){
                solved = solved + ((Integer.parseInt(token[o--]) < Integer.parseInt(token[o++])) ? 1 : 0);
            }
            else if(token[o].equals(">")){
                solved = solved + ((Integer.parseInt(token[o--]) > Integer.parseInt(token[o++])) ? 1 : 0);
            }
            else if(token[o].equals("<=")){
                solved = solved + ((Integer.parseInt(token[o--]) <= Integer.parseInt(token[o++])) ? 1 : 0);
            }
            else{
                solved = solved + ((Integer.parseInt(token[o--]) >= Integer.parseInt(token[o++])) ? 1 : 0);
            }
            myCalculus(token, o++, solved);
        }
        else{
            myCalculus(token, o++, solved);
        }
    }
}

Upvotes: 0

Views: 70

Answers (2)

RealSkeptic
RealSkeptic

Reputation: 34628

Parameters in Java are passed by value, not by reference.

None of your methods ever returns a value. You seem to expect that solved will contain the final value, but it won't, because it's passed by value.

For the same reason, there is really no need for all the ++ operators. You should just pass o+1 to the lower levels. It's not going to affect the "o" variables in upper levels of the recursion!

Finally, there is no point in the while loop in your myCalculus method, because you proceed through recursion inside of your other methods. So the while will just cause the calculation to be wrong.

Also note that your handling of parentheses is probably wrong. You are not handling a closing bracket anywhere, and this will probably also lead to wrong calculations.

Upvotes: 1

codebox
codebox

Reputation: 20254

I think you need to change your recursive calls to use ++o rather than o++:

myCalculus(token, ++o, solved);

your current code will only increment o after the call to myCalculus so whenever you encounter a bracket your code will enter an infinite loop.

Upvotes: 0

Related Questions