使用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