Parsing 使用Parsec来解析几种不同类型的字段

Parsing 使用Parsec来解析几种不同类型的字段,parsing,haskell,parsec,Parsing,Haskell,Parsec,我有一个小的parsec解析器,可以将制表符分隔值(TSV)解析为字符串。我想切换到检查源文件中的数字和布尔值(列为“Y”或“N”) 这是旧的TSV版本(返回[[String]]) 我想将其更改为支持以下类型: data Cell = CellString String | CellNumber Int | CellBool Bool deriving (Show) 下面是我为number和bool定义的函数。这些

我有一个小的parsec解析器,可以将制表符分隔值(TSV)解析为字符串。我想切换到检查源文件中的数字和布尔值(列为“Y”或“N”)

这是旧的TSV版本(返回
[[String]]

我想将其更改为支持以下类型:

data Cell = CellString String
          | CellNumber Int
          | CellBool Bool          
          deriving (Show)
下面是我为number和bool定义的函数。这些是错误的吗

cellBool = do
    b <- oneOf "YN"
    return $ CellBool (b == 'Y')

cellNumber = do
    d <- many digit
    return $ CellNumber (read d)

cellString = do
    s <- many (noneOf "\t\n")
    return $ CellString s
cellBool=do

b首先,您可能应该按照

parse (tsvFile <* eof) nm s

我只需更改
cellNumber
的定义,就可以让它正常工作:

cellNumber = do
    d <- many1 digit
    return $ CellNumber (read d)
可能不太理想。相反,我会考虑像

cellNumber = do
    d <- many1 digit
    notFollowedBy cellString
    return $ CellNumber (read d)

注意:如果整个单元格(直到下一个选项卡)由数字组成,我只想将其解析为数字,而不仅仅是以数字开头。我本打算在前面添加这个,但忘记了:我调试解析函数的方法是给它们签名
ParsecT String u IO cell
,然后插入
liftIO$putStrLn之类的行“正在尝试cellBool”
liftIO$putStrLn$”阅读文本:“++在每次提取文本时显示b
。这就是我在
cellNumber
中遇到的
many
many1
的问题,因为我发现它从未通过
cellNumber
。请记住,
ParsecT
是一个monad转换器,这意味着您可以始终使用它来堆叠其他monad。唯一的问题是你必须使用
runParsecT
而不是
parseTest
。而不是
cellBool=do{b你能告诉我如何正确地将我的手机号码包装在try中吗?谢谢!@SeanClarkHess我编辑了答案,但是
try
只是一个函数,所以它的优先级高于
。添加
(tsvFile这里是错误:
Left”(未知)”(第1行,第1列):意外的'C'需要数字、制表符、换行符或输入结尾
,因此它在更基本的级别上肯定会失败。即使在第一个单元格上,它也无法使用我的
cellString
函数,即
“Crs Prefix Num”
谢谢!你说得对,我现在在“2b01dcc3”上失败了向下5行。你能为我指出回溯的正确方向吗?创造性地使用
try
lookAhead
?我编辑了你的示例以显示lookAhead,但我觉得很奇怪。有没有更好的方法来表达这一点@bheklilr@SeanClarkHess我已经回滚了您的编辑,支持使用
notfollowerby
,但是看起来我们同时在编辑,你的解析器对于一个单元格的末尾可能会起作用。你的性能有什么不同,或者它更清楚吗?@ SeaCalrkHess,你可能想考虑在<代码> CELBOBOL 中添加<代码> <代码> >行>,因为目前它在I上也有相同的问题。类似于
“Y1\n”
的输入。
cell = try cellBool <|> try cellNumber <|> cellString
    -- Don't need try on cellString as it's the last alternative
cellNumber = do
    d <- many1 digit
    return $ CellNumber (read d)
cellNumber = do
    d <- many1 digit
    lookAhead $ oneOf "\t\n"
    return $ CellNumber (read d)
cellNumber = do
    d <- many1 digit
    notFollowedBy cellString
    return $ CellNumber (read d)
cell = try cellBool <|> try cellNumber <|> cellString