2012-03-13 20 views
1

我在頭文件中定義了一些常量,這些常量包含由flex/bison中寫入的文件解析器解析的某些字符串的最大長度。我想將檢查字符串長度的代碼從c代碼移到我的正則表達式中,以使事情更簡潔一些。在flex規則中使用外部定義的常量

現在我有一個看起來像規則:

[[:alnum:]]+ { yylval.sval = (char*) strdup(yytext); return STRING; } 

凡長度檢查發生在野牛規則。

我想修改這一點,以便它檢查比賽比MAX_STR_LEN不再這是在頭叫constants.h定義。如果MAX_STR_LEN等於32,比我想同樣的效果:

[[:alnum:]]{1,32} 

反正有沒有做到這一點無需經過預處理的額外步驟運行我的Flex文件?

編輯:

下面的規則將失敗,因爲MAX_STR_LEN不是文字數,它被看作是一個字符串,因此柔性認爲2個行動已經爲一個規則定義。

[[:alnum:]]{1,MAX_STR_LEN} { do_something(); } 

另外如果試圖向限定在flex文件的聲明部分的宏比它也失敗本身。

max_len 32 /* Also fails if 32 is replaces with MAX_STR_LEN */ 
%% 
[[:alnum:]]{1,max_len} { do_something(); } 

回答

2

你可以在動作規則處理它:

[[:alnum:]]+ { if (yyleng > MAX_STR_LEN) yyless(MAX_STRING_LEN); 
        yylval.sval = (char*) strdup(yytext); return STRING; } 

這使得規則有效地與您的{1,MAX_STR_LEN}修改器我已經包括常量頭圖案

+0

請注意,如果您執行了上述'yyless',則您將重新掃描作爲另一個'STRING'標記的多餘部分,給出掃描儀中的其他功能。這實際上是原始問題的問題,但至少可以說,將ABCDEFG作爲三個單獨的字符串ABC,DEF,G(使用3作爲此示例的最大值)是非常不尋常的。 (這也是低效率的,但是再次,所以呢?) – torek 2012-03-22 19:15:43

+0

這可能是最接近我最初問的。我確實決定採取這種方法,因爲它看起來更靈活一些。 – msikora 2012-03-24 21:41:28

1

Flex生成一個C源文件。在這個C源文件的頂部是「任意的C代碼」,你自己寫的:

%{ 
whatever you like goes here 
%} 

由於這個生成的代碼之前出來,你可以#include "constants.h"並訪問您的宏。您也#include <string.h>,可以strdup之前,只要你不限制自己嚴格的POSIX溝投(如果你在圖書館有strdup可言,你可能有它在string.h)。

+0

。問題是正則表達式。如果我嘗試 '[[:alnum:]] {1,MAX_STR_LEN} {do_something(); }' 它失敗,因爲MAX_STR_LEN不是一個數字,它認爲我爲單個規則定義了2個動作。 – msikora 2012-03-14 00:48:03

+0

哦。呃,對不起,誤解了你的問題!唉,不,你不能讓RE解析器來做到這一點。無論如何,這可能不是一個好主意,因爲它意味着33個字符的字母數字根本不會是一個有效的標記。在決定它是一個有效的標記之後,但在返回之前,即在設置yylval並返回一個標記號碼的代碼之內,你有什麼理由不能做這個開關?只要返回TOOLONG_STRING len> max。這給你一個把解析器中的錯誤處理器放在一個好地方。 – torek 2012-03-14 00:57:38

+0

我只是打算解析器失敗,如果字符串太長,但爲無效字符串添加標記也可能會有所幫助。感謝您的快速響應。 – msikora 2012-03-14 01:04:53

0

不,由flex生成的掃描器設置得很好,不能在運行時更改。除了在torek的回答(if (strlen (yytext) > MAX_STR_LEN) return TOOLONG_STRING;)的評論中討論的選項之外,另一個更復雜的可能性是使用啓動條件和臨時緩衝區等自己完成字符串累加,並且如果發現超過MAX_STR_LEN個字符,則表示發生錯誤,但很難想象這是值得努力的場景。

完全無關,我會考慮是否真的有一個令人信服的理由來限制長度。一旦你設計你的程序的時候,假定「弦永遠不會超過MAX_STR_LEN」,這很難改變裝備。如果您以「字符串可以是任意長度」的要求開始,代碼並不複雜得多,但您獲得了很大的靈活性。