首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >条件超前( attoparsec )

条件超前( attoparsec )
EN

Stack Overflow用户
提问于 2016-07-05 11:30:43
回答 1查看 283关注 0票数 3

假设有一个数据结构,表示内部有注释的文本。

代码语言:javascript
复制
data TWC
  = T Text TWC -- text
  | C Text TWC -- comment
  | E -- end
  deriving Show

因此,字符串类似

代码语言:javascript
复制
"Text, {-comment-}, and something else"

可以被编码为

代码语言:javascript
复制
T "Text, " (C "comment" (T ", and something else" E))

注释块和E的解析器非常琐碎:

代码语言:javascript
复制
twcP :: Parser TWC
twcP = eP <|> cP <|> tP

cP :: Parser TWC
cP = do
  _ <- string "{-"
  c <- manyTill anyChar (string "-}")
  rest <- cP <|> tP <|> eP
  return (C (pack c) rest)

eP :: Parser TWC
eP = do
  endOfInput
  return E

以一种简单的方式实现文本块的解析器

代码语言:javascript
复制
tP :: Parser TWC
tP = do
  t <- many1 anyChar
  rest <- cP <|> eP
  return (T (pack t) rest)

让它以文本的形式使用评论部分,因为它是贪婪的。

代码语言:javascript
复制
> parseOnly twcP "text{-comment-}"
Right (T "text{-comment-}" E)
it ∷ Either String TWC

因此,问题是如何表达直到输入结束或评论部分的解析逻辑?换句话说,如何实现条件查找解析器?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-07-05 14:15:57

没错,有问题的代码是tP的第一行代码,它贪婪地解析文本而不停止注释:

代码语言:javascript
复制
tP = do
  t <- many1 anyChar

在解决这个问题之前,我首先要重构一下您的代码,引入帮助程序并使用应用程序风格,将有问题的代码隔离到text助手中:

代码语言:javascript
复制
-- Like manyTill, but pack the result to Text.
textTill :: Alternative f => f Char -> f b -> f Text
textTill p end = pack <$> manyTill p end

-- Parse one comment string
comment :: Parser Text
comment = string "{-" *> textTill anyChar (string "-}")

-- Parse one non-comment text string (problematic implementation)
text :: Parser Text
text = pack <$> many1 anyChar

-- TWC parsers:

twcP :: Parser TWC
twcP = eP <|> cP <|> tP

cP :: Parser TWC
cP = C <$> comment <*> twcP

eP :: Parser TWC
eP = E <$ endOfInput

tP :: Parser TWC
tP = T <$> text <*> twcP

为了实现前瞻性,我们可以使用lookAhead组合器,它在不消耗输入的情况下应用解析器。允许我们对text进行解析,直到它到达comment (不消耗它)或endOfInput为止。

代码语言:javascript
复制
-- Parse one non-comment text string (working implementation)
text :: Parser Text
text = textTill anyChar (void (lookAhead comment) <|> endOfInput)

使用该实现,twcP的行为与预期的相同:

代码语言:javascript
复制
ghci> parseOnly twcP "text{-comment-} post"
Right (T "text" (C "comment" (T " post" E)))
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38202349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档