Я работал над заданием о разборе в Haskell. Я сделал функцию для анализа строки в абстрактном синтаксическом дереве, и это работает как надо.
Краткий пример того, как синтаксический анализатор работает с ранее созданным кодом:
tokenize :: String -> [String]
tokenize [] = []
tokenize xs @ (x : xs')
| x `elem` t = [x] : tokenize xs'
| isDigit x = [y | y <- takeWhile isDigit xs] : (tokenize (dropWhile isDigit xs))
| otherwise = tokenize xs'
where t = ['+', '-', '*']
--parseExpr recursively goes through list and produces ast
parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Error!"
parseExpr (s:ss) | all isDigit s = (Int (read s),ss)
| s == "-" = let (e,ss') = parseExpr ss in (Min e,ss')
| s == "*" = (Mult e e',ss'')
| s == "+" = (Sum e e',ss'') where
(e,ss') = parseExpr ss
(e',ss'') = parseExpr ss'
-- parse returns the first in the tuple returned from parseExpr
parse :: String -> Ast
parse [] = error "Empty string"
parse str = fst $ parseExpr x
where x = tokenize str
parse "+ 8 * 9 10"
>> Sum (Int 8) (Mult (Int 9) (Int 10))
Теперь мне нужно написать функцию, которая печатает данные ast с правильным отступом.
Вот функции:
showw :: Ast -> String
showw ast = ???
show :: Ast -> IO ()
show ast = putStr (showw ast)
Итак:
show (parse "+ 8 * 9 10")
Sum
Int 8
Mult
Int 9
Int 10
Нужно ли писать showw :: Ast -> String
, чтобы он возвращал строку "Sum\n---Int 8\n---Mult\n------Int9\n------Int10"
(«-» только здесь, чтобы визуализировать пробелы) (Я здесь на правильном пути? Будет ли это вообще возможно без какого-то невероятно сложного кода?). Я также должен сделать так, чтобы напечатанное дерево имело увеличивающийся отступ в 3 пробела (Как бы я это сделал?). Из моего исследования я обнаружил нечто, называемое prettyprint, но проблема в том, что мне не разрешено импортировать что-либо кроме Data.Char.
Кстати, мне не разрешено изменять какие-либо функции
Помощь с благодарностью