一般来说,我对haskell (我从不使用Monad、函子和其他东西)和FP非常陌生。我决定用一些扩展的可能性来编写最简单的解析器。(我对编程语言有普遍的兴趣,所以这就是我选择这样做的原因.)。
我有一个简单的解析器类型:
type Parser a = String -> (Maybe a, String)
-- (Nothing, ErrorMessage)
-- (Just a, Leftovers)如果没有任何字符,我可以解析任何字符并返回错误:
eatParser :: Parser Char
eatParser [] = (Nothing, "Unexpected EOF")
eatParser (x:xs) = (Just x, xs)我可以解析一个特定的字符:
charParser :: Char -> Parser Char
charParser c s = case eatParser s of
(Nothing, e) -> (Nothing, e)
(Just x, xs) | x == c -> (Just x, xs)
(Just x, _) | x /= c ->
(Nothing,
"Expected " ++ [c] ++ ", but got " ++ [x] ++ " instead.")另外,一个特定的字符串:
stringParser :: String -> Parser String
stringParser [] s = (Just "", s)
stringParser u s = case charParser (head u) s of
(Nothing, e) -> (Nothing, e)
(Just x, xs) -> case stringParser (tail u) xs of
(Nothing, e) -> (Nothing, e)
(Just x', xs') -> (Just $ x : x', xs')任何一个词:
varParser :: Parser String
varParser s = case eatParser s of
(Nothing, _) -> (Just [], [])
(Just x, xs) | not $ isLetter x -> (Just [], xs)
(Just x, xs) | isLetter x ->
case varParser xs of
(Nothing, e') -> (Nothing, e')
(Just [], _) -> (Just [x], xs)
(Just x', xs') ->
(Just $ x : x', xs')最后,表达式解析器
data Expr = Open Expr | Value String deriving (Show)
exprParser :: Parser Expr
exprParser s = case charParser '(' s of
(Nothing, _) -> case varParser s of
(Nothing, e) -> (Nothing, e)
(Just x, xs) -> (Just $ Value x, xs)
(Just _, xs) -> case exprParser xs of
(Nothing, e) -> (Nothing, e)
(Just q, xs') -> case charParser ')' xs' of
(Nothing, e) -> (Nothing, e)
(Just _, xs'') -> (Just $ Open q, xs'')下面是代码的一些示例:
*Test2> eatParser "abc"
(Just 'a',"bc")
*Test2> charParser 'a' "abc"
(Just 'a',"bc")
*Test2> charParser 'b' "abc"
(Nothing,"Expected b, but got a instead.")
*Test2> stringParser "abc" "abce"
(Just "abc","e")
*Test2> stringParser "abc" "abc"
(Just "abc","")
*Test2> stringParser "abc" "axbc"
(Nothing,"Expected b, but got x instead.")
*Test2> varParser "abc"
(Just "abc","")
*Test2> varParser "abc2"
(Just "abc","2")
*Test2> varParser "abc abc2"
(Just "abc"," abc2")
*Test2> exprParser "((aa))bc"
(Just (Open (Open (Value "aa"))),"bc")
*Test2> exprParser "((aa)b)bc)"
(Nothing,"Expected ), but got b instead.")我知道有一个方法可以简化所有的case ... s of (Nothing, e) -> (Nothing, e) (Just x, xs) -> ...
不使用parserSequence..。
你能告诉我能改进什么吗?预先感谢:D
发布于 2020-12-16 20:44:11
https://codereview.stackexchange.com/questions/253497
复制相似问题