避免从字符串流中抓取任何内容

sj7*_*755 2 c++ string parsing stringstream

我正在为一个非常基本的ISA工作.目前我正在实现解析器函数,我正在使用字符串流来从行中获取单词.这是汇编代码的示例:

; This program counts from 10 to 0
        .ORIG x3000
        LEA R0, TEN     ; This instruction will be loaded into memory location x3000
        LDW R1, R0, #0
START   ADD R1, R1, #-1
        BRZ DONE
        BR  START
                        ; blank line
DONE    TRAP    x25     ; The last executable instruction
TEN     .FILL   x000A   ; This is 10 in 2's comp, hexadecimal
        .END
Run Code Online (Sandbox Code Playgroud)

不要担心汇编代码的性质,只需看第3行,右边有注释的那一行.我的解析器功能不完整,但这就是我所拥有的:

// Define three conditions to code
enum {DONE, OK, EMPTY_LINE};
// Tuple containing a condition and a string vector
typedef tuple<int,vector<string>> Code;

// Passed an alias to a string
// Parses the line passed to it
Code ReadAndParse(string& line)
{

    /***********************************************/
    /****************REMOVE COMMENTS****************/
    /***********************************************/
    // Sentinel to flag down position of first
    // semicolon and the index position itself
    bool found = false;
    size_t semicolonIndex = -1;

    // Convert the line to lowercase
    for(int i = 0; i < line.length(); i++)
    {
        line[i] = tolower(line[i]);

        // Find first semicolon
        if(line[i] == ';' && !found)
        {
            semicolonIndex = i;
            // Throw the flag
            found = true;
        }
    }

    // Erase anything to and from semicolon to ignore comments
    if(found != false)
        line.erase(semicolonIndex);


    /***********************************************/
    /*****TEST AND SEE IF THERE'S ANYTHING LEFT*****/
    /***********************************************/

    // To snatch and store words
    Code code;
    string token;
    stringstream ss(line);
    vector<string> words;

    // While the string stream is still of use
    while(ss.good())
    {
        // Send the next string to the token
        ss >> token;
        // Push it onto the words vector
        words.push_back(token);

        // If all we got was nothing, it's an empty line
        if(token == "")
        {
            code = make_tuple(EMPTY_LINE, words);
            return code;
        }
    }

    /***********************************************/
    /***********DETERMINE OUR TYPE OF CODE**********/
    /***********************************************/


    // At this point it should be fine
    code = make_tuple(OK, words);
    return code;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,Code元组包含enum decleration中表示的条件和包含该行中所有单词的向量.我想要的是将一行中的每个单词都推入向量然后返回.

问题的第三次调用(汇编代码的第三行)出现了问题.我使用ss.good()函数来确定我是否在字符串流中有任何单词.由于某种原因,即使第三行中没有第四个单词,ss.good()函数也会返回true,并且最终将[lea] [r0,] [ten]和[ten]这些单词推入向量中.ss.good()在第四次调用时为真,令牌没有收到任何内容,因此我[10]将两次推入向量.

我注意到如果删除分号和最后一个单词之间的空格,则不会发生此错误.我想知道如何将正确数量的单词推入向量中.

请不要推荐Boost库.我喜欢这个图书馆,但我想让这个项目变得简单.这没什么大不了的,这个处理器只有十几个指令.另外,请记住,这个功能只是半生不熟,我正在逐步测试和调试它.

NPE*_*NPE 5

仅在条件(例如到达流的末尾)发生之后才设置流的错误标志.

尝试用以下方法替换循环条件:

while(ss >> token)
{
    // Push it onto the words vector
    words.push_back(token);

    // If all we got was nothing, it's an empty line
    if(token == "")
    {
        code = make_tuple(EMPTY_LINE, words);
        return code;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用此代码,我获得第3行的以下标记:

"LEA"
"R0,"
"TEN"
";"
"This"
"instruction"
"will"
"be"
"loaded"
"into"
"memory"
"location"
"x3000"
Run Code Online (Sandbox Code Playgroud)

我知道你要解析的语言很简单.尽管如此,如果您考虑使用专门的工具来完成工作,例如,您也可以帮到自己flex.