在遵循教程Write yourself a Scheme in 48 hours的過程中,我試圖增強解析代碼以創建對十六進制,八進制,二進制和十進制文字的支持。使用Parsec設計解析代碼
import Text.ParserCombinators.Parsec hiding (spaces)
import Control.Monad
import Numeric
hexChar :: Parser Char
hexChar = ...
octChar :: Parser Char
octChar = ...
hexNumber :: Parser Integer
hexNumber = do
char '#'
char 'x'
s <- many1 hexChar
return $ (fst . head) readHex s
octNumber :: Parser Integer
octNumber = do
char '#'
char 'o'
s <- many1 hexChar
return $ (fst . head) readOct s
如果我們在這個討論中忘記了十進制和二進制數:
parseNumber :: Parse Integer
parseNumber = hexNumber <|> octNumber
那麼這個解析器將無法識別八進制數。這似乎與需要從十六進制數字中區分出十六進制數和八進制數的前瞻字符的數量有關(如果我們在語法中刪除前導'#',那麼解析器將工作)。因此,我們似乎不得不重新審視的代碼和「分比化」龍頭「#」可以這麼說,通過降低在個別解析器的char '#'
和定義:
parseNumber = char '#' >> (hexNumber <|> octNumber)
這是不錯,但我發現的代碼少愉快。不知何故,如果我有一個叫hexNumber
的函數,我希望它識別#xffff
(這是合適的Scheme語法),而不是xffff
。這是我必須忍受的事情,還是有辦法繞過主角#的強制分解?
非常感謝你! –