2017-08-14 87 views
0

我試圖建立與伊德里斯一光年格式化。 整個項目到目前爲止是在這裏:光年解析器的行爲在意想不到的方式

https://github.com/hejfelix/IdrisFMT/blob/501a4a9e8b1b4154ed0d7836676c24d98de8b76a/IdrisFmt.idr

現在,目的是來標記文件本身,然後漂亮的打印出來,即文件作爲輸入應該是一個固定點。

這個問題是每個字符串文字,我的解析器似乎吃了空白之後。如果在字符串文字之後立即放置除空格之外的其他字符,它將解析該字符以及下面的所有空格。

此示例程序顯示錯誤:

main2 : IO() 
main2 = putStrLn $ str 
    where 
     str = case parse tokenParser "\"IdrisFMT.idr\" \n" of 
       (Left l) => "failed" ++ show l 
       (Right r) => show $ map (show @{default}) r 

此打印出:

*IdrisFMT> :exec main2 
["StringLiteral(\"IdrisFMT.idr\")"] 

如果我改變我解析到"\"IdrisFMT.idr\"c \n"字符串,我得到:

*IdrisFMT> :exec main2 
["StringLiteral(\"IdrisFMT.idr\")", "Identifier(c)", "' '", "'\\n'"] 

這是我的預期。

我相信從我解析字符串文本的方式出現錯誤,但我不理解我的錯誤,我無法找到調試光年解析器的好方法。 我的字符串字面解析器的實現如下:

escape : Parser String 
escape = do 
    d <- char '\\' 
    c <- oneOf "\\\"0nrvtbf" 
    pure $ pack $ (the $ List Char) [d,c] 

nonEscape : Parser String 
nonEscape = map (\x => pack $ (the $ List _) [x]) $ noneOf "\\\"\0\n\r\v\t\b\f" 

character : Parser String 
character = nonEscape <|>| escape 

stringLiteralToken : Parser Token 
stringLiteralToken = map (StringLiteral . concat) $ dquote (many character) 

如何防止我的字符串字面解析器從字面後吃起來空白?

+0

您在github存儲庫中提供的代碼似乎正常工作。在文字之後它不會吃掉空白。我建議你添加一個簡短的回答,描述你做什麼來解決問題。 – illabout

回答

0

在#idris頻道上聊天后,我瞭解到大部分內置的高階解析器(例如dquote)在最後跳過空格。 在我的情況下,這不是我想要的。相反,我使用了帶3個參數的between函數,何時開始的解析器,何時停止的另一個解析器,以及介於兩者之間的第三個參數。

要解析字符串文字,現在我這樣做:

escape : Parser String 
escape = do 
    d <- char '\\' 
    c <- oneOf "\\\"0nrvtbf'" 
    pure $ pack $ (the $ List Char) [d,c] 

nonEscape : Parser String 
nonEscape = map (\x => pack $ (the $ List _) [x]) $ noneOf "\\\"\0\n\r\v\t\b\f" 

character : Parser String 
character = nonEscape <|>| escape 

stringLiteralToken : Parser Token 
stringLiteralToken = map (StringLiteral . concat) $ (between (char '"') (char '"')) (many character) 

這解決了我的問題。

相關問題