首页 > 解决方案 > VM Translator中的向量下标超出范围?

问题描述

作为 nand2tetris 课程的一部分,我一直在研究 VM 翻译器,我花了很长时间试图调试此错误,但无济于事。我尝试捕获错误,但随后引发调试断言错误:向量下标超出范围。

这是几个片段,我会尝试在任何地方包含它被调用的地方。


int Parser::arg2() {

    int arg2 = 0;

    try {
        if (currentCommand.find(" ") != string::npos)
            arg2 = stoi(currentCommand.substr(currentCommand.find_last_of(" "), currentCommand.length()));
        return arg2;
    }
    catch (const std::invalid_argument& ia ) {
        cerr << "Invalid argument: " << ia.what() << endl;
        return 0;
    }
    catch (const std::out_of_range & oor) {
        cerr << "Out of range: " << oor.what() << endl;
        return 0;
    }

    return 0;
} 

这是抛出错误的地方,以下是我从中调用它的地方:

for (const auto& entry : fs::recursive_directory_iterator(dir)) {
        ostringstream oss;
        oss << entry;
        string file = oss.str();

        if (file.find(".vm") != string::npos) {
            Parser parser(file);

            while (true) {
                parser.advance();
                if (!parser.hasMoreCommands()) break;
                if (parser.commandType() == "C_ARITHMETIC") writer.writeArithmetic(parser.command());

                if (parser.commandType() == "C_BRANCHING") writer.writeBranching(parser.command(), parser.arg1(), parser.arg2());
                if (parser.commandType() == "C_POP") writer.writePushPop("C_POP", parser.arg1(), parser.arg2());
                if (parser.commandType() == "C_PUSH") writer.writePushPop("C_PUSH", parser.arg1(), parser.arg2());
            }
        }
        else continue;  
    }

在调试时,我尝试注释掉 writeBranching 行并删除了导致我认为该方法有问题的错误,所以这里也是一个:

void Writer::writeBranching(string command, string name, int numArgs) {
    cout << "HITTING:" << command << endl;
    if (command == "goto") writeGoTo(name); return;
    if (command == "if-goto") writeIf(name); return;
    if (command == "label") writeLabel(name); return;
    if (command == "call") writeCall(name, numArgs); return;
    if (command == "function") writeFunction(name, numArgs); return;
    if (command == "return") writeReturn(); return;
}

使用调试器并单步执行并没有太大帮助,它可以在崩溃之前成功运行和解析所有这些方法至少一次,所以我很迷茫。

这是我正在解析的文件:

function Main.fibonacci 0
push argument 0
push constant 2
lt                     // checks if n<2
if-goto IF_TRUE
goto IF_FALSE
label IF_TRUE          // if n<2, return n
push argument 0        
return
label IF_FALSE         // if n>=2, returns fib(n-2)+fib(n-1)
push argument 0
push constant 2
sub
call Main.fibonacci 1  // computes fib(n-2)
push argument 0
push constant 1
sub
call Main.fibonacci 1  // computes fib(n-1)
add                    // returns fib(n-1) + fib(n-2)
return

最后是第一个解析的输出(我相信它在翻译阶段之前就崩溃了):

function Main.fibonacci 0
push argument 0
ARG 0
push constant 2
constant 2
lt
if-goto IF_TRUE
Invalid argument: invalid stoi argument
goto IF_FALSE
Invalid argument: invalid stoi argument
label IF_TRUE
Invalid argument: invalid stoi argument
push argument 0
Invalid argument: invalid stoi argument
ARG 0
return

标签: c++code-translation

解决方案


推荐阅读