2013-12-15 42 views
0

說我有一個代碼具有以下形式。一些彈性/野牛問題

display <<"hello">> (number1) (number2) (number3) { 
    a = 1; 
    b = 2; 
    ... 
} 

注意這只是一個例子,雖然是一個醜陋的例子,不過,這只是我想去做的exageration。 number1,number2,number3是數字,顯示將是一種操作符,後跟一個包含變量賦值的{}之間的塊,並以特殊方式打印整個事物。如上所述,只是一個例子。

我的問題是......說這個語法,display <<str>>()()() {}表格只與「顯示」關鍵字一起使用,並且從未使用過。假設< <和>>通常是運營商。我想知道......怎麼可能告訴野牛/ flex在這種情況下< <和>>不是用作操作符,而只是屬於「顯示」語法的分隔符?並且,如何正確提取<和<和>>之間的數據,然後使用不同的,特定的語法將整個塊解析爲{}之間的塊。

例如,如果我有:

display <<"hello">> (1) (5) (8) { 
    a = 1; 
    b = 8 * 273 + 40; 
} 

然後,我會想撥打電話這樣的:

handle_display_operator(szStr, num1, num2, num3) 

// here szStr contains "hello", num1 = 1, num2 = 5, num3 = 8 

調用該函數後,我需要解析成塊。

有人能解釋我如何正確處理這個問題嗎?

感謝

回答

1

你可以寫爲像野牛規則:

statement: DISPLAY LSHIFT string RSHIFT '(' expr ')' '(' expr ')' '(' expr ')' 
       { handle_display_operator($3, $6, $9, $12); } 
      block 
     ; 

在詞法分析器識別display爲關鍵詞進行顯示和<<>>爲令牌LSHIFT和RSHIFT。在其他情況下(例如表達式),您將使用LSHIFTRSHIFT作爲移位運算符。

這允許括號中的任何表達式(您可以在您的expr規則中計算整數),並且如果您在string規則中處理它們,則可能允許字符串「表達式」。

如果您真的想在<</>>(而不是字符串)之間使用原始文本,另一種方法是在display關鍵字之後使用flex獨佔狀態。然後,你就必須像彎曲的規則:

%x display, raw_text 
%{ 
    /* use a dynamic buffer if you don't have an upper limit on the length */ 
    static char raw_text_buffer[MAX_LENGTH], *raw_text_end; 
%} 

%% 

"display"  { BEGIN(display); return DISPLAY; } 
<display>"<<" { BEGIN(raw_text); raw_text_end = raw_text_buffer; } 
<raw_text>. { *raw_text_end++ = *yytext; /* DANGER -- may overflow */ } 
<raw_text>\n { error?? or just put it in the buffer... } 
<raw_text>">>" { *raw_text_end = 0; 
       yylval.string = strdup(raw_text_buffer); 
       BEGIN(INITIAL); 
       return RAW_TEXT; } 

現在,您的規則將是這樣的:

statement: DISPLAY RAW_TEXT '(' expr ')' '(' expr ')' '(' expr ')' 
       { handle_display_operator($2, $4, $7, $10); } 
      block 

這讓像display << %" ,> >> (1)(2)(3)輸入並會把你的處理函數的字符串%" ,>(包括前/後間隔,引號和全部。

當然,您應該添加檢查緩衝區溢出與適當的錯誤消息。

+0

感謝您的理解敏捷而快速的回答克里斯。我仍然希望從您的經驗中獲益。在由顯示器處理的塊中,假設我想在其中有一個獨特的語法。假設我有第二個運算符叫做'struct',它也可以接受struct {block}等塊,並且struct語法中的塊也有一個獨特的語法。我再次展示了這個例子,但我想清楚地理解這個概念。我是否需要製作另一個yyparse()(前綴),還是可以在單個解析器中執行?謝謝! – Yannick