2017-01-24 72 views
0

我正在尝试读取Flex词法分析器中字符的已知数字(在运行时)。我知道它以CRLF开头,所以我匹配,然后使用yyinput读取literal_length字符。如何防止Flex丢弃yyinput字符?

<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

您与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的一部分)。

+0

感谢信息西蒙。但是我无法创建一个匹配,直到运行时才知道确切数量的字符。 我知道这些字符被读取,因为调用yyinput()会导致它们被读取。我们可以在预期字符数之前检测EOF是否发生,如果YYINPUT尚未准备好,可以等待YYINPUT等待。所以人们知道这些角色在那里。 我可以重写yyinput()以不销毁传入的字符,但由于这个问题被排除在外,我会接受你的答案为“否”。 – Roderick

+0

@Roderick,这就是星号所做的。 '[0-9]'匹配任何ASCII数字,星号重复匹配。 'yyleng'然后告诉你有多少个字符匹配。 –

+0

星号获取所有可能的字符。问题是获得“literal_length”字符,并且只有那么多。 – Roderick

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 */ 

这需要更多的错误处理,效果显着。

相关问题