Bha*_*rni 5 parsing haskell parsec
我正在摆弄 Haskell 的parsec库。我试图将形式的十六进制字符串解析"#x[0-9A-Fa-f]*"为整数。这是我认为可行的代码:
module Main where
import Control.Monad
import Numeric
import System.Environment
import Text.ParserCombinators.Parsec hiding (spaces)
parseHex :: Parser Integer
parseHex = do
string "#x"
x <- many1 hexDigit
return (fst (head (readHex x)))
testHex :: String -> String
testHex input = case parse parseHex "lisp" input of
Left err -> "Does not match " ++ show err
Right val -> "Matched" ++ show val
main :: IO ()
main = do
args <- getArgs
putStrLn (testHex (head args))
Run Code Online (Sandbox Code Playgroud)
然后我尝试testHex在 Haskell 的 repl 中测试该函数:
GHCi, version 8.6.5: http://www.haskell.org/ghc/ :? for help
[1 of 1] Compiling Main ( src/Main.hs, interpreted )
Ok, one module loaded.
*Main> testHex "#xcafebeef"
"Matched3405692655"
*Main> testHex "#xnothx"
"Does not match \"lisp\" (line 1, column 3):\nunexpected \"n\"\nexpecting hexadecimal digit"
*Main> testHex "#xcafexbeef"
"Matched51966"
Run Code Online (Sandbox Code Playgroud)
第一次和第二次尝试按预期进行。但在第三个中,字符串匹配到无效字符。我不希望解析器执行此操作,而是如果字符串中的任何数字不是有效字符串,则不匹配。为什么会发生这种情况,如何解决这个问题?
谢谢你!
你需要放在eof最后。
parseHex :: Parser Integer
parseHex = do
string "#x"
x <- many1 hexDigit
eof
return (fst (head (readHex x)))
Run Code Online (Sandbox Code Playgroud)
或者,eof如果您想在其他地方重用,您可以将其与您使用的地方组合起来parseHex。
testHex :: String -> String
testHex input = case parse (parseHex <* eof) "lisp" input of
Left err -> "Does not match " ++ show err
Right val -> "Matched" ++ show val
Run Code Online (Sandbox Code Playgroud)