-1

因此,我正在用 Java 制作一个笨拙的解释器,除了 [ 和 ] 之外,我没有任何问题。(不可避免地)问题在于解析字符串。所以我处理循环的方法是将代码定位在两个括号之间,然后调用函数(递归)来重做括号内的代码。这在纸上听起来不错,但substring不与我合作。这是我处理 [

void openBracket(short i, String brainfuck)
    {
        /*LOGIC EXPLAINED: First set balance = 1, then loop through all characters after this,
         if another opening bracket is found increment balance, if a close bracket is found, 
         decrement balance. Also, when another close bracket is found test if balance is 1, if
         so then this is the proper bracket*/
        String codeSection = brainfuck.substring(i);
        short balance = 1;
        String codeToRedo;
        short endPoint = -1;

        for (short j = i; j < codeSection.length(); j++) 
        {
        //Check the character
        if (codeSection.charAt(j) == '[') 
        {
            balance++;
        } else if (codeSection.charAt(j) == ']') 
        {
            balance--;

        }
        //Check if it's the right bracket
        if (balance == 1) {
            endPoint = j;
        }
        }

        //Only do such a thing if the cell is not equal to 0
        if (cell[pointer] > 0 && endPoint != -1) 
        {
        codeToRedo = brainfuck.substring(i, endPoint);
        output += brainfuckExecute(codeToRedo);
        } 
        else if (endPoint == -1) //If endpoint is equal to -1, that means that there was no closing bracket
        {
        errorList += "ERROR: No closing bracket (" + i + ")";
        }
    }

我对缩进表示歉意,它没有很好地从 Netbeans 复制。但无论如何,正如您在代码顶部看到的那样,我创建了一个名为“codeSection”的变量,它应该包含正确的文本。这是我为参数“brainfuck”给出的内容:+++[>+++++ +++++<-]>+++.这是我打印变量时得到的内容:

[>+++++ +++++<-]>+++.
[>+++++ +++

是的,我用 System.out.println 打印变量,我打印了两个不同的东西。第一次,它是正确的字符串。我第二次得到处理的内容,并且没有右括号。我在brainfuck的代码中安装了一个错误检查系统,所以我可以检查一下。我得到了我应该的错误。(错误:没有右括号(0))我真的对此感到茫然和困惑,因此非常感谢提供的任何帮助。

PS 额外代码,例如它的调用位置等:它的调用位置:

String brainfuckExecute(String brainfuck)
    {
        //Reset the output
        output = "";

        //Loop through all instructions
        for(short i = 0; i < brainfuck.length(); i++)
        {
        //Execute a switch to do the instructions
        switch(brainfuck.charAt(i))
        {
            //Increment current cell
            case '+': 
            incrementCell();
            break;
            //Decrement current cell
            case '-': 
            decrementCell(i);
            break;
            //Move pointer up
            case '>': 
            incrementPointer(i);
            break;
            //Move pointer down
            case '<': 
            decrementPointer(i);
            break;
            //Get user input and store it in the current cell
            case ',': 
            getInput();
            break;
            //Add the cell to the output string
            case '.': 
            addOutput();
            break;
            //Start the while loop -- Recurssive
            case '[': 
            openBracket(i, brainfuck);
            break;
        }
        }

        //Return said output
        return output;
    }

(它在一个包含所有这些变量的类中)其中 main 是:

Brainfuck codeTranslator = new Brainfuck();
    System.out.println(codeTranslator.brainfuckExecute("+++[>+++++ +++++<-]>+++."));
    System.out.println(codeTranslator.getErrors());

再次感谢

4

1 回答 1

4

当您第一次调用openBracket()时,您有i == 3brainfuck == "+++[>+++++ +++++<-]>+++."。因此,在第一个substring()电话中,您会得到:

String codeSection = brainfuck.substring(3);

结果是:

String codeSection = "+++[>+++++ +++++<-]>+++.".substring(3);
String codeSection = "[>+++++ +++++<-]>+++."

然后你循环codeSection看看它是否平衡。问题是您已经剪掉了 之前的部分[,但是您从 开始循环j = 3。我将用 标记当前索引位置( ),以便更容易理解:

您在以下位置开始循环j = 3

[>+(+)+++ +++++<-]>+++.

直到j = 14,这是-之前的索引]

[>+++++ +++++<(-)]>+++.

由于您没有找到第一个,所以一直是[值。所以,最后,你做到了。balance1endPoint = 14

if (balance == 1) {
    endPoint = j;
}

在下一次迭代中,您会发现], 并balance递减为0,因此循环继续进行但endPoint不会再次更新。

在此之后,您执行以下操作:

codeToRedo = brainfuck.substring(i, endPoint);

结果是:

codeToRedo = brainfuck.substring(3, 14);
codeToRedo = "+++[>+++++ +++++<-]>+++.".substring(3, 14);
codeToRedo = "[>+++++ +++";

我猜你的循环应该是:

for (short j = 0; j < codeSection.length(); j++) { ... }

最后,要仅获取brainfuck括号之间的部分,您应该注意到,当balance为 1 时,您会不断更新endPoint. 我想你想在找到平衡支架时停下来,所以你可以break在你的if:

for (short j = 0; j < codeSection.length(); j++) {
    //Check the character
    if (codeSection.charAt(j) == '[') {
        balance++;
    } else if (codeSection.charAt(j) == ']') {
        balance--;
    }
    //Check if it's the right bracket
    if (balance == 1) {
        endPoint = j;
        break; // Stop when you find the ] position
    }
}

然后做:

codeToRedo = brainfuck.substring(i + 1, i + endPoint);

或者:

codeToRedo = codeSection.substring(1, endPoint);

此外,您可以连接brainfuckExecute()when you do的结果output += brainfuckExecute(codeToRedo)。这可能就是为什么它看起来像打印两次的原因。

于 2015-03-29T03:43:39.653 回答