0

假设我正在编写一个解释器,它的一个命令具有以下形式

define variable

其中变量只能是小写拉丁字母。

这就是我正在做的事情。在确定命令是定义命令后,我从字符串创建一个流,比如"define a"(iss),然后从中读取命令名称,断言它确实是“定义”。

std::istringstream iss(Command);
//read the word "define"
std::string cmdstr;
assert(iss >> cmdstr);
assert(cmdstr == DefineStr);

然后我从流中读取一个字符。阅读应该成功,所以我检查

if(!(iss >> var))
{
    errorMsg = "Invalid syntax of define command. Too few arguments\n";
    return false;
}

然后我必须检查流中没有更多的非空格字符,所以我检查

//the rest of the line must be empty;
if(iss >> var)
{
    errorMsg = "Invalid syntax of define command. Too many arguments\n";
    return false;
}

我测试流中有更多字符的策略是否错误?我知道我可以使用正则表达式、精神解析器等来解决这个问题,但假设我希望坚持这种方法。问题是,在调试模式(MSVC10.0)下,当我输入时,该函数按预期工作,define a而在发布模式下,该函数以某种方式进入if(iss >> var)并说Invalid syntax of define command. Too many arguments。我被卡住了,我不明白出了什么问题。

该函数的完整代码如下:

bool Interpreter::ExecuteDefineCommand(const std::string& Command, std::string& errorMsg)
{
    std::istringstream iss(Command);

    //read the word "define"
    std::string cmdstr;
    assert(iss >> cmdstr);
    assert(cmdstr == DefineStr);

    //read the variable name
    char var;
    if(!(iss >> var))
    {
        errorMsg = "Invalid syntax of define command. Too few arguments\n";
        return false;
    }
    if(!islower(var))
    {
        errorMsg = "You may define only lowercase variables\n";
        return false;
    }

    //the rest of the line must be empty;
    if(iss >> var)
    {
        errorMsg = "Invalid syntax of define command. Too many arguments\n";
        return false;
    }

    auto insertRes = variables.insert(std::make_pair(var, 0));

    if(!insertRes.second)
    {
        errorMsg = "The variable ";
        errorMsg += var;
        errorMsg += " has already been defined!\n";
        return false;
    }

    return true;
}
4

1 回答 1

0

问题在这里:

std::string cmdstr;
assert(iss >> cmdstr);
assert(cmdstr == DefineStr);

因为 operator >> 在 assert 内部,所以它不会在 Release 模式下执行!正确的方法是

std::string cmdstr;
iss >> cmdstr;
assert(iss);
assert(cmdstr == DefineStr);
于 2013-04-29T11:17:42.760 回答