簡體   English   中英

如何修復自制解析器中的堆棧溢出?

[英]How to fix stack overflow in self-made parser?

我正在為類創建一個解析器。 用戶必須在等式中輸入每個元素之間的空格。 然后,將每個元素讀入其自己索引中的同一數組。 我一直在堆棧溢出。 我認為這是因為只有myCalculus函數的最后一個調用實際上才關閉。 不過,如果是這種情況,我不確定如何組織代碼來避免這種情況。 在此先感謝您的幫助。

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);
        }
    }
}

Java中的參數是通過值而不是通過引用傳遞的。

您的任何方法都不會返回值。 您似乎希望solved將包含最終值,但不會,因為它是按值傳遞的。

出於同樣的原因,實際上並不需要所有++運算符。 您應該只將o + 1傳遞到較低級別。 它不會影響遞歸上層的“ o”變量!

最后, myCalculus方法的while循環沒有意義,因為您要在其他方法內部進行遞歸。 因此,一會兒就會導致計算錯誤。

另請注意,您對括號的處理可能是錯誤的。 您不會在任何地方處理右括號,這也可能會導致錯誤的計算。

我認為您需要將遞歸調用更改為使用++o而不是o++

myCalculus(token, ++o, solved);

您的當前代碼只會在調用myCalculus之后遞增o ,因此無論何時遇到方括號,您的代碼都會進入無限循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM