Haskell - 写一个小解析器

fuu*_*man 1 parsing haskell

我想为足球比分写一点解析器.

例如,"0:2"应该将输入解析为Just (Score 0 2).如果有类似的"3:3"东西应该给我"Nothing".其他一切也应该给我"Nothing".

data Score = Score Int Int
deriving (Eq,Show,Ord)


runParsec :: Parser a -> String -> Maybe a
runParsec parser input = case runP parser () "" input of
Left  _ -> Nothing
Right a -> Just a
Run Code Online (Sandbox Code Playgroud)

我将runParsec作为参数提供的解析器直到现在看起来像这样:

parseScore :: Parser Score
parseScore str1 = case str1 of
    "x:y" && (x /= y)   -> Right Score x y
    Otherwise           -> Left x
Run Code Online (Sandbox Code Playgroud)

我知道,parseScore的这段代码无法正常工作.因为我无法模式匹配像"x:y"这样的字符串.但是我该如何解决这个问题呢?

runParsec parseScore "0:2" 应该给我 Just (Score 0 2)

我很感谢提示.

谢谢!

Sib*_*ibi 5

只需Parser为您的类型编写适当的内容并过滤掉您不需要的内容:

import Control.Applicative ((<$>))
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Char

data Score = Score Int Int deriving (Show)

parseScore :: Parser Score
parseScore = do
  a <- integer
  char ':'
  b <- integer
  return $ Score a b

integer :: Parser Int
integer = read <$> many1 digit

runParsec :: String -> Maybe Score
runParsec input = case parse parseScore "" input of
  Left e -> Nothing
  Right e -> case e of
    Score 0 2 -> Just e
    _ -> Nothing
Run Code Online (Sandbox Code Playgroud)

演示ghci:

?> runParsec "0:2"
Just (Score 0 2)
?> runParsec "3:3"
Nothing
?> runParsec "3:4"
Nothing
Run Code Online (Sandbox Code Playgroud)

我能做什么,如果我想接受所有分数,1:0,0:4等等?一切,但没有随机输入像"jirjgir"和没有相同的分数,如"2:2"或"5:5"

只需更改过滤条件:

runParsec :: String -> Maybe Score
runParsec input = case parse parseScore "" input of
  Left e -> Nothing
  Right e -> case e of
    Score x y -> if x == y
                 then Nothing
                 else Just e
Run Code Online (Sandbox Code Playgroud)

演示:

?> runParsec "1:0"
Just (Score 1 0)
?> runParsec "0:4"
Just (Score 0 4)
?> runParsec "2:2"
Nothing
?> runParsec "jiraf"
Nothing
Run Code Online (Sandbox Code Playgroud)