c/c++语言开发共享Flex,连续扫描流(来自sockets)。 我是否错过了使用yywrap()的东西?

使用Flex进行模式识别,使用基于套接字的扫描仪(连续流)。 Flex没有找到与’array bounderies’重叠的匹配项。 所以我实现了yywrap()来设置新的数组内容,因为yylex()检测到(它将调用yywrap)。 到目前为止没有成功。

基本上(针对我的问题)这是我的代码:

%{ #include  #include  #include  #define BUFFERSIZE 26 /* 0123456789012345678901234 */ char cbuf1[BUFFERSIZE] = "Hello everybody, lex is su"; // Warning, no '' char cbuf2[BUFFERSIZE] = "per cool. Thanks! "; char recvBuffer[BUFFERSIZE]; int packetCnt = 0; YY_BUFFER_STATE bufferState1, bufferState2; %} %option nounput %option noinput %% "super" { ECHO; } . { printf( "%c", yytext[0] );} %% int yywrap() { int retval = 1; printf(">> yywrap()n"); if( packetCnt <= 0 ) // Stop after 2 { // Copy cbuf2 into recvBuffer memcpy(recvBuffer, cbuf2, BUFFERSIZE); // yyrestart(NULL); // ?? has no effect // Feed new data to flex bufferState2 = yy_scan_bytes(recvBuffer, BUFFERSIZE); // packetCnt++; // Tell flex to resume scanning retval = 0; } return(retval); } int main(void) { printf("Lenght: %dn", (int)sizeof(recvBuffer)) ; // Copy cbuf1 into recvBuffer memcpy(recvBuffer, cbuf1, BUFFERSIZE); // packetCnt = 0; // bufferState1 = yy_scan_bytes(recvBuffer, BUFFERSIZE); // yylex(); yy_delete_buffer(bufferState1); yy_delete_buffer(bufferState2); return 0; } 

这是我的输出:

 dkmbpro:test dkroeske$ ./text Lenght: 26 Hello everybody, lex is su>> yywrap() per cool. Thanks! >> yywrap() 

所以没有匹配’超级’。 根据文件,lexxer不会在yywrap之间“重置”。 我错过了什么? 谢谢。

    flex提供输入流的机制是提供YY_INPUT宏的定义,每当flex需要重新填充其缓冲区时调用该宏[注1]。 使用三个参数调用宏,大致如下:

     YY_INPUT(buffer, &bytes_read, max_bytes) 

    期望宏将max_bytes读入buffer ,并将bytes_read设置为读取的实际字节数。 如果此流中没有其他输入, YY_INPUT应将bytes_read设置为YY_NULL (为0)。 除了设置文件结束条件之外,无法标记输入错误。 不要将YY_INPUT设置为负值。

    请注意, YY_INPUT不提供从何处读取输入或任何类型的userdata参数的指示。 唯一提供的机制是全局yyin ,它是一个FILE* 。 (您可以使用fdopen从文件/套接字描述符创建FILE*并使用fileno返回描述符。其他解决方法超出了本答案的范围。)

    当扫描程序遇到流的结尾时,如YY_INPUT返回0所示,它完成当前令牌[注释2],然后调用yywrap来决定是否还有另一个要处理的流。 如手册所示,它不会重置解析器状态(即,它恰好位于哪个启动条件;如果启用了行计数,则为当前行号等)。 但是, 它不允许令牌跨越两个流。

    当解析器/扫描程序应用于命令行上指定的许多不同文件时,最常使用yywrap机制。 在该用例中,如果令牌可以在一个文件中启动并继续到另一个文件中,则会有点奇怪; 大多数语言实现更喜欢他们的文件在某种程度上是独立的。 (例如,考虑多行字符串文字。)通常,您实际上也希望重置更多的解析器状态(行号,当然,有时是开始条件),但这是yywrap的责任。 [注3]

    对于来自套接字的lexing,您可能希望从YY_INPUT实现中调用recv 。 但是出于实验目的,这里是一个简单的YY_INPUT ,只返回内存缓冲区中的数据:

     /* Globals which describe the input buffer. */ const char* my_in_buffer = NULL; const char* my_in_pointer = NULL; const char* my_in_limit = NULL; void my_set_buffer(const char* buffer, size_t buflen) { my_in_buffer = my_in_pointer = buffer; my_in_limit = my_in_buffer + buflen; } /* For debugging, limit the number of bytes YY_INPUT will * return. */ #define MY_MAXREAD 26 /* This is technically incorrect because it returns 0 * on EOF, assuming that YY_NULL is 0. */ #define YY_INPUT(buf, ret, maxlen) do {  size_t avail = my_in_limit - my_in_pointer;  size_t toread = maxlen;  if (toread > avail) toread = avail;  if (toread > MY_MAXREAD) toread = MY_MAXREAD;  *ret = toread;  memcpy(buf, my_inpointer, toread);  my_in_pointer += toread;  } while (0) 

    笔记

    感谢大米 ,答案是重新定义YY_INPUT宏。 所以我做了:

     #undef YY_INPUT #define YY_INPUT(buf, result, max_size) inputToFlex(buf, &result, max_size) .... void inputToFlex(char *buf, unsigned long int *result, size_t max_size) { if( recv(psock, recvBuffer, RECVBUFFERSIZE, MSG_WAITALL) ) { memcpy(buf, recvBuffer, RECVBUFFERSIZE ); *result = RECVBUFFERSIZE; } else { *result = YY_NULL; } } 

    这很好用,它在套接字关闭时调用yywrap()(由客户端调用)。 备注我使用的MSG_WAITALL而不是更常见的’0’。

    另请注意rici的评论2.如果您的扫描仪需要查看我的解决方案是不够的,您需要实现’1字符重叠缓冲管理’。

    谢谢你。 (它对二进制流也很有用)

      以上就是c/c++开发分享Flex,连续扫描流(来自sockets)。 我是否错过了使用yywrap()的东西?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/568972.html

      (0)
      上一篇 2021年2月24日
      下一篇 2021年2月24日

      精彩推荐