2017-01-24 74 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 */ 

這需要更多的錯誤處理,效果顯着。

相關問題