2013-02-12 20 views
3

它往往是方便的表達在BNF語法產生像代表小量生產與FParsec解析器組合

A ::= "car" 
    | "bike" 
    | ε 

其中,ε表示空產生規則;即非終端「A」可以擴展到終端「汽車」,「自行車」或什麼都不是。但是,除非我重構我的語法,否則我不清楚在FParsec中如何表示這樣的語法。我知道'選擇'組合子,<|>,但據我所知沒有'空'組合子。即,返回true並且不消耗輸入的組合器。

我已經搜索了FParsec文檔的高低,但是我還沒有找到任何能夠做到這一點的事情,這讓我感到驚訝,因爲這看起來像是一種常見的情況。我對FParsec(以及一般的combinators)相當陌生,所以也許我只是沒有使用正確的單詞。任何提示?

回答

3

我認爲傑克的解決方案應該爲您解決問題。但是,如果您正在尋找代表解析器成功的原語而不消耗任何輸入,那麼您可能需要preturnFParsec.Primitives(請參閱preturn in the documentation)。

如果您將解析器組合成某些AST的值而不是字符串,它可能會很有用。例如,如果你有一個區分聯合:

type Vehicle = Car | Bike | Other 

你可以使用pstring "car" >>% Carpstring "bike" >>% Bike來創建返回Vehicle值解析器。然後,你可以使用<|>將它們結合起來,並添加使用preturn一個特殊的(空)的情況下:

let parseA = 
    pstring "car" >>% Car <|> 
    pstring "bike" >>% Bike <|> 
    preturn Other 

preturn操作可能不會直接使用非常頻繁,但它是基本的原語之一(因爲它定義了一元單元返回解析器的操作)。

+0

謝謝你提到這個,托馬斯。事實上,我在發佈上述問題後發現並使用了'preturn'。 – 2013-02-13 12:39:34

+1

我剛剛在fparsec文檔中注意到[this](http://www.quanttec.com/fparsec/reference/primitives.html#members.:60::124::62::37) - 您可以優化'<|>其他'爲'<|>%其他'。 – 2013-02-13 23:46:35

1

我不太熟悉FParsec - 我通常使用fsyacc - 但是如果您在選擇組合器中使用空字符串會發生什麼?例如,類似於:

let parseA = pstring "car" <|> pstring "bike" <|> pstring "" 
+0

Duh。這是推翻問題的一個例子。謝謝。 – 2013-02-12 01:23:10