我需要帮助写Haskell程序。我已经写了大部分内容,基本上我想要做的是:
当我在终端中输入 parse "a + b"
时,我希望得到以下输出:
Plus (Word "a") (Word "b")
当我在终端中输入 parse "a - 2 * b + c"
时,我希望输出为:
Minus (Word "a") (Plus (Mult (Num 2) (Word "b")) (Word "c"))
我的代码如下:
当我在终端中输入 parse "a + b"
时,我希望得到以下输出:
Plus (Word "a") (Word "b")
当我在终端中输入 parse "a - 2 * b + c"
时,我希望输出为:
Minus (Word "a") (Plus (Mult (Num 2) (Word "b")) (Word "c"))
我的代码如下:
data Ast
= Word String
| Num Int
| Mult Ast Ast
| Plus Ast Ast
| Minus Ast Ast
deriving (Eq, Show)
tokenize :: [Char] -> [String]
tokenize [] = []
tokenize (' ' : s) = tokenize s
tokenize ('+' : s) = "+" : tokenize s
tokenize ('*' : s) = "*" : tokenize s
tokenize (c : s)
| isDigit c =
let (cs, s') = collectWhile isDigit s
in (c : cs) : tokenize s'
| isAlpha c =
let (cs, s') = collectWhile isAlpha s
in (c : cs) : tokenize s'
| otherwise = error ("unexpected character " ++ show c)
collectWhile :: (Char -> Bool) -> String -> (String, String)
collectWhile p s = (takeWhile p s, dropWhile p s)
isDigit, isAlpha :: Char -> Bool
isDigit c = c `elem` ['0' .. '9']
isAlpha c = c `elem` ['a' .. 'z'] ++ ['A' .. 'Z']
parseU :: [String] -> (Ast, [String])
parseU ("+" : s0) =
let (e1, s1) = parseU s0
(e2, s2) = parseU s1
in (Plus e1 e2, s2)
parseU ("*" : s0) =
let (e1, s1) = parseU s0
(e2, s2) = parseU s1
in (Mult e1 e2, s2)
parseU (t : ts)
| isNumToken t = (Num (read t), ts)
| isWordToken t = (Word t, ts)
| otherwise = error ("unrecognized token " ++ show t)
parseU [] = error "unexpected end of input"
isNumToken, isWordToken :: String -> Bool
isNumToken xs = takeWhile isDigit xs == xs
isWordToken xs = takeWhile isAlpha xs == xs
parse :: String -> Ast
parse s =
case parseU (tokenize s) of
(e, []) -> e
(_, t : _) -> error ("unexpected token " ++ show t)
inn :: Ast -> String
inn (Plus x y) = innP x ++ " + " ++ innP y
inn (Mult x y) = innP x ++ " * " ++ innP y
inn ast = innP ast
innP :: Ast -> String
innP (Num n) = show n
innP (Plus x y) = "(" ++ innP x ++ " + " ++ innP y ++ ")"
innP (Mult x y) = "(" ++ innP x ++ " * " ++ innP y ++ ")"
innP (Word w) = w --
innfiks :: String -> String
innfiks s = inn (parse s)
目前我在终端中输入文本时遇到错误,但是如果我这样写:
parse "+ a b"
我会得到正确的输出:
Plus (Word "a") (Word "b")
我知道我必须更改代码,使其接受我以以下格式发送给解析函数的内容:
value operator value,
而不是这种形式:
operator value value
但我很难找到需要进行更改的内容和位置。