2017-04-05 180 views
0

正則表達式對應於以下Flex結構?我正在嘗試爲一個項目重新創建Rusts語法,但現在我被卡在了這一塊上?這是內部/外部文檔評論的語法(Rust有六種類型的評論)。它應該匹配評論,如/** *//*! */,但例如我不明白爲什麼[^*]需要在第一行以及匹配的順序是在這種情況下。找出Flex(詞法分析器)yy_push_state

\/\*(\*|\!)[^*]  { yy_push_state(INITIAL); yy_push_state(doc_block); yymore(); } 
<doc_block>\/\*  { yy_push_state(doc_block); yymore(); } 
<doc_block>\*\/  { 
    yy_pop_state(); 
    if (yy_top_state() == doc_block) { 
     yymore(); 
    } else { 
     return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT); 
    } 
} 
<doc_block>(.|\n)  { yymore(); } 

據我明白:第1行,相匹配的開始/**/*!;第2行,匹配塊註釋(出於某種原因?);第3行,匹配結束*/;第11行,匹配任何字符或換行符(爲什麼?)。

兩行還進一步匹配正常的塊註釋。爲什麼它在文檔評論中也匹配它?

\/\*     { yy_push_state(blockcomment); } 
<blockcomment>\/\* { yy_push_state(blockcomment); } 
<blockcomment>\*\/ { yy_pop_state(); } 
<blockcomment>(.|\n) { } 

回答

1

撓曲狀態堆棧允許不能由正則表達式描述的字符串的詞法分析,所以沒有正則表達式等效於撓曲規範。有關狀態堆棧的文檔,包括編寫狀態條件規則的語法,請參閱flex manual

鐵鏽臭名昭着,並且評論語法(es)屬於該類別。鐵鏽書在syntax index中提到塊註釋,但未能記錄引用的comments section中的精確語法。我找不到任何對rustdoc理解的語法的精確描述。

我已經反向設計了你引用的flex摘錄的語法,但是用了一粒鹽;它可以只具有一個通過的相似由rustcrustdoc接受的實際語法:

  1. 鏽塊註釋,不同於C或C++的塊註釋,可以嵌套。這使得他們的括號語法,這是不規則的;他們需要一個下推自動機解析。所以沒有正則表達式可以描述Rust塊註釋,並且需要使用flex狀態堆棧來識別它們。

  2. 鏽病文檔塊註釋必須以斜線和精確的兩顆星(或星號和感嘆號)開頭。 A文檔框:

    /************************************* 
    *  START OF SECTION   * 
    *************************************\ 
    

    不被視爲文檔註釋。

    (我懷疑是不是認識內部的塊註釋開始`/ 「是一個疏忽,但誰知道!)

如果以上是正確的,可以爲您解答:

  1. 「我不明白爲什麼[^ *]需要在第一行」

    這是爲了避免匹配箱的意見,如ABO注意五個。 「

  2. 」這種情況下匹配順序是什麼。「

    在所有情況下,flex會在輸入中的任意點選擇最長的匹配項,如果多個規則匹配相同的最長字符串,它會選擇文件中的第一條規則,即所謂的」 。最大適合」規則,所以給出的兩個規則(我不扶着木材的森林中寫道,因爲我覺得它不可讀):

    "/*"[*!][^*]  { DocComment(); } 
    "/*"    { BlockComment(); } 
    

    第二條規則將適用於輸入/* Comment/****,匹配兩個字符,而第一條規則將適用於/** Documentation comment,匹配四個字符(它也將錯誤地適用於/**/,恕我直言,這應該被分析爲空塊註釋,而不是一個文檔註釋的開始。)

  3. 「第11行,匹配任意字符或一個換行符(爲什麼?)」

    是的,它的作用。如果它與任何字符不匹配,那麼該字符將不會被任何規則匹配,這將是不正確的。

  4. 「這兩行還匹配正常的塊註釋,爲什麼它在doc註釋中也匹配?」

    由於doc註釋內部的匹配僅適用於doc註釋。不包含在文檔評論中的阻止評論也需要進行匹配。但是,在這裏可以進行一些重構,這可以簡化詞法描述。

+0

首先,感謝您的好書面解釋。不,我沒有使用Bleibig的回購代碼。我甚至不確定他想要實現什麼。我從原始的Rust repo https://github.com/rust-lang/rust/tree/master/src/grammar得到了這個。我認爲這將是代碼庫中最具代表性的代碼?你的回答清除了我的困惑。 –

+0

好吧,我將刪除對Bleibig回購的引用。我不知道你引用的文件的狀態是什麼,但它在Antlr語法的註釋處理上有所不同(https://github.com/rust-lang/rust/blob/master/src/grammar/RustLexer)。 g4)自述文件所說的是權威的(但實際上並沒有被rustc使用)。 – rici

+0

@AdrianZ:有什麼困惑,我無法幫助你? :) – rici