2016-08-28 51 views
4

我想分析一些語法像GROUPBY TO USING條款如下FParsec解析無序的條款

OUTPUT data 
GROUPBY key 
TO location 
USING object 

順序允許變化,但可能會出現最多一次每個條款。

是否有方便或內置的方式來解析FParsec中的這個?我閱讀了一些提及Haskell Parsec的問題和答案。在FParsec中似乎沒有排列。如果這是要走的路,我會怎樣在FParsec中構建一個排列?

+2

我知道在FParsec沒有內置的方式,但有時候這些類型的屬性可以更容易驗證作爲AST的語義檢查。 – FuleSnabel

回答

3

我不認爲FParsec中有一個置換語法分析器。我看到幾個方向,你可以採取它。

  • 一般來說,@FuleSnabel的建議是非常合理的,可能最簡單的實現。不要讓解析器負責斷言每個子句最多出現一次的屬性。相反,分別解析每個子句,允許重複,然後檢查產​​生的AST,如果您的財產不成立,則出錯。

  • 您可以生成解析器的所有排列並將它們與choice結合使用。顯然這種方法不能擴展,但對於三個解析器,我認爲這是公平的遊戲。

  • 您可以使用以任意順序應用的解析器集合來編寫自己的原語進行解析。這將是many的變體,其中在每一步中,您都會創建解析器的choice,然後丟棄該解析器。因此,在每一步中,您都可以從縮小的解析器列表中進行選擇,直至無法解析,最終返回沿途收集的結果。

  • 您可以使用user state來跟蹤已使用的解析器,並且如果解析器在相同的上下文中使用兩次,則會失敗。不知道這是否會產生一個特別好的解決方案 - 以前沒有真正嘗試過。

+0

謝謝我制定了一個解決方案,使用用戶狀態來記住是否已經看到特定的子句用於解析當前的OUTPUT語句。看到評論和回答後,我開始在AST上驗證這一點。我覺得這並不像我想在AST上「驗證」那樣容易。具體來說,現在有一個OUTPUT聯合類型'類型OutputStatement = .. |的輸出TO ......「。解析器返回一個'OutputStatement list'。我的工作現在是驗證列表,看看是否有孿生兄弟。如何做到這一點慣用? – KFL

+0

更具體地說,如何確定DU列表中的重複聯合事件? '[去'foo'; TO「酒吧」;使用「aaa」;使用「bbb」; ...] – KFL

+0

沒有「一個真正的方法」,但一個簡單的方法是將DU映射到標記中(TO - > 0,USING - > 1等),獲取一組列表,然後檢查如果輸入列表的長度與輸出集合的計數相同。 – scrwtp