2013-03-30 63 views
0

我下面這個方案翻譯教程:http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/如何獲取秒差距解析倍數表達

,但似乎無法弄清楚如何設置REPL或秒差距,所以我可以有解釋的整體功能源文件。我想要做的是能夠從REPL進入這樣的事情:

:l ~/myscheme.scm 

和文件將被解釋。現在,它所做的只是解析一個表達式,而忽略其餘部分。我可以看到爲什麼這樣 - readExpr只讀取1個表達式。

分析器摘錄,整個代碼可以在這裏找到:http://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing

parseExpr :: Parser LispVal 
parseExpr = parseAtom 
     <|> parseString 
     <|> parseNumber 
     <|> parseQuoted 
     <|> do char '(' 
       x <- try parseList <|> parseDottedList 
       char ')' 
       return x 

readExpr :: String -> String 
readExpr input = case parse parseExpr "lisp" input of 
    Left err -> "No match: " ++ show err 
    Right _ -> "Found value" 

REPL:

import System.IO 

flushStr :: String -> IO() 
flushStr str = putStr str >> hFlush stdout 

readPrompt :: String -> IO String 
readPrompt prompt = flushStr prompt >> getLine 

evalString :: String -> IO String 
evalString expr = return $ extractValue $ trapError (liftM show $ readExpr expr >>= eval) 

evalAndPrint :: String -> IO() 
evalAndPrint expr = evalString expr >>= putStrLn 

until_ :: Monad m => (a -> Bool) -> m a -> (a -> m()) -> m() 
until_ pred prompt action = do 
    result <- prompt 
    if pred result 
    then return() 
    else action result >> until_ pred prompt action 

runRepl :: IO() 
runRepl = until_ (== "quit") (readPrompt "Lisp>>> ") evalAndPrint 

main :: IO() 
main = do args <- getArgs 
      case length args of 
       0 -> runRepl 
       1 -> evalAndPrint $ args !! 0 
       otherwise -> putStrLn "Program takes only 0 or 1 argument" 

希望得到任何幫助!

回答

2

parse (many parseExpr)而不是parse parseExpr

然後您將不得不修改解釋器,以便它可以解釋表達式列表。

+0

如果你想讓'[ParseError a]而不是'ParseError [a]'? – mk12