如何防止 Flex 丢弃 yyinput 字符?
How can I prevent Flex from discarding yyinput characters?
我正在尝试读取 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 = '[=11=]'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
这意味着 yytext 没有获得额外的 literal_length 个字符。如果可以避免的话,我宁愿不创建一个新的缓冲区来存储它们,因为我知道字符序列已经在内存中了。
除了完全重新定义yyinput(),有没有办法保留yytext中多余的字符?
您正在匹配 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 的一部分了)。
您可以在单独的状态下匹配数字,当您拥有所有数字时终止状态:
%{
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 */
显然,这需要更多的错误处理。
我正在尝试读取 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 = '[=11=]'; /* preserve yytext */
yy_hold_char = *++yy_c_buf_p;
这意味着 yytext 没有获得额外的 literal_length 个字符。如果可以避免的话,我宁愿不创建一个新的缓冲区来存储它们,因为我知道字符序列已经在内存中了。
除了完全重新定义yyinput(),有没有办法保留yytext中多余的字符?
您正在匹配 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 的一部分了)。
您可以在单独的状态下匹配数字,当您拥有所有数字时终止状态:
%{
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 */
显然,这需要更多的错误处理。