尽管逐个字符地读取输入缓冲区溢出

时间:2015-09-30 19:21:40

标签: yacc lex

为了克服lex中输入缓冲区溢出的问题,每当我希望看到一个长字符串时,我编写代码来逐字符地读取输入流,但是,仍然得到错误输入缓冲区溢出,无法放大缓冲区,因为扫描仪使用REJECT

代码段:

<STATE> {identifier} {
    string str = yytext; 
    if(str == "ExpectedStr")
       handleLongStr(str);
    copyString(yylval.str, str);
    return IDENTIFIER; 
}

void handleLongStr(string &str)
{
  str.clear();
  char ch;
  while((ch = yyinput()) != '\n')
    str.push_back(ch);
  unput(ch); 
}

1 个答案:

答案 0 :(得分:0)

yyinput占用了缓冲区中的缓冲区空间,但它不允许您恢复从yytext读取的数据。关于这种行为的唯一原因,我曾经提出过,它允许您unput()尽可能多地input()使用yytext字符而不会破坏input(),这是yyinput如果您使用%% /* Variable is local to a call to yylex */ std::string longtoken; <STATE>{identifier} { /* Personally I'd prefer to use a regex pattern than an if here */ if (is_long_prefix(yytext)) { longtoken.clear(); BEGIN(STATE_LONG_IDENTIFIER); } else { yylval.str = strdup(yytext); return IDENTIFIER; } // ... } <STATE_LONG_IDENTIFIER>{ /* Here we handle subtokens of up to 100 characters. The number * is arbitrary, but the nature of flex is that the resulting DFA * will have one state per repetition, and large repetitions create * a lot of states. */ .{1,100} { longtoken.append(yytext, yyleng); } \n { yylval.str = strdup(longtoken.c_str();); BEGIN(STATE); return IDENTIFIER; } <<EOF>> { error("Unterminated long identifier"); } } 作为窥视下一个输入的方式,则非常有用。

无论出于何种原因,这意味着您无法使用<div id="stem"></div> <div id="wards"> <div class="specialward"></div> <div class="ward"></div> <div class="ward"></div> </div>来避免缓冲区重新分配。所以你需要做下一个最好的事情:处理较小的长令牌。例如,你可以这样做:

.ward {
        /*border: 1px solid #666666;*/
        background-color: #666666;
        position: relative;
        display: inline-block;
        opacity: 1;
        width: 7px;
        height: 12px!important;
        margin-right: -8px;
        overflow: hidden;
    }

.specialward {
        /*border: 1px solid #666666;*/
        background-color: #666666;
        position: relative;
        display: inline-block;
        opacity: 1;
        width: 7px;
        height: 10px!important;
        margin-right: -8px;
        overflow: hidden;
    }