使用Attoparsec解析简单的分子名称

魔方

我发现很难学习如何使用Attoparsec,因为该文档实际上只是一个API文档,并且基本上没有教程(FPComplete的教程除外)。如果您知道我可以在其他地方学习Attoparsec的地方,那就太好了。

我要解析简单的分子名称,按以下格式:NaClCO2H2OHCNH2O2
一个元素名称是大写字母任选接着进行一个小写一个(我不考虑与符号超过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

哪里emptyData.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
    

    pfn参数的函数在哪里

所以在这里您可能想要这样的东西:

-- 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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用Attoparsec解析简单的分子名称

来自分类Dev

使用attoparsec解析IP地址

来自分类Dev

如何使用Attoparsec解析雅虎历史csv

来自分类Dev

使用attoparsec解析逗号内的逗号分隔字符串

来自分类Dev

使用简单的DOM解析图像

来自分类Dev

了解attoparsec解析器monad

来自分类Dev

基本的Attoparsec解析仅返回“ Right []”

来自分类Dev

基本的Attoparsec解析仅返回“ Right []”

来自分类Dev

使用名称空间解析XML

来自分类Dev

Autofac注册并使用名称解析

来自分类Dev

使 Symfony 表单使用简单的 GET 名称

来自分类Dev

使用简单框架解析XML的正确方法

来自分类Dev

使用简单XML特殊解析XML

来自分类Dev

无法使用简单的xml进行解析

来自分类Dev

使用简单框架解析XML的正确方法

来自分类Dev

如何使用简单的HTML DOM解析列表

来自分类Dev

使用Antlr4解析简单的模板

来自分类Dev

使用GSON抛出IllegalArgumentException的简单JSON解析

来自分类Dev

解析不以attoparsec中的某些字符结尾的标识符

来自分类Dev

使用元素名称中的空格解析XML

来自分类Dev

无法使用空格解析城市名称

来自分类Dev

使用空名称空间解析xml

来自分类Dev

如何使用名称空间解析XML

来自分类Dev

使用名称空间信息解析XML

来自分类Dev

使用gson解析名称未知的json对象

来自分类Dev

使用DOM解析XML与名称空间

来自分类Dev

如何使用名称空间解析XML?

来自分类Dev

Javascript是否使用动态名称解析?

来自分类Dev

使用名称空间解析xml的问题