parsing - 如何使用 attoparsec 解析固定长度、非分隔整数?

标签 parsing haskell integer attoparsec

我正在尝试使用 attoparsec 从 3 个字符中解析两个整数。示例输入可能如下所示:

341

...我想解析为:

Constructor 34 1

我有两个可行的解决方案,但有些笨重:

stdK :: P.Parser Packet
stdK = do
    P.char '1'
    qstr <- P.take 2
    let q = rExt $ P.parseOnly P.decimal qstr
    n <- P.decimal
    return $ Std q n

stdK2 :: P.Parser Packet
stdK2 = do
    P.char '1'
    qn <- P.decimal
    let q = div qn 10
    let n = rem qn 10
    return $ Std q n

一定有更好的方法来实现如此简单的事情。我错过了什么吗?

最佳答案

您的代码片段远非独立(特别是缺少 Packet 数据类型的导入和定义),但您似乎使事情变得过于复杂。

首先,为一位整数定义一个解析器。然后,使用后者作为两位整数解析器的构建 block 。之后,使用应用运算符组合这两个解析器,并为您的自定义 Packet 数据类型定义一个解析器。见下文。

请注意,您不需要 monad 的全部功能;在这里,应用解析就足够了。

-- test_attoparsec.hs

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative ((<$>))
import Data.Attoparsec.Text
import Data.Char

data Packet = Std {-# UNPACK #-} !Int
                  {-# UNPACK #-} !Int
  deriving (Show)

stdK :: Parser Packet
stdK = char '1' *> (Std <$> twoDigitInt <*> oneDigitInt)

twoDigitInt :: Parser Int
twoDigitInt = timesTenPlus <$> oneDigitInt <*> oneDigitInt
  where
    timesTenPlus x y = 10 * x + y

oneDigitInt :: Parser Int
oneDigitInt = digitToInt <$> digit

GHCi 中的测试:

λ> :l test_attoparsec.hs
[1 of 1] Compiling Main             ( test_attoparsec.hs, interpreted )
Ok, modules loaded: Main.

λ> :set -XOverloadedStrings 

λ> parseOnly stdK "1341"
Right (Std 34 1)

λ> parseOnly stdK "212"
Left "1: Failed reading: satisfyWith"

关于parsing - 如何使用 attoparsec 解析固定长度、非分隔整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30704459/

相关文章:

linux - 今天无法解析 Linux 日志文件

Python解析字符串列表

c++ - 如何将原始 Haskell 绑定(bind)编译到 OpenCV 又名 GitHub 成员 arjuncomar 的 OpenCV-Raw 仓库

Javascript 整数数组错误

html - 如何使用 Ruby 解析 HTML 文件标题

Python 正则表达式反向引用命名组

haskell - 为记录类型定义幺半群实例

http - 在 wreq 中发送数据(不是表单)

java - 如何对作为字符串的整数进行排序?

java - 如何在 Java 中将 float 转换为整数