Haskell Ast-> IO()

问题描述 投票:0回答:1

我一直在从事有关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之外,我不允许导入其他任何东西。

顺便说一句,我不允许更改任何功能

非常感谢您的帮助

parsing haskell abstract-syntax-tree pretty-print
1个回答
0
投票

换行并随着深度增加间距是您所需要的。

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>
© www.soinside.com 2019 - 2024. All rights reserved.