我目前正在編寫一個簡單的編程語言的解析器。它到達那裏,但我無法解析布爾邏輯語句,如「i == 0 AND j == 0」。所有我回來的是「非窮舉模式的情況下」Haskell卡在解析布爾邏輯
當我自己解析一個布爾表達式它可以很好地工作,例如, 「我== 0」。注意「i == 0 a」也會返回一個布爾語句,但「i == 0 AND」不返回任何內容。
任何人都可以幫忙嗎?
雖然上述作品正確輸入,如運行parseBoolean「我== 0」
我目前正在編寫一個簡單的編程語言的解析器。它到達那裏,但我無法解析布爾邏輯語句,如「i == 0 AND j == 0」。所有我回來的是「非窮舉模式的情況下」Haskell卡在解析布爾邏輯
當我自己解析一個布爾表達式它可以很好地工作,例如, 「我== 0」。注意「i == 0 a」也會返回一個布爾語句,但「i == 0 AND」不返回任何內容。
任何人都可以幫忙嗎?
雖然上述作品正確輸入,如運行parseBoolean「我== 0」
由於@hammar指出,你應該使用Text.Parsec.Expr
爲這種事情。但是,既然這是作業,也許你必須以艱難的方式去做!
的問題是在parseArithmetic
,你讓anyChar
是一個運營商,但隨後在case語句,你只允許+
,-
,*
,/
,%
和^
。當parseArithmetic
試圖解析i == 0
時,它使用第一個=
作爲運算符,但不能從第二個=
解析intExp2
,並且在轉到case語句之前在monad和backtracks中失敗。但是,當您嘗試分析i == 0 AND j == 0
,它得到了i ==
一部分,但後來認爲有中0 A ND
,其中A
是運營商的一個算術表達式,並ND
是一些變量的名稱,所以它得到的情況, boom。順便提一句,不是使用解析器來匹配字符串,然後使用case語句再次匹配它,你可以讓你的解析器返回一個函數而不是一個字符串,然後直接應用這個函數:
parseOp :: String -> a -> Parser a
parseOp op a = string op >> spaces >> return a
parseLogic :: Parser BoolExp
parseLogic = do
boolExp1 <- parseBoolExp
spaces
operator <- choice [ try $ parseOp "AND" And
, parseOp "OR" Or
, parseOp "XOR" XOr
]
boolExp2 <- parseBoolExp
return $ operator boolExp1 boolExp2
parseBoolean :: Parser BoolExp
parseBoolean = do
intExp1 <- parseIntExp
spaces
operator <- choice [ try $ parseOp "==" Main.EQ
, parseOp "=>" GTorEQ
, parseOp "<=" LTorEQ
]
intExp2 <- parseIntExp
return $ operator intExp1 intExp2
感謝帕特。我正在考慮parseArithmetic中的錯誤。如果我使用選擇讓它像上面一樣,你認爲它應該工作嗎?或者有沒有更好的方法來做到這一點? 現在我已經開始這樣做了,下次我將使用Text.Parsec.Expr。我這樣做是因爲這是我們如何在類中進行解析。 – user1424720
我還沒有調試過你的整個解析器,但只允許你想要而不是使用'anyChar'是一件好事。 – pat
另外,您可能希望所有的終端解析器都以'spaces'結尾,這樣就不需要在非終端上遍撒'spaces'。這就是'lexeme'組合器的用途。 – pat
請不要鏈接到外部代碼。請不要只是在這裏轉儲所有的代碼。縮小問題範圍,然後寫出具體問題以及相關代碼,預期產出和實際產出。 –
呃...你是否檢查過相關的病例陳述? –
您是否嘗試添加默認情況? – phg