Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 帕塞克<|&燃气轮机;在解析器中选择,错误抛出但不转到下一个解析器_Parsing_Haskell_Parsec - Fatal编程技术网

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