Ich habe dieses Problem für ein paar Tage jetzt fest und so ist dieser Parser. Der Punkt dieses Parsers besteht darin, die HTTP-Anfrage zu parsen und dass es in Ordnung ist, aber wenn das Ende der Anfrage erreicht ist, tritt der Parser in die Endlosschleife ein. Ich habe den Punkt in der C Datei gefunden, die aus Lex-Datei generiert wird, aber keine Ahnung, wie Sie dieses Problem lösen.Lex Yacc Parser bei EOF stecken
Ich habe versucht, die folgenden Ansätze in anderen ähnlichen Fragen ohne Erfolg vorgeschlagen.
lex-flex-scanning-for-the-eof-character
Dies ist meine lex-Datei:
#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);
}
Die Ausführung wird while (/*CONSTCOND*/1)
Schleife stecken und hält zweimal in case YY_END_OF_BUFFER:
eingeben und dann auf einmal in case 126:
in ssolex.c Datei . Die Zeile, die in case 126
angegeben wird, ist die Zeile %%
in Lex-Datei.
/** The main scanner function which does all the work.
*/
YY_DECL
{
yy_state_type yy_current_state;
char *yy_cp, *yy_bp;
int yy_act;
if (!(yy_init))
{
(yy_init) = 1;
#ifdef YY_USER_INIT
YY_USER_INIT;
#endif
if (! (yy_start))
(yy_start) = 1; /* first start state */
if (! ssoin)
ssoin = stdin;
if (! ssoout)
ssoout = stdout;
if (! YY_CURRENT_BUFFER) {
ssoensure_buffer_stack();
YY_CURRENT_BUFFER_LVALUE =
sso_create_buffer(ssoin,YY_BUF_SIZE);
}
sso_load_buffer_state();
}
{
#line 44 "ssolex.l"
#line 1265 "<stdout>"
while (/*CONSTCOND*/1) /* loops until end-of-file is reached */
{
yy_cp = (yy_c_buf_p);
/* Support of ssotext. */
*yy_cp = (yy_hold_char);
/* yy_bp points to the position in yy_ch_buf of the start of
* the current run.
*/
yy_bp = yy_cp;
yy_current_state = (yy_start);
yy_current_state += YY_AT_BOL();
yy_match:
do
{
YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
if (yy_accept[yy_current_state])
{
(yy_last_accepting_state) = yy_current_state;
(yy_last_accepting_cpos) = yy_cp;
}
while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
{
yy_current_state = (int) yy_def[yy_current_state];
if (yy_current_state >= 802)
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
while (yy_base[yy_current_state] != 1067);
yy_find_action:
yy_act = yy_accept[yy_current_state];
if (yy_act == 0)
{ /* have to back up */
yy_cp = (yy_last_accepting_cpos);
yy_current_state = (yy_last_accepting_state);
yy_act = yy_accept[yy_current_state];
}
YY_DO_BEFORE_ACTION;
do_action: /* This label is used only to access EOF actions. */
Letzte, was gedruckt wird, wird ein Token Lesen: die in yacc ist C-Datei, so denke ich, dass das Problem EOF in lex Handhabung sein muss.
/* 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);
}
Versuchen Sie, Daten direkt von einer offenen Netzwerkverbindung zu analysieren? EOF ist nicht dasselbe wie "jetzt ist keine Eingabe mehr verfügbar". Sie werden EOF in einer Netzwerkverbindung nicht sehen, bis die Verbindung geschlossen ist. –
Ja, wie soll ich feststellen, wann ich die Analyse der Daten stoppen soll? –
Verwenden Sie tatsächlich yyless in Ihrem Lexer-Code? – rici