我发现很难学习如何使用Attoparsec,因为该文档实际上只是一个API文档,并且基本上没有教程(FPComplete的教程除外)。如果您知道我可以在其他地方学习Attoparsec的地方,那就太好了。
我要解析简单的分子名称,按以下格式:NaCl
,CO2
,H2O
,HCN
,H2O2
。
一个元素名称是大写字母任选接着进行一个小写一个(我不考虑与符号超过2个字符的那些元素)。
元素后可以跟数字(该数字将成为公式中的下标)。
新版本(由于Mark和Tarmil的建议),可以编译但不解析:
module Chem
where
import Data.Text (Text, pack)
import Control.Applicative ((<*>), (<$>))
import Data.Attoparsec.Text
data Element = Element String Int deriving (Eq, Ord, Show)
type Molecule = [Element]
parseString :: String -> Result Molecule
parseString = parse (many' parseElement) . pack
parseElement :: Parser Element
parseElement = do
el <- (++) <$> pClass "A-Z" <*> option "" (pClass "a-z")
n <- option 1 decimal
return $ Element el n
pClass :: String -> Parser String
pClass cls = (\c -> [c]) <$> satisfy (inClass cls)
任何建议表示赞赏。
编辑:我设法使其运行。基本上,Partial
返回了延续,并且要完成解析,有必要向解析器提供一个空的字节串。因此正确的parseString
是:
parseString = flip feed empty . parse (many' parseElement) . pack
哪里empty
是Data.Text.empty
。但是,由于我不需要增量解析,所以有一个有用的函数parseOnly
,它不需要等待更多的输入并返回Either
。
考虑到这一点,我重写了这样的代码(现在可以使用):
module Chem
where
import Data.Text (Text, pack)
import Control.Applicative ((<*>), (<$>))
import Data.Attoparsec.Text
data Element = Element String Int deriving (Eq, Ord, Show)
type Molecule = [Element]
parseString :: String -> Either String Molecule
parseString = parseOnly (many' parseElement) . pack
parseElement :: Parser Element
parseElement = do
el <- (++) <$> pClass "A-Z" <*> option "" (pClass "a-z")
n <- option 1 decimal
return $ Element el n
pClass :: String -> Parser String
pClass cls = (\c -> [c]) <$> satisfy (inClass cls)
字母解析部分存在两个问题:
inClass
不是解析器,而是要传递给的函数satisfy
。<*>
具有type Parser (a -> b) -> Parser a -> Parser b
,因此左侧的解析器应返回一个函数。通常,它的用法如下:
pf <$> p1 <*> p2 <*> ... <*> pn
pf
带n
参数的函数在哪里。
所以在这里您可能想要这样的东西:
-- parse a character in the given class, and transform it to a single-char string
pClass cls = (\c -> [c]) <$> satisfy (inClass cls)
-- ...
el <- ((++) <$> pClass "A-Z" <*> pClass "a-z") <|> pClass "A-Z"
-- ...
我认为这可以通过使用来增强option
,而不是复制A-Z
解析器:
el <- (++) <$> pClass "A-Z" <*> option "" (pClass "a-z")
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句