Java 什么';我的brainfuck解析器代码有什么问题?

Java 什么';我的brainfuck解析器代码有什么问题?,java,parsing,brainfuck,esoteric-languages,Java,Parsing,Brainfuck,Esoteric Languages,我正在尝试用Java编写一个可以读取、编译和运行源文件(.bf)的程序。我已经让它与维基百科的Hello World示例配合得很好,但是它在ROT13示例上出现了中断(声称它在实际匹配时达到了一个不匹配的]) 实际的解析器代码都写在一个.JAVA文件中,但它的核心(实际的brainfuck解析器和运行代码)在下面的方法中,doNow(char)。以下是变量的内容:cells是要运行的字符数组(char[])pointer是指向数组中地址的Java变通方法(short)PC是程序计数器(int),

我正在尝试用Java编写一个可以读取、编译和运行源文件(
.bf
)的程序。我已经让它与维基百科的Hello World示例配合得很好,但是它在ROT13示例上出现了中断(声称它在实际匹配时达到了一个不匹配的
]

实际的解析器代码都写在一个
.JAVA
文件中,但它的核心(实际的brainfuck解析器和运行代码)在下面的方法中,
doNow(char)
。以下是变量的内容:
cells
是要运行的字符数组(
char[]
pointer
是指向数组中地址的Java变通方法(
short
PC
是程序计数器(
int
),而
loopStack
是一堆地址,对应于
[
s(基本上是
短[]
)。这些都不是问题,因为它们在Hello World测试中工作得很好。接受输入的方法会自动过滤掉多余的字符,我通过调试检查确认它工作得很好

为什么这个解析器不运行ROT 13代码?

代码
我的解析器,用Java编写

  /** The array of data */
  private byte[] cells = new byte[Short.MAX_VALUE];
  /** The pointer that is manipulated by the user or program */
  private short pointer = 0;
  /** The program counter, to run compiled programs */
  private int PC = 0;
  /** The compiled commands */
  private ArrayPP<Character> commandBuffer = new ArrayPP<>();
  /** The stack of locations of loop brackets ({@code [}) in the command buffer */
  private ArrayPP<Short> loopStack = new ArrayPP<>();//ArrayPP is my proprietary augmented array object, which also functions as a perfectly working stack.

  public int doNow(char command) throws IOException
  {
    PC++;
    switch (command)
    {
      case '>':
        return ++pointer;
      case '<':
        return --pointer;
      case '+':
        return ++cells[pointer];
      case '-':
        return --cells[pointer];
      case '.':
        System.out.print((char)cells[pointer]);
        return 0;
      case ',':
        return cells[pointer] = (byte)System.in.read();
      case '[':
        if (cells[pointer] == 0)//If we're ready to skip this conditional
        {
          int oldPC = PC;
          try
          {
            while (getCompiledCommand(PC) != ']')//Find the matching ]
              PC++;
            PC++;//Now that we're at the ], skip over it to the next command
          }
          catch (ArrayIndexOutOfBoundsException e)
          {
            throw new NullPointerException("Unmatched '[' at " + oldPC);//If we try to reference a command outside the buffer
          }
        }
        else//if we want to enter this conditional
          loopStack.push(PC - 1);//Add the location of this conditional to the list of conditionals which we are in
        return PC;
      case ']':
        try
        {
          return PC = loopStack.pop();//Move us to the matching [ and remove it from the list of conditionals we're in
        }
        catch (ArrayIndexOutOfBoundsException e)
        {
          throw new NullPointerException("Unmatched ] at " + PC);//If the loop stack is empty
        }
      default:
        throw new AssertionError(command + " is not a valid command.");
    }
  }
  public char getCompiledCommand(int commandIndex)
  {
    return commandBuffer.get(commandIndex);//Look into the buffer of precompiled commands and fetch the one at the given index
  }
为了说明这一点,这里是它的转折点:

            >[+[<+>-]>+>>]   Special case: increase remainder / move it back to divisor / increase quotient
                         ^
[+[-]>+>]特殊情况:增加余数/将其移回除数/增加商
^

您应该跟踪“[]”案例分支中的“[]”嵌套:现在,
[++[----]+]
中第一个“[]”的匹配是第一个“]”,这是不好的。

问题
问题似乎出在这一行:

            while (getCompiledCommand(PC) != ']')//Find the matching ]
这在Hello World程序中运行良好,因为它没有嵌套循环。但是,使用嵌套循环时,我们遇到了一个问题,即它遇到了第一个遇到的
]
,但并不总是匹配的
]

修理
一种可能的修复方法是在while循环之前引入一个变量,比如说
loopCount
,并在每次遇到
[
时将其递增,然后在遇到
]
loopCount
大于0时将其递减。例如:

        int loopCount = 0;
        while ((command = getCompiledCommand(PC)) != ']' && loopCount == 0)//Find the matching ]. We can save the return in command because we're done using it.
        {
          if (command == '[')//If we run into a nested loop
            loopCount++;
          else if (command == ']')//If we run into the end of a nested loop
            loopCount--;

          PC++;
        }

@怎么了?太久了?您想要Java变量的声明吗?这不重要;问题在于posted方法。不过,我会为您添加它们。是否知道嵌套的“['-']”呢?如果是这样,当您看到“[”,您将前进到第一个“]”,这是错误的,例如
[+++[----]+]
-第一个“[”与第一个“]”匹配。您的“Hello world”只包含一对,这就是它工作的原因。@Supuhstar,实际上没有什么问题。我希望有人能帮你。但是如果读者能够运行你的代码,那么发现问题就会容易得多。哦,是的。对不起
getCompiledCommand(int)
只返回从文件或其他文本输入源加载到内存中的字符。它不知道任何事情,也没有条件逻辑。不过,我明白你的意思。你能把它作为一个答案吗?@Supuhstar,我也认为你应该输出并包括异常细节。特别是堆栈跟踪。是的,我在你发表评论指出它之前就发现了这一点。我仍然会接受你的回答,但我也发布了我的解决方案:3
            while (getCompiledCommand(PC) != ']')//Find the matching ]
        int loopCount = 0;
        while ((command = getCompiledCommand(PC)) != ']' && loopCount == 0)//Find the matching ]. We can save the return in command because we're done using it.
        {
          if (command == '[')//If we run into a nested loop
            loopCount++;
          else if (command == ']')//If we run into the end of a nested loop
            loopCount--;

          PC++;
        }