2012-11-22 37 views
1

我想讓這個解析器工作。我目前不太確定錯誤在哪裏。它主要來自Parsec部分的「給你寫一個方案」我的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 }' 
+3

你有'char')'return x' 'lindaCmd'的末尾。 – huon

回答

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 ...

+0

至於我下面從這裏的例子實際上是符號:http://hackage.haskell.org/packages/archive/parsec/latest/doc/html/Text-Parsec-Combinator.html#v:sepBy –

+1

'symbol'似乎是['GenTokenParser'](http://hackage.haskell.org/packages/archive/parsec/latest/doc/html/Text-Parsec-Token.html#t:GenTokenParser)數據類型的字段。你所遵循的例子不是過時就是總是出錯。 – dave4420

+0

在lindaCmd中仍然存在問題,無論是字符串,因爲LindaTpl是預期的還是在最後一行中的其他方式。 –