Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing Haskell ReadP至少解析列表中的一个_Parsing_Haskell_Parsec_Parser Combinators - Fatal编程技术网

Parsing Haskell ReadP至少解析列表中的一个

Parsing Haskell ReadP至少解析列表中的一个,parsing,haskell,parsec,parser-combinators,Parsing,Haskell,Parsec,Parser Combinators,我尝试用ReadP标准库解析命令(create)。我的命令应该以字符串create开头,然后至少包含一个单词/tag/due,可能还有一个选项。下面是我的实际表达: createxpr::ReadP[Arg] createxpr=do 滑雪场 cmd一个简单的解决方案是使用Control.Monad中的guard 假设函数像isOpt::Arg->Bool,它与 isOpt :: Arg -> Bool isOpt (AddOpt _) = True isOpt _ =

我尝试用ReadP标准库解析命令(create)。我的命令应该以字符串
create
开头,然后至少包含一个单词/tag/due,可能还有一个选项。下面是我的实际表达:

createxpr::ReadP[Arg]
createxpr=do
滑雪场

cmd一个简单的解决方案是使用
Control.Monad中的
guard

假设函数像
isOpt::Arg->Bool
,它与

isOpt :: Arg -> Bool
isOpt (AddOpt _) = True
isOpt _          = False 
然后您对
createExpr
的定义将更改为

createExpr :: ReadP [Arg]
createExpr = do
    skipSpaces
    cmd <- SetCmd <$> cmdAliasExpr ["create", "add"]
    skipSpaces
    rest <-
      many1
      $   (AddWord <$> wordExpr)
      <|> (AddTag <$> addTagExpr)
      <|> (SetDue <$> dueExpr)
      <|> (AddOpt <$> optExpr)
    guard $ at_least_one_non_optional rest
    skipSpaces
    return $ cmd : rest
  where at_least_one_non_optional = not . null . filter (not . isOpt)
createxpr::ReadP[Arg]
createxpr=do
滑雪场

cmd您可以检查
rest
是否至少有一个单词/tag/due(
filter
,然后检查
null
),并使用
Control.Monad中的
guard
确保解析器在这种情况下失败。我不确定是否完全理解您所说的内容。你能给我举个例子吗?不要给问题添加答案……你读了所有的评论了吗?多亏了我得到的帮助,我找到了解决办法。我让店主(M.Aroosi)用我的发现更新他的答案,然后我会验证它。我明白你的意思。我用
isJust$find atLeastOne rest实现了同样的效果。但这会导致另一个问题。如果我键入
create--opt
,我有
[([SetCmd“create”,AddWord”--json“],”)]
。我猜这是因为
optExpr
失败了,它返回到
wordExpr
@soywod这听起来像你的
wordExpr
optExpr
都接受
“--json”
,在这种情况下解析器
(AddWord-wordExpr)(AddTag addTagExpr)(SetDue dueepr)(AddOpt-optExpr)
尝试了
wordExpr
optExpr
这两种方法都成功了。你说两种方法都尝试是什么意思?只有第一个失败了,它才会尝试一个,不是吗?事实上,
wordExpr
就像“垃圾”。与opt/tag/due不匹配的所有内容都将以单词结尾。
()
定义为
(+++)
对于可交换的
ReadP
,它会尝试所有选项并返回所有结果。例如,尝试使用解析器
(0确实是,
(
createExpr :: ReadP [Arg]
createExpr = do
    skipSpaces
    cmd <- SetCmd <$> cmdAliasExpr ["create", "add"]
    skipSpaces
    rest <-
      many1
      $   (AddWord <$> wordExpr)
      <|> (AddTag <$> addTagExpr)
      <|> (SetDue <$> dueExpr)
      <|> (AddOpt <$> optExpr)
    guard $ at_least_one_non_optional rest
    skipSpaces
    return $ cmd : rest
  where at_least_one_non_optional = not . null . filter (not . isOpt)