我想让这个解析器工作。我目前还不太清楚错误在哪里。它主要取自“写你一个方案”的Parsec部分
还有一个问题:如果它最终有效,是否有任何方法可以确保以问号开头的字符串始终是列表中的最后一个?
input_text :: String
input_text = "Eval (isFib::, 1000, ?BOOL)"
data LTuple
= Command [LTuple]
| Number Integer
| String String
| Query Bool
deriving (Eq, Ord, Show)
data Command = Rd | Read | In | Take | Wr | Out | Eval
deriving (Eq, Ord, Show)
main :: IO ()
main = do
case parse lindaCmd "example" input_text of
Left err -> print err
Right res -> putStrLn $ "I parsed: '" ++ res ++ "'"
parseList :: Parser lindaTpl
parseList = liftM Command $ sepBy1 lindaCmd ( symbol "," )
lindaCmd = string "rd"
<|> string "take"
<|> string "out"
<|> string "eval"
<|> do char '('
x <- try parseList
char ')'return x
当前的错误消息是:
test.hs:30:48:
Couldn't match expected type `ParsecT s0 u0 m0 sep0'
with actual type `String -> ParsecT s1 u1 m1 String'
In the return type of a call of `symbol'
Probable cause: `symbol' is applied to too few arguments
In the second argument of `sepBy1', namely `(symbol ",")'
In the second argument of `($)', namely
`sepBy1 lindaCmd (symbol ",")'
test.hs:38:17:
The function `char' is applied to three arguments,
but its type `Char -> ParsecT s0 u0 m0 Char' has only one
In a stmt of a 'do' block: char ')' return x
In the second argument of `(<|>)', namely
`do { char '(';
x <- try parseList;
char ')' return x }'
In the second argument of `(<|>)', namely
`string "eval"
<|>
do { char '(';
x <- try parseList;
char ')' return x }'
答案 0 :(得分:3)
第一个错误:
parseList = liftM Command $ sepBy1 lindaCmd ( symbol "," )
应该是
parseList = liftM Command $ sepBy1 lindaCmd ( string "," )
第二个错误,正如dbaupp指出的那样,
<|> do char '('
x <- try parseList
char ')'return x
应该是
<|> do char '('
x <- try parseList
char ')'
return x
这应该解决你现在的两个错误,但我还没有检查是否还有。
编辑:
你有
parseList :: Parser lindaTpl
但我希望你想要
parseList :: Parser LTuple
我希望你也想要
lindaCmd :: Parser LTuple
并且还必须修改lindaCmd
的主体---所有除了最终分支似乎都想要类型Parser String
...