Lex-Yacc解析器卡在EOF上
我已经被这个问题困扰了好几天了,这个解析器也是。这个解析器的目的是解析http请求,它可以,但当到达请求的末尾时,解析器进入无限循环。我已经找到了从lex文件生成的C文件中的点,但不知道如何解决这个问题 我在其他类似问题中尝试了以下方法,但没有成功 这是我的lex文件:Lex-Yacc解析器卡在EOF上,c,bison,flex-lexer,yacc,lex,C,Bison,Flex Lexer,Yacc,Lex,我已经被这个问题困扰了好几天了,这个解析器也是。这个解析器的目的是解析http请求,它可以,但当到达请求的末尾时,解析器进入无限循环。我已经找到了从lex文件生成的C文件中的点,但不知道如何解决这个问题 我在其他类似问题中尝试了以下方法,但没有成功 这是我的lex文件: #undef YYLMAX #define YYLMAX 4096 #include "ssoyacc.h" #define yylval ssolval extern YYSTYPE yylval; #ifde
#undef YYLMAX
#define YYLMAX 4096
#include "ssoyacc.h"
#define yylval ssolval
extern YYSTYPE yylval;
#ifdef FLEX_SCANNER
#define YY_INPUT(buf, result, max_size) { int cc = sso_read(); result = (cc == -1) ? YY_NULL : (buf[0] = cc, 1);}
#else /* NO FLEX */
#undef input
#define input() sso_read()
#define unput(cc) sso_unput(cc)
#define yyless(cc) sso_yyless(cc)
#endif /* FLEX */
%}
%p 30000
%n 4000
%e 2000
%a 30000
%k 2500
%o 50000
nondigit [_a-zA-Z]
alfanum [_a-zA-Z0-9]
digit [0-9]
nonzero_digit [1-9]
octal_digit [0-7]
hexadecimal_digit [0-9a-fA-F]
%start HTTP QUERY ARG XML TAG CDAT FORM_PARAM FORM_VALUE
%%
<INITIAL,HTTP>[ ] {
return SP;
}
<INITIAL,HTTP>\r\n {
return CRLF;
}
<HTTP>HTTP\/{digit}\.{digit} {
return HTTP_VERSION;
}
<HTTP>OPTIONS {
return OPTIONS;
}
<HTTP>GET {
return GET;
}
.
.
.
other tags
.
.
.
<FORM_PARAM>\= {
BEGIN(FORM_VALUE);
return IS;
}
<FORM_VALUE>\& {
BEGIN(FORM_PARAM);
return AMPERSAND;
}
<FORM_VALUE>[0-9a-zA-Z\%\+\.\/]* {
if (yyleng < MAX_ARG_LEN)
{
char cc[3];
int ii;
int jj = 0;
for (ii=0;ii<yyleng;ii++)
{
if (yytext[ii] != '%')
{
if (yytext[ii] == '+')
{
yylval.sval[jj++] = ' ';
}
else
{
yylval.sval[jj++] = yytext[ii];
}
}
else
{
strncpy(cc, yytext+ii+1, 2);
cc[2] = 0;
yylval.sval[jj++] = strtol(cc, NULL, 16);
ii+=2;
}
}
yylval.sval[jj] = 0;
return STRING;
}
else
{
return ERROR;
}
}
%%
int ssowrap(void)
{
return 1;
}
void start_http()
{
init_content(); /* initialize content count */
BEGIN(HTTP);
}
void start_urlencoded()
{
BEGIN(FORM_PARAM);
}
void start_xml()
{
BEGIN(XML);
}
int sso_yyless(int count)
{
int i;
if (count>yyleng)
{
return 0;
}
for (i=0;i<yyleng-count;i++)
{
unput(yytext[yyleng-1-i]);
yytext[yyleng-1-i] = '\0';
}
return 0;
}
void allprint(wchar_t cc)
{
if (isprint(cc))
{
fprintf(stdout, "'%c' 0x%x", cc, cc);
}
else
{
fprintf(stdout, "%x", cc);
}
}
void sprint(wchar_t *pc)
{
fprintf(stdout, "%s", pc);
}
打印的最后一件事是读取一个令牌:它位于yaccC文件中,所以我认为问题一定是lex中的EOF处理
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = yylex ();
printf("TOKEN %c, %d\n", yychar, yychar);
}
如前所述,
sso\u read
函数没有返回-1,而是返回0。此外,由于tcp套接字仍按应打开,因此从未达到EOF。感谢rici和Jon Bollinger帮助解决这个问题 如前所述,sso_read
函数没有返回-1,而是返回0。此外,由于tcp套接字仍按应打开,因此从未达到EOF。感谢rici和Jon Bollinger帮助解决这个问题 您是否正试图直接从开放网络连接解析数据?EOF与“现在没有更多的输入可用”不是一回事。在网络连接关闭之前,您不会在网络连接上看到EOF。是的,我应该如何确定何时停止解析数据?您是否在lexer代码中实际使用yyless?此外,我认为您需要提供更多信息。您是否验证了请求结束时sso_read
是否返回-1?@rici Yes正在使用yyless。从未调用sso_读取函数。您是否正试图直接从开放网络连接解析数据?EOF与“现在没有更多的输入可用”不是一回事。在网络连接关闭之前,您不会在网络连接上看到EOF。是的,我应该如何确定何时停止解析数据?您是否在lexer代码中实际使用yyless?此外,我认为您需要提供更多信息。您是否验证了请求结束时sso_read
是否返回-1?@rici Yes正在使用yyless。永远不会调用sso_读取函数。
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = yylex ();
printf("TOKEN %c, %d\n", yychar, yychar);
}