首先,回答你的問題:「我如何在Flex中以可讀模式使用尾隨上下文?」。如果你堅持認爲模式只有在被空白的情況下才可讀,那麼答案是「你不行。」對不起,但就是這樣。 (?x:
旗幟在某個時候被砍成了彎曲,並且還有很多粗糙的邊緣。
從某種意義上說,這並不重要,因爲您不能在r|s
正則表達式中使用$運算符作爲一個替代項的一部分。所以,即使你可以使用「可讀語法」,它也不意味着你想要的。你當然可以使用下面的「可讀語法」(至少,我認爲它是可讀的)。這意味着不同的東西,但它是唯一使用$
運營商的其中Flex支持:
NAME (?x: foo | bar)$
下面是一些注意事項。
在Flex中,我可以在這樣的名字定義中使用尾隨模式:
NAME foo$|bar
不,你不能。或者,更好的說,你可以寫,但它不涉及尾隨上下文因爲:
…一個「$」不以規則的末尾出現失去了它的特殊屬性和被視爲正常字符。
(從Flex manual,它是在該點的最後一句它說,你不能把落後情況下運營商在括號內。)
這是真的(略好奇),其彈性將拒絕:
NAME (?x: foo$ | bar)
雖然會接受:
NAME (?x: foo$| bar)
我會去上肢體和說這是一個錯誤。A $只有在模式結束時才被認爲是尾隨上下文運算符。但是,檢查代碼只是檢查下一個字符是否爲空白,因爲模式在第一個空白字符處終止。 (圖案未在定義解析;當它實際上是包括在一些規則圖案,它被解析。)測試不檢查$是否爲(?x:
塊內,所以在
(?x: foo$ | bar)
所述$是一個尾隨上下文運算,它是(操作者必須出現在圖案的最末端)了語法錯誤,而在
(?x: foo$| bar)
的$只是一個普通字符,這是法律但也許意外。
最後,稍微注意一下:下面是完全合法和$將被視爲一個尾隨上下文運算,提供的定義是在一個模式的最末尾處:
NAME bar|foo$
但是,它可能並不意味着你認爲它的意思。尾隨上下文運算具有比交替操作者的優先級低,所以只要膨脹是在一個圖案的端部,即解析,似乎它在書面
NAME (bar|foo)$
我會強烈建議不要使用這樣的定義。 (實際上,我通常不鼓勵定義的使用,部分原因是所有這些怪癖。)以參考模式插入以$結尾的定義而不用圓括號包圍(以便可以處理$作爲運營商)。這會導致各種意想不到的行爲。例如,如果你寫:
NAME bar|foo$
,然後使用它:
x{NAME}y /* Some action */
最終的結果將是,就像你寫
xbar|foo"$"y /* Some action */
(沒有括號,但$是一個普通人物。)
在另一方面,如果你使用這樣的:
x{NAME} /* Some action */
這是因爲雖然你寫
xbar|foo$ /* Some action */
其中$是尾隨背景下運營商,但由於該運營商的低優先級,它最終相當於
(xbar|foo)$ /* Some action */
任何擴展都不可能是你想要的,更不可能是任何讀你代碼的人都會期望得到這些結果。
謝謝你,這是非常豐富。在我寫完這個問題之後,我意識到自己寫了什麼,尾隨上下文不能用於定義,只能用於規則。在閱讀你的答案和對我的問題的更多分析之後,我現在得出結論認爲,不要使用flex,而是編寫我自己的詞法分析器,然後通過標準接口將其連接到野牛。 –
@Mark:如果您堅持,您可以在定義中使用尾隨上下文。一個定義畢竟只是一個宏而已 - 智力適用的唯一一點就是(通常)用圓括號圍繞擴展,正如答案所指出的那樣,它經常會出現這種錯誤。所以如果你想在定義中使用尾隨上下文,你只需要在規則末尾使用定義,並且你應該自己插入圓括號:定義:'FOO_OR_BAR_AT_EOL(foo | bar)$'use:'//。 * {FOO_OR_BAR_AT_EOL} {puts(「評論以foo結尾」);}'會做幾乎它看起來會做的事...... – rici
......但我不會這麼做。我不喜歡在C中使用宏,並且我只在Flex中使用定義時纔有明顯的好處。然而,對於他們自己。儘管有一些粗糙的邊緣,我個人認爲flex是一個巨大的倍頻器。因人而異。祝你的項目好運。 – rici