代码之家  ›  专栏  ›  技术社区  ›  rubenvb

从文件读取令牌(复杂)

  •  1
  • rubenvb  · 技术社区  · 14 年前

    我有一个基本的标记化结构/算法。这是相当复杂的,我希望我可以澄清它足够简单,以启发你对我的设计“缺陷”。

    类分析器状态

    // bool functions return false if getline() or stream extraction '>>' fails
    static bool nextLine(); // reads and tokenizes next line from file and puts it in m_buffer
    static bool nextToken(); // gets next token from m_buffer, via fetchToken(), and puts it in m_token
    static bool fetchToken( std::string &token ); // procures next token from file/buffer
    
    static size_t m_lineNumber;
    static std::ifstream m_fstream;
    static std::string m_buffer;
    static std::string m_token;
    

    m_token nextToken 继续。 fetchToken 电话 nextLine m_buffer 为空,并将下一个标记放入其参数中:

    istringstream stream;
    
    do // read new line until valid token can be extracted
    {
        Debug(5) << "m_buffer contains: " << m_buffer << "\n";
        stream.str( m_buffer );
    
        if( stream >> token )
        {
            Debug(5) << "Token extracted: " << token << "\n";
            m_token = token;
            return true; // return when token found
        }
        stream.clear();
    } while( nextLine() );
    // if no tokens can be extracted from the whole file, return false
    return false;
    

    问题是从m_缓冲区删除的令牌没有被删除,并且每次调用 nextToken() m_缓冲器 可以修改,因此调用 istringstream::str stream >> token 从stringstream指向内部的字符串中移除某些内容?也许我需要 使用 stringstream ,但在这种情况下更基本的内容(比如查找第一个空白并从字符串中剪切第一个标记)?

    注:任何修改函数/类结构的建议都是可以的,只要它们允许跟踪行号(所以没有完整的文件被读入 m_缓冲器 istringstream ,这是我之前想要的行号错误报告)。

    3 回复  |  直到 14 年前
        1
  •  1
  •   André Caron    14 年前

    为什么不干脆 m_buffer 一个 std::istringstream 而不是 std::string m_缓冲器

    m_buffer = ...
    

    请改为:

    m_buffer.str(...);
    
        2
  •  0
  •   vitaut    14 年前

    为了避免多次阅读同一个标记,我想你必须得到这个位置 stream tellg 然后使用 seekg (描述了这些方法 here ). 但是使用 std::istringstream 看来我在这有点过分了。我宁愿和 m_buffer 直接的。

        3
  •  0
  •   Ira Baxter    14 年前

    处理行号报告的通常方案是一次读取一行,如您所做的那样,递增行号计数,然后当您的令牌赋予器开始构建令牌时,它获取行号的快照并将其存储到令牌数据结构中(通常包含行号、令牌类型和令牌值(如果有的话)。

    这可以在不丢失行号的情况下将行读取与令牌生成分离。这也意味着你可以有很多标记,它们都可以有行号(包括不同的行号),一个标记可以从一行开始,到另一行结束,等等。