Haskell Ast -> IO ()
Haskell Ast -> IO ()
我一直在做关于 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))
现在我要做的是编写一个函数,以正确的缩进打印 given 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
以便它 returns 字符串 "Sum\n---Int 8\n---Mult\n------Int9\n------Int10"
(“-”仅用于可视化空格)(我在正确的轨道上吗?将如果没有一些非常复杂的代码,这甚至是可能的?)。我还必须使打印树的缩进增加 3 个空格(我该怎么做?)。从我的研究中,我遇到了一种叫做 prettyprint 的东西,但问题是我不允许导入除 Data.Char.
以外的任何东西
顺便说一句,我不能更改任何功能
非常感谢帮助
您需要换行符和随深度增加的间距。
spacing n = concat $ take n (repeat " ")
showw :: Ast -> String
showw ast = showw2 ast 0
showw2 :: Ast -> Int -> String
showw2 (Mult a a') n = spacing n ++ "Mult" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Sum a a' ) n = spacing n ++ "Sum" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Min a a' ) n = spacing n ++ "Min" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Int i ) n = spacing n ++ "Int " ++ show i ++ "\n"
示例输出
putStr $ showw $ parse "+ 8 * 9 10"
Sum
Int 8
Mult
Int 9
Int 10
*Main>
我一直在做关于 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))
现在我要做的是编写一个函数,以正确的缩进打印 given 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
以便它 returns 字符串 "Sum\n---Int 8\n---Mult\n------Int9\n------Int10"
(“-”仅用于可视化空格)(我在正确的轨道上吗?将如果没有一些非常复杂的代码,这甚至是可能的?)。我还必须使打印树的缩进增加 3 个空格(我该怎么做?)。从我的研究中,我遇到了一种叫做 prettyprint 的东西,但问题是我不允许导入除 Data.Char.
顺便说一句,我不能更改任何功能
非常感谢帮助
您需要换行符和随深度增加的间距。
spacing n = concat $ take n (repeat " ")
showw :: Ast -> String
showw ast = showw2 ast 0
showw2 :: Ast -> Int -> String
showw2 (Mult a a') n = spacing n ++ "Mult" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Sum a a' ) n = spacing n ++ "Sum" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Min a a' ) n = spacing n ++ "Min" ++ "\n" ++ showw2 a (n+1) ++ showw2 a' (n+1)
showw2 (Int i ) n = spacing n ++ "Int " ++ show i ++ "\n"
示例输出
putStr $ showw $ parse "+ 8 * 9 10"
Sum
Int 8
Mult
Int 9
Int 10
*Main>