如何使用Parsec的Perm解析排列短语的非连续元素?

时间:2016-07-06 12:49:14

标签: parsing haskell parsec

Haskell的Parsec通过parsing of permutation phrases模块支持Perm。在permute的文档中,您可以看到各种排列" abc"," aab"," bc"," cbaaaaa&#34 ;等等可以解析。虽然该示例显示支持分离同一元素的许多连续实例,例如" aaaa"但它不会解析非连续的实例,例如" aabc a & #34;,大概是因为每个解析器在每个排列中只包含一次(论文似乎暗示了这一点在树中......)

除了对输入进行排序以便实例是连续的,我还有哪些选项来解析不连续的实例?

1 个答案:

答案 0 :(得分:1)

根据您的实际需要,您可以使用many $ oneOf ['a','b','c']

如果您确实需要使用置换解析器,请记住,允许多个相邻字符的解析会引入歧义。例如,在字符串"bacacbbca"中,可以将其解析为权限bacacb bca,或者,如果您允许重复字符bacacbb,留下ca的剩余非排列。

如果您允许重复的字母,

{-# LANGUAGE FlexibleContexts #-}

import Text.Parsec
import Text.Parsec.Char
import Text.Parsec.Perm
import Data.Text
import Control.Monad.Identity

perm :: (Stream s Identity Char) => Parsec s u (String,String,String)
perm = permute $ triple <$$>
  (many1 $ char 'a') <||>
  (many1 $ char 'b') <||>
  (many1 $ char 'c')
  where triple a b c = (a,b,c)

multiPerm :: (Stream s Identity Char) => Parsec s u [(String,String,String)]
multiPerm = many $ try $ perm

main :: IO ()
main = parseTest multiPerm $ "bacacbbca" 

main生成[("a","b","c"),("a","bb","c")]

如果不是:

perm :: (Stream s Identity Char) => Parsec s u (Char,Char,Char)
perm = permute $ triple <$$>
  (char 'a') <||>
  (char 'b') <||>
  (char 'c')
  where triple a b c = (a,b,c)

你可以说是更好:[('a','b','c'),('a','b','c'),('a','b','c')]