如何使用Parsec(Haskell)基于密钥令牌将值插入字符串?

时间:2017-08-27 03:18:07

标签: parsing haskell parsec

我是解析世界的新手,并且有一个相当简单的问题:

我有一个包含 distLists, LocLists = performSim(maxTime, numTrials, drunkType) means = [] ## distLists = performSim(maxTime, numTrials, drunkType) for t in range(maxTime + 1):# 1 step is necessary, 0 isn't move tot = 0.0 for distL in distLists: tot += distL[t]# Sum of values within an array of each element means.append(tot/len(distLists))#divide by the number of lists pylab.figure() pylab.plot(means) pylab.ylabel('distance') pylab.xlabel('time') pylab.title(title + 'Ave. Distance') lastX = [] lastY = [] for locList in LocLists: x, y = locList[-1].getCoords() lastX.append(x) lastY.append(y) pylab.figure() pylab.scatter(lastX, lastY) pylab.xlabel('EW Distance') pylab.ylabel('NW Distance') pylab.title(title + 'Final locations') pylab.figure() pylab.hist(lastX) pylab.xlabel('EW Value') pylab.ylabel('Number of Trials') pylab.title(title + 'Distribution of Trial EW Values') 个普通文本的长字符串,以及Chunk个编码为Key的字符串。

<<key-label>>

我想用值替换这些键,但是我可以解决这个问题,如果我可以将字符串解析为我的标记,IE data Merge a = Chunk a | Key a deriving (Show) key :: Parser (Merge String) key = Key <$> between (string "<<") (string ">>") (many1 letter) chunk :: Parser (Merge String) chunk = Chunk <$> many1 anyChar prose = many1 $ key <|> chunk ex = parseTest prose "hi <<x>> ! Do you like <<y>>?" -- Returns: -- [Chunk "hi <<x>> ! Do you like <<y>>?"] -- I'd like: -- [Chunk "hi ", Key "x", Chunk " !", ...]

我已经潜入了无边无际的深度,而且我希望最终能够学到所有这些,现在有任何关于解决这个问题的指导吗?

这是我尝试的最简单的实例化,虽然我尝试了对数据的单独传递,包括单独的lexing /解析步骤,并且我喜欢使用String -> [Merge]而不是一个更具体的插值库。

2 个答案:

答案 0 :(得分:1)

您可以使用notFollowedBy表示您希望一个块包含一个 只要不是关键字。 notFollowedBy不消费 输入所以prose仍将继续将该键再次解析为自己的项目。

chunk = Chunk <$> many1 (notFollowedBy key >> anyChar)

这样就可以将aaa<<bbbbbb之类的内容解析为块, 通过一直到文件的末尾,而不是找到一个结束 >>,决定它一定不是关键,因此它可以 成为大块的一部分。

如果您希望<<始终是密钥的开头而且如果失败则失败 它没有关闭,从块中禁止<<

chunk = Chunk <$> many1 (notFollowedBy (string "<<") >> anyChar)

答案 1 :(得分:0)

replace-megaparsec 是用于使用解析器进行搜索和替换的库。的 搜索和替换功能是 streamEdit

select id_number, category, type, dat
   , case when pId is null then 'new' else 'updated' end new_or_updated
from (
 select id_number, category, type, dat 
  , max(dat) over(partition by ID_NUMBER) dmax
  , lag(ID_NUMBER) over(partition by ID_NUMBER order by dat) pId
  , lag(category) over(partition by ID_NUMBER order by dat) pCategory
  , lag(type) over(partition by ID_NUMBER order by dat) pType
 from tbl
) t
where dat = dmax and (pId is null or pCategory != Category or pType !=Type );
import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char
import Data.Char

key = between (string "<<") (string ">>") (many letterChar) :: Parsec Void String String
editor k = "Key " ++ (fmap toUpper k)

streamEdit key editor "hi <<x>> ! Do you like <<y>>?"

您还可以使用 sepCap 解析器组合器,它返回与"hi Key X ! Do you like Key Y?" 等效的结构 您正在尝试构建的。