Parsing Haskell:运算符解析器一直使用未定义的而不是输入
我在练习写语法分析器。我用它作为参考。我试图通过解析任意长度的算法来增加它,我已经提出了以下ASTParsing Haskell:运算符解析器一直使用未定义的而不是输入,parsing,haskell,Parsing,Haskell,我在练习写语法分析器。我用它作为参考。我试图通过解析任意长度的算法来增加它,我已经提出了以下AST data HVal = HInteger Integer -- No Support For Floats | HBool Bool | HNull | HString String | HChar Char | HList [HVal] | HObj [(String, HVal)] deriving (Show, Eq, Read) data Op -- Th
data HVal
= HInteger Integer -- No Support For Floats
| HBool Bool
| HNull
| HString String
| HChar Char
| HList [HVal]
| HObj [(String, HVal)]
deriving (Show, Eq, Read)
data Op -- There's only one operator for the sake of brevity at the moment.
= Add
deriving (Show, Read)
newtype Parser a = Parser {
runParser :: String -> Maybe (String, a)
}
以下函数是我实现运算符解析器的尝试
ops :: [Char]
ops = ['+']
isOp :: Char -> Bool
isOp c = elem c ops
spanP :: (Char -> Bool) -> Parser String
spanP f = Parser $ \input -> let (token, rest) = span f input
in Just (rest, token)
opLiteral :: Parser String
opLiteral = spanP isOp
sOp :: String -> Op
sOp "+" = Add
sOp _ = undefined
parseOp :: Parser Op
parseOp = sOp <$> (charP '"' *> opLiteral <* charP '"')
我不知道错误发生在哪里。我假设这与sOp
有关,主要是因为其他函数与parseOp
的其余部分一样,都是parseString
函数的翻译:
stringLiteral :: Parser String
stringLiteral = spanP (/= '"')
parseString :: Parser HVal
parseString = HString <$> (charP '"' *> stringLiteral <* charP '"')
()
的实现是罪魁祸首。在下一次调用q
时,您没有使用input'
,而是使用了input
。因此,您可以将字符串传递给下一个解析器,而无需“吃掉”字符。您可以通过以下方法解决此问题:
instance Applicative Parser where
pure x = Parser $ \input -> Just (input, x)
(Parser p) <*> (Parser q) = Parser $ \input -> do
(input', f) <- p input
(input'', a) <- q input'
Just (input'', f a)
嗯,
+
符号没有被解析。你到底传递给解析器什么?我忘了把它加进去!我在编辑中添加了它,但我在GHCI中做了以下操作:λ>runParser parseOp“\”+\”
您发布的所有代码对我来说都很好;请同时发布charP
和Applicative
实例。@leftaroundabout我添加了它们!
charP :: Char -> Parser Char
charP x = Parser $ f
where f (y:ys)
| y == x = Just (ys, x)
| otherwise = Nothing
f [] = Nothing
instance Applicative Parser where
pure x = Parser $ \input -> Just (input, x)
(Parser p) <*> (Parser q) = Parser $ \input -> do
(input', f) <- p input
(input', a) <- q input
Just (input', f a)
instance Applicative Parser where
pure x = Parser $ \input -> Just (input, x)
(Parser p) <*> (Parser q) = Parser $ \input -> do
(input', f) <- p input
(input'', a) <- q input'
Just (input'', f a)
*Main> runParser parseOp "\"+\""
Just ("",Add)