我尝试这样做:
解析以下形式的文本:
一些文本 #{0,0,0} 一些文本 #{0,0,0}#{0,0,0} 更多文本 #{0,0,0}
进入一些数据结构的列表:
[内部“一些文本”,外部(0,0,0),内部“一些文本”,外部(0,0,0),外部(0,0,0),内部“更多文本”,外部(0, 0,0)]
所以这些#{a,b,c}位应该变成与文本其余部分不同的东西。
我有这个代码:
module ParsecTest where
import Text.ParserCombinators.Parsec
import Monad
type Reference = (Int, Int, Int)
data Transc = Inside String | Outside Reference
deriving (Show)
text :: Parser Transc
text = do
x <- manyTill anyChar ((lookAhead reference) <|> (eof >> return (Inside "")));
return (Inside x)
transc = reference <|> text
alot :: Parser [Transc]
alot = do
manyTill transc eof
reference :: Parser Transc
reference = try (do{ char '#';
char '{';
a <- number;
char ',';
b <- number;
char ',';
c <- number;
char '}';
return (Outside (a,b,c)) })
number :: Parser Int
number = do{ x <- many1 digit;
return (read x) }
这按预期工作。您可以通过键入以下内容在 ghci 中测试这一点
parseTest alot“一些文本#{0,0,0}一些文本#{0,0,0}#{0,0,0}更多文本#{0,0,0}”
但我觉得这不太好。
1)是使用lookAhead
对于我的问题真的有必要吗?
2) 是return (Inside "")
一个丑陋的黑客?
3)通常是否有更简洁/更智能的方法来实现相同的目的?