首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在uu-parsinglib中使用`opt`组合符

在uu-parsinglib中使用`opt`组合符
EN

Stack Overflow用户
提问于 2012-03-01 15:41:50
回答 1查看 184关注 0票数 2

我正在为我的项目编写一个简单的文本模板语言的解析器,我完全被uu-parsinglib中的opt组合子所困扰(如果有必要的话,2.7.3.2版本)。有关于如何正确使用它的想法吗?

这是一个非常简单的例子,它显示了我的困境。

代码语言:javascript
复制
{-# LANGUAGE FlexibleContexts #-}

import Text.ParserCombinators.UU hiding (pEnd)
import Text.ParserCombinators.UU.Utils
import Text.ParserCombinators.UU.BasicInstances

pIdentifier :: Parser String
pIdentifier = pMany pLetter

pIfClause :: Parser ((String, String), String, Maybe (String, String), String)
pIfClause = (,,,) <$> pIf <*> pIdentifier <*> pOptionalElse <*> pEnd

pIf :: Parser (String, String)
pIf = pBraces ((,) <$> pToken "if " <*> pIdentifier)

pOptionalElse :: Parser (Maybe (String, String))
pOptionalElse = (((\x y -> Just (x, y)) <$> pElse <*> pIdentifier) `opt` Nothing)

pElse :: Parser String
pElse = pBraces (pToken "else")

pEnd :: Parser String
pEnd = pBraces (pToken "end")

main :: IO ()
main = do
  putStrLn $ show $ runParser "works" pIfClause "{if abc}def{else}ghi{end}"
  putStrLn $ show $ runParser "doesn't work" pIfClause "{if abc}def{end}"

第一个字符串可以正确解析,但第二个字符串会失败,并显示错误:

代码语言:javascript
复制
main: Failed parsing 'doesn't work' :
Expected  at position LineColPos 0 12 12 expecting one of [Whitespace, "else"] at LineColPos 0 12 12 :
                              v
                  {if abc}def{end}
                              ^
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-03-01 17:14:08

opt的文档中写道:

如果p可以识别,则使用p的返回值。否则,将使用值v。请注意,默认情况下,opt是贪婪的。

<<|>的文档中解释了贪婪的含义

<<|>是<|>的贪婪版本。如果它的左侧解析器可以取得任何进展,那么它将提交到该替代方案。

在本例中,opt的第一个参数可以识别输入的一部分,因为elseend都以e开头。因此,它提交给pElse,这会导致失败,并导致整个解析失败。

解决此问题的一个简单方法是使用... <|> pure Nothing,正如文档所建议的那样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9512374

复制
相关文章

相似问题

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