Haskell的级联解析器

托默

我的解析器类型是

newtype Parser a = Parser { parse :: String -> Maybe (a,String) }

我有两个解析器:

1)a = (satisfy isAlpha)知道如何匹配字符串中的第一个字母数字字符。

跑步parse a "k345"Just ('k',"345")

2)b = many (satisfy isDigit)知道如何匹配任意数量的数字。跑步parse b "1234 abc"Just ("1234"," abc")

现在,我想结合这两个解析器,并匹配一个单字母数字字符,后跟任意数量的数字。

我试过了:

parse (a *> b) "k1234 7"并得到了Just ("1234"," 7 ")看起来'k'第一个解析器匹配的内容a从输出中消失了。我该如何解决这个问题?

谢谢!

Y

对于玩具解析器,请查看以下代码:

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
module Parse where

import Data.Char
import Data.List

newtype Parser a = Parser 
  { parse :: String -> Maybe (a, String) }

satisfy :: (Char -> Bool) -> Parser Char
satisfy cond = Parser $ \s ->
   case s of 
     "" -> Nothing 
     (c:cs) -> if cond c then Just (c, cs) else Nothing

many :: Parser a -> Parser [a]
many p = Parser $ \s -> 
  case parse p s of 
    Nothing -> Just ([], s)
    Just (c, cs) -> let Just (cc, cs') = parse (many p) cs
                     in Just (c:cc, cs')

string :: String -> Parser String 
string str = Parser $ \s -> if isPrefixOf str s 
                               then Just (str, drop (length str) s)
                               else Nothing

instance Functor Parser where 
  fmap f (Parser g) = Parser $ \s -> 
    case g s of
      Nothing -> Nothing
      Just (r, remain) -> Just (f r, remain)

instance Applicative Parser where
  pure a = Parser $ \s -> Just (a, s)
  -- (<*>) :: f (a -> b) -> f a -> f b
  (Parser f) <*> (Parser g) = Parser $ \s -> 
    case f s of
      Nothing -> Nothing
      Just (ab, remain) -> case g remain of
                            Nothing -> Nothing
                            Just (r, remain1) -> Just (ab r, remain1)

instance Semigroup a => Semigroup (Parser a) where 
  (Parser p1) <> (Parser p2) = Parser $ \s -> 
    case p1 s of 
      Nothing -> Nothing 
      Just (r1, s1) -> case p2 s1 of 
                         Nothing -> Nothing 
                         Just (r2, s2) -> Just (r1 <> r2, s2)

instance (Monoid a, Semigroup (Parser a))=> Monoid (Parser a) where
  mempty = Parser $ \s -> Just (mempty, s)
  mappend = (<>)

a = satisfy isAlpha
b = many (satisfy isDigit)
λ> parse a "k345"
Just ('k',"345")
λ> parse b "12345 abc"
Just ("12345"," abc")
λ> parse (a *> b) "k1234 7"
Just ("1234"," 7")
λ> parse (string "k" <> b) "k1234 7"
Just ("k1234"," 7")

因此,也许你应该找到一些教程,并尝试熟悉FunctorApplicativeMonad看,您可以Monoid为您的Parser类型实现a的实例,然后可以使用(<>)来将解析的结果组合在一起。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Haskell解析器组合器

来自分类Dev

解析器(Haskell)的更好应用实例

来自分类Dev

在Haskell中合并解析器

来自分类Dev

使用Parsec的Haskell HTML解析器

来自分类Dev

用解析器组合器解析Haskell本身

来自分类Dev

如何使用Haskell解析器解析任意列表?

来自分类Dev

真实世界的Haskell的CSV解析器实现

来自分类Dev

从头开始在Haskell中编写解析器

来自分类Dev

如何在EOF停止Haskell Parsec解析器

来自分类Dev

Haskell中使用GHCi的功能解析器示例

来自分类Dev

Haskell:Turtle:命令行解析器

来自分类Dev

具有拼写检查功能的haskell解析器

来自分类Dev

如何通过单词列表制作Haskell解析器?

来自分类Dev

在Haskell(Parsec)中链接两个解析器

来自分类Dev

使用monad进行简单的Haskell解析器

来自分类Dev

Haskell-编写一个小解析器

来自分类Dev

用 Haskell 为 Person 编写解析器

来自分类Dev

Haskell Aeson - Gloss - JSON 实例解析器:颜色

来自分类Dev

算术解析器

来自分类Dev

对话解析器

来自分类Dev

OsmInEdit的解析器

来自分类Dev

对话解析器

来自分类Dev

WikiRank 解析器

来自分类Dev

Haskell 解析中 CPS 与非 CPS 解析器的堆使用情况

来自分类Dev

Haskell Parsec组合器“很多”应用于接受空字符串的解析器

来自分类Dev

Haskell Parsec组合器“很多”应用于接受空字符串的解析器

来自分类Dev

如何使argparse解析器也充当子解析器

来自分类Dev

Android SimpleXml解析器数据解析器错误

来自分类Dev

Python LDIF解析器