【问题标题】:Improving efficiency of std::string in a compiler提高编译器中 std::string 的效率
【发布时间】:2013-10-26 20:09:08
【问题描述】:

我正在尝试为类似 C 的语言的编译器构建扫描仪,并且正在寻找一种生成令牌的有效方法...我有一个扫描功能:

vector<Token> scan(string &input);

还有一个 main 函数,它读入一个词法正确的文件并删除 cmets。 (该语言不支持/* , */ cmets)我正在使用具有最大咀嚼能力的 DFA 来生成令牌......而且我很确定扫描仪的一部分相当有效。然而,扫描仪不能很好地处理大文件,因为它们都以一个字符串结尾......并且文件的 1000 行与第 1001 行的所有连接都破坏了扫描仪。不幸的是,我的 FSM 无法处理 cmets,因为它们可以包含任何 Unicode 和其他奇数字符。我想知道......有没有更好的方法从标准输入中的文件到标记向量,记住函数扫描必须采用单个字符串并返回单个向量,并且所有标记都必须在扫描结束时的单个向量...无论如何,这是“扫描”的代码:请不要太嘲笑我的坏主意:)

string in = "";
string build;
while(true)
{
    getline(cin, build);
    if( cin.eof() ) 
    break;

    if(build.find ("//") != string::npos)
    build = build.substr(0, build.find("//",0));

    in += " " + build;
}

try {
  vector<Token> wlpp = scan(in);
  ...
  ...

【问题讨论】:

    标签: c++ performance stdin tokenize lexical-analysis


    【解决方案1】:

    您可能需要考虑的几件事:

    in += " " + build;
    

    效率非常低,可能不希望你在那个循环中,但这似乎不是你遇到问题的地方。 (至少,了解一下输入的大小并在此之前执行in.reserve(size)

    扫描仪的更好设计可能是作为一个类,它将输入文件包装为istream_iterator&lt;Token&gt;,并为令牌实现适当的operator&gt;&gt;。如果你真的想要它在一个向量中,你可以做类似vector&lt;Token&gt; v(istream_iterator&lt;Token&gt;(cin), istream_iterator&lt;Token&gt;()); 的事情并完成它。然后,您的 operator&gt;&gt; 会吞下 cmets 并在返回之前填充一个令牌。

    【讨论】:

    • 这似乎是一个很好的解决方案,但是它让我想到了使用字符串流而不是 + 运算符,你知道这与使用 istream_iterator 相比如何吗?
    猜你喜欢
    • 2011-08-11
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多