2016-11-19 29 views
0

我不明白爲什麼在2個功能相同的源文件中,只有1個編譯階段通過flex,另一個生成關於use of undeclared identifier的錯誤。使用flex時,有一些格式規則需要遵循?

這一個是OK(我通常不會在我的編輯器中使用的標籤,這些都是空格)

 int num_lines = 0, num_chars = 0; 

%% 
\n  ++num_lines; ++num_chars; 
.  ++num_chars; 

%% 
int main() 
     { 
     yylex(); 
     printf("# of lines = %d, # of chars = %d\n", 
       num_lines, num_chars); 
     } 

這一次它不是由flex接受,不會產生任何東西,但錯誤

int num_lines = 0, num_chars = 0; 

%% 
\n ++num_lines; ++num_chars; 
. ++num_chars; 

%% 

int main() 
{ 
    yylex(); 
    printf("# of lines = %d, # of chars = %d\n", num_lines, num_chars); 
} 

如果我想用flex編譯我的掃描儀,是否必須遵循一些特定的約定?

+0

我嘗試了flex的最新github版本,並得到相同的行爲,這可能意味着我錯過了一些東西... – user31223

+0

我真的需要一個反饋,因爲沒有暗示我做錯了什麼或如果這甚至是一個錯誤 – user31223

回答

0

是的,在lex/flex中有格式化規則,你違反了它們。

我會總結一下。 lex/flex輸入程序有三個主要部分,第一列中的%%分隔符(在行首)分隔。最後一節是可選的。第一部分是詞彙聲明;在本節中可以命名正則表達式。第二部分指定要對模式執行的操作,第三部分(可選)用於要轉錄到輸出文件的(C)代碼。它用於定義操作部分中使用的函數。

用於第一(法聲明)部分的標準格式是:

name  pattern 

凡名稱必須從第一列開始(線的開始),並且圖案通過白色分離在同一行空間。

用於第二(動作)部分中的格式是類似的:

pattern action 

凡模式必須從第一列開始(線的開始),並且操作由空格分隔在同一行 。該模式可以在多行上繼續,但必須由空格縮進,否則將被解釋爲新模式。

第三部分沒有佈局限制,因爲代碼只是跳過了。

有一個最終的句法特徵很有用。在第一節中,沒有指定應該複製到輸出的詞彙模式的代碼可以在行的開始處由%{%}來指示。此外,在動作(第二)部分,任何沒有模式和只有一個動作的代碼都會被複制到輸出中。

用變量聲明開始文件C違反了這些規則。如果它從左邊開始,它將被視爲一個詞彙定義。

如果你想在Ç應複製到輸出聲明一些變量,你可以做以下方式:

%{ 
int num_lines = 0, num_chars = 0; 
%} 
%% 
\n  ++num_lines; ++num_chars; 
.  ++num_chars; 

或者交替,就像這樣:

%% 
     int num_lines = 0, num_chars = 0; 
\n  ++num_lines; ++num_chars; 
.  ++num_chars; 
+0

謝謝,使用'%{'和'%}'解決了這個問題,事實上,來自'flex'源doc文件夾的手冊中的官方示例的格式與我的文章一樣,甚至可以在線閱讀https://ftp.gnu.org/old-gnu/Manuals/flex-2.5.4/html_node/flex_5.html並且他們不使用您提到的最後2種解決方案中的任何一種;這只是讓我更加困惑,因爲我假設這些示例寫得很好,並且在手冊的前幾節中沒有提及格式規則*。至少現在我知道了,再次感謝。 – user31223

+0

這不完全正確。定義部分中的縮進行和規則部分中的縮進行都被複制到輸出中,但在不同的地方。規則部分中的縮進行進入輸出文件的開頭,因此聲明是文件範圍。規則部分開始處的縮進行位於'yylex'的開頭,因此聲明是局部的(並且每次輸入'yylex'時都會執行賦值操作(規則部分中的第一個規則之後的縮進行將轉到未指定的位置,所以他們真的應該是評論。) – rici

+0

@rici感謝您的澄清。 –

相關問題