我试图读取Flex词法分析器中已知的字符数(在运行时)。我知道它以CRLF开头,所以我匹配它,然后使用yyinput读取literal_length字符。
<EXPECT_LITERAL>"\r\n" {
for(int i=0;i<literal_length;i++){
int c= yyinput(yyg);
if(c == EOF) break;
}
*yylval = val_new_s(yytext);
return(LITERAL);
}
但yyinput不会添加新字符,而是包含:
*yy_c_buf_p = '\0'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
这意味着yytext没有获得额外的literal_length字符。如果我可以避免它,我宁愿不创建一个新的缓冲区来存储它们,因为我知道字符序列已经存在于内存中。
除了完全重新定义yyinput()之外,有没有办法在yytext中保留额外的字符?
答案 0 :(得分:0)
您正在匹配CRLF,因此yytext
包含CRLF。
如果要匹配CRLF后的数字,则需要匹配数字:
%x EXPECT_DIGITS
<EXPECT_LITERAL>\r\n BEGIN(EXPECT_DIGITS); /* ignore otherwise */
<EXPECT_DIGITS>[0-9]* BEGIN(INITIAL); /* parse yytext here */ return LITERAL;
可能已经读取的字符是您不能依赖的实现细节。
你可以在没有特殊状态的情况下稍微简化一下比赛(例如,你可以匹配\r\n[0-9]*
,那么数字已经是yytext的一部分了。)
答案 1 :(得分:0)
您可以在单独的状态下匹配数字,并在拥有所有数字时终止状态:
%{
uint64_t accumulator;
unsigned int remaining_digits;
%}
%x EXPECT_DIGITS
<EXPECT_LITERAL>\r\n BEGIN(EXPECT_DIGITS); remaining_digits = literal_length; accumulator = 0;
<EXPECT_DIGITS>[0-9] accumulator = accumulator * 10 + *yytext - '0'; if(!--remaining_digits) { BEGIN(INITIAL); *yylval = accumulator; return LITERAL; }
<EXPECT_DIGITS>. /* handle non-digits */
显然,这需要更多的错误处理。