2017-10-06 29 views
2

有人可以告訴我這裏有什麼問題嗎?我找不出錯誤在哪裏。我對haskell很陌生,所以我不知道語法atm的每個規則。Haskell - 語法錯誤

parseS (s:xs) | all isDigit s = (xs, Lit (read s)) 
      | s == " " = parseS xs 
      | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
      | s == "+" = (xs'', Sum e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

      | s == "*" = (xs'', Mul e e') where  <- parse error on input on this line 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 
+2

請將此處的代碼,錯誤,示例數據或文本輸出以純文本的形式發佈,而不是可能難以閱讀的圖像,不能複製粘貼以幫助測試代碼或在答案中使用,並且不利於那些使用屏幕閱讀器的人。您可以編輯您的問題以在問題的正文中添加代碼。使用'{}'按鈕來格式化任何代碼塊,或使用四個空格縮進以獲得相同的效果。我們無法將您的屏幕截圖作爲代碼運行。 – tadman

+3

請逐字發佈錯誤消息。 –

回答

2

這是哈斯克爾是如何看待你的代碼:

parseS (s:xs) 
     | all isDigit s = (xs, Lit (read s)) 
     | s == " " = parseS xs 
     | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e) 
     | s == "+" = (xs'', Sum e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

| s == "*" = (xs'', Mul e e') 
    where 
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

一個where塊連接到一個聲明,而你的情況是整個parseS定義。

|開頭的下一行被視爲新聲明的開始,因爲無法以|開始聲明,所以無效。

最簡單的解決方法是停止使用where本地綁定,並使用let代替,就像這樣:

  | s == "+" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Sum e e') 

      | s == "*" = 
       let 
        (xs', e) = parseS xs 
        (xs'', e') = parseS xs' 
       in 
       (xs'', Mul e e') 
3

的問題是,第一where條款被視爲定義爲parseS (s:xs)結束。之後,您正試圖添加另一個受保護的案例,但解析器不會將其視爲附加到相同的定義。

有幾種方法可以解決這個問題。

可以使用let ... in而不是爲s == "+"

 | s == "+" = let (xs', e) = parseS xs 
         (xs'', e') = parseS xs 
        in (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

解決這個問題,但有一個更簡單的方法來做到這一點 - 只是丟棄where條款。

 | s == "+" = (xs'', Sum e e') 
     | s == "*" = (xs'', Mul e e') where 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 

where條款中定義的變量範圍的定義(所有後衛的情況下)的全部,所以你的xs''定義可以爲這兩種情況下被重用。