Parsing 使用Parsec来解析几种不同类型的字段
我有一个小的parsec解析器,可以将制表符分隔值(TSV)解析为字符串。我想切换到检查源文件中的数字和布尔值(列为“Y”或“N”) 这是旧的TSV版本(返回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定义的函数。这些
[[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