Lex-Yacc解析器卡在EOF上

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

我已经被这个问题困扰了好几天了,这个解析器也是。这个解析器的目的是解析http请求,它可以,但当到达请求的末尾时,解析器进入无限循环。我已经找到了从lex文件生成的C文件中的点,但不知道如何解决这个问题

我在其他类似问题中尝试了以下方法,但没有成功

这是我的lex文件:

#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);
}