尽管逐个字符读取,但输入缓冲区溢出
Input buffer overflow in spite of reading character by character
为了克服lex中输入缓冲区溢出的问题,我写了代码,每当我希望看到一个长字符串时,一个字符一个字符地读取传入的流,但是,仍然得到输入缓冲区溢出的错误,can' t 扩大缓冲区,因为扫描器使用 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);
}
yyinput
用尽了缓冲区中的缓冲区 space,尽管它不会让您恢复从 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"); }
}
为了克服lex中输入缓冲区溢出的问题,我写了代码,每当我希望看到一个长字符串时,一个字符一个字符地读取传入的流,但是,仍然得到输入缓冲区溢出的错误,can' t 扩大缓冲区,因为扫描器使用 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);
}
yyinput
用尽了缓冲区中的缓冲区 space,尽管它不会让您恢复从 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"); }
}