我在用 Parsec 制作的 haskell 中有一个抽象语法树。我希望能够在遍历它的同时查询它的结构,以便将其转换为中间代码。例如,我需要知道我的 AST 的任何给定函数需要多少参数才能进行这种翻译。我目前正在做的是将 AST 传递给每个函数,这样我就可以在需要进行查找时调用它,并且我在另一个文件中有辅助函数来为我进行查找。这污染了我的类型签名。尤其是当我开始添加更多的东西时,比如累加器。
而不是将 AST 传递给我听说过的每个函数,这对于 Reader Monad(对于不改变的状态,AST)和 State Monad(对于确实改变的状态,累加器)来说是一个很好的工作。
如何从 IO monad ( gulp ) 中取出 ast 并在 Reader Monad 中使用它来进行全局查找?
main = do
putStrLn "Please enter the name of your jack file (i.e. Main)"
fileName <- getLine
file <- readFile (fileName++".jack")
let ast = parseString file
writeFile (fileName++".xml") (toClass ast) --I need to query this globally
putStrLn $ "Completed Parsing, " ++ fileName ++ ".vm created..."
type VM = String
toClass :: Jack -> VM
toClass c = case c of
(Class ident decs) ->
toDecs decs
toDecs ::[Declaration] -> VM -- I don't want to add the ast in every function arg...
toDecs [] = ""
toDecs (x:xs) = case x of
(SubDec keyword typ subname params subbody) ->
case keyword of
"constructor" -> --use the above ast to query the # of local variables here...
toSubBody subbody ++
toDecs xs
otherwise -> []
Reader Monad 进度更新:我已将上面的示例转换为如下内容:(见下文)。但是现在我想知道由于所有这些字符串输出的积累,我是否也应该使用作家 Monad?如果是这样,我应该如何组合这两者?ReaderT 应该封装作家吗?或相反亦然?我是否应该创建一个只接受 Reader 和 Writer 而不尝试将它们组合为 Monad Transformer 的类型?
main = do
putStrLn "Please enter the name of your jack file (i.e. Main)"
fileName <- getLine
file <- readFile (fileName++".jack")
writeFile (fileName++".xml") (runReader toClass $ parseString file)
putStrLn $ "Completed Parsing, " ++ fileName ++ ".xml created..."
toClass = do
env <- ask
case env of Class ident decs -> return $ toDecs decs env
toDecs [] = return ""
toDecs ((SubDec keyword typ subname params subbody):xs) = do
env <- ask
res <- (case keyword of
"method" -> do return "push this 0\n"
"constructor" -> do return "pop pointer 0\nMemory.alloc 1\n"
otherwise -> do return "")
return $ res ++ toSubBody subbody env ++ toDecs xs env
toDecs (_:xs) = do
decs <- ask
return $ toDecs xs decs
toSubBody (SubBodyStatement states) = do
return $ toStatement states
toSubBody (SubBody _ states) = do
return $ toStatement states
http://hpaste.org/83595 --for 声明