gpt4 book ai didi

haskell - 使用 Parsec 从文本文件中选取数据

转载 作者:行者123 更新时间:2023-12-02 17:06:20 25 4
gpt4 key购买 nike

作为学习练习,我使用秒差距来查找测试文件中的值。对于这种特殊情况,我通常会使用 regexp,但想看看 parsec 是否也有意义。不幸的是,我遇到了一些问题。

数据文件由看起来类似于以下内容的重复部分组成。 “SHEF”是六个值之一,并且随着页面的不同而变化,我想用它来构造数据类型。

Part A SHEF Nov/14/2011 (10:52)
-------------------
Portfolio Valuation
-------------------

FOREIGN COMMON STOCK 6,087,152.65
FOREIGN COMMON STOCK - USA 7,803,858.84
RIGHTS 0.00

我正在构建每个 Assets 类别中金额的数据类型:

type Sector = String
type Amount = Double
type FundCode = String

data SectorAmount = SectorAmount (Sector,Amount) deriving (Show, Eq)

data FundSectors = FundSectors {
fund :: FundCode
, sectorAmounts :: [SectorAmount]
} deriving (Show, Eq)

我的代码,编译成功,如下所示。它解析文件并正确检索每个 Assets 类别中的值,但我永远无法在fundValue解析器中正确设置状态。我已经使用输入字符串测试了fundValue解析器,它确实成功解析了它,但由于某种原因,行函数没有按照我想象的方式工作。我希望它在文件中查找以“Part A”开头的行,找到代码并将其存储在状态中,以便稍后在标记解析器成功解析行时使用。

使用 fail 是否会导致问题?

allocationParser :: String -> Either ParseError [FundSectors]
allocationParser input = do
runParser allocationFile "" "" input


allocationFile :: GenParser Char FundCode [FundSectors]
allocationFile = do
secAmt <- many line
return secAmt


line :: GenParser Char FundCode FundSectors
line = try (do fund <- try fundValue
eol
fail "")
<|> do result <- try tag
eol
f <- getState
return $ FundSectors {fund=f, sectorAmounts = [result]}


fundValue :: GenParser Char FundCode FundCode
fundValue = do manyTill anyChar . try $ lookAhead (string "Part A ")
string "Part A "
fCode <- try fundCode
setState fCode
v <- many (noneOf "\n\r")
eol
return fCode


fundCode :: GenParser Char FundCode String
fundCode = try (string "SHSF")
<|> try (string "SHIF")
<|> try (string "SHFF")
<|> try (string "SHEF")
<|> try (string "SHGE")
<|> try (string "SHSE")
<|> fail "Couldn't match fundCode"


tag :: GenParser Char FundCode SectorAmount
tag = do manyTill anyChar . try $ lookAhead tagName
name <- tagName
v <- many (noneOf "\n\r")
let value = read ([x | x <- v, x /= ',']) :: Double -- remove commas from currency
return $ SectorAmount (name,value)

eol :: GenParser Char FundCode String
eol = try (string "\n\r")
<|> try (string "\r\n")
<|> string "\n"
<|> string "\r"
<|> fail "Couldn't find EOL"

提前致谢。

最佳答案

是的,“tryfundValue” block 中的失败会撤消 setState。您将需要稍微重新设计解析器,但您看起来已经很接近了。

关于haskell - 使用 Parsec 从文本文件中选取数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8333176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com