Parsing 帕塞克<|&燃气轮机;在解析器中选择,错误抛出但不转到下一个解析器
我正在通过Parsing 帕塞克<|&燃气轮机;在解析器中选择,错误抛出但不转到下一个解析器,parsing,haskell,parsec,Parsing,Haskell,Parsec,我正在通过为自己编写一个方案学习haskell 我目前正在尝试在scheme中实现一个char识别。字符是\或\类似\\A或\\或\\space 因此,我编写了以下代码: -- .. some code .. data LispVal = Atom String | List [LispVal] | DottedList [LispVal] LispVal | String String |
为自己编写一个方案
学习haskell
我目前正在尝试在scheme中实现一个char
识别。字符是\
或\
类似\\A
或\\
或\\space
因此,我编写了以下代码:
-- .. some code ..
data LispVal = Atom String
| List [LispVal]
| DottedList [LispVal] LispVal
| String String
| Number Integer
| Bool Bool
| Char Char deriving Show
-- .... More code ...
parseChar :: Parser LispVal
parseChar = liftM Char (parseSingleChar <|> parseSpecialCharNotation)
parseSingleChar :: Parser Char
parseSingleChar = do string "#\\"
x <- letter
return x
parseSpecialCharNotation :: Parser Char
parseSpecialCharNotation = do string "#\\"
x <- (parseSpace <|> parseNewline)
return x
parseSpace :: Parser Char
parseSpace = do char 's'
char 'p'
char 'a'
char 'c'
char 'e'
return ' '
parseNewline :: Parser Char
parseNewline = do char 'n'
char 'e'
char 'w'
char 'l'
char 'i'
char 'n'
char 'e'
return '\n'
-- .. some more code...
readExpr :: String -> String
readExpr input = case parse parseExpr "lisp" input of
Left err -> "Parse Error: " ++ show err
Right val -> "Found value: " ++ show val
为了解决这个问题,我将parseChar
更改为
parseChar :: Parser LispVal
parseChar = liftM Char (parseSpecialCharNotation <|> parseSingleChar)
为什么会这样?当parseSpecialCharNotation
失败时,它不应该移动到parseSingleChar
完整代码位于:来自for
:
该解析器被称为预测解析器,因为只有当解析器p不使用任何输入时(即,前瞻性为1),才会尝试q
在您的情况下,两个解析都会在失败之前使用“\\\”
,因此无法评估其他替代方法。您可以使用try
确保回溯按预期工作:
解析器try p
的行为类似于解析器p
,只是它假装在发生错误时没有使用任何输入
类似于下一个:
try parseSpecialCharNotation <|> parseSingleChar
do
string "#\\"
try parseSpecialCharNotation <|> parseSingleChar
此外,您还可以使用combinator代替一系列char
解析器
try parseSpecialCharNotation <|> parseSingleChar
do
string "#\\"
try parseSpecialCharNotation <|> parseSingleChar