2012-12-03 30 views
6

我想寫使用秒差距命題演算的分析器。解析器使用Text.Parsec.Expr中的buildExpressionParser函數。以下是定義邏輯運算符的代碼。爲什麼只有第一個定義的中綴運算符在使用Parsec的buildExpressionParser時解析?

operators = [ [Prefix (string "~" >> return Negation)] 
      , [binary "&" Conjunction] 
      , [binary "|" Disjunction] 
      , [binary "->" Conditional] 
      , [binary "<->" Biconditional] 
      ] 

binary n c = Infix (spaces >> string n >> spaces >> return c) AssocRight 

expr = buildExpressionParser operators term 
    <?> "compound expression" 

我省略解析器爲變量,術語和parenthesised表達式,但如果你認爲他們可能是相關的問題,你可以閱讀full source for the parser

解析器成功用於使用僅否定和結合,即只有前綴操作者和所述第一操作者綴表達式。使用其他運營商

*Data.Logic.Propositional.Parser2> runPT expr() "" "p & ~q" 
Right (p ∧ ¬q) 

表達式失敗於操作的第一個字符,通過類似以下的錯誤:

*Data.Logic.Propositional.Parser2> runPT expr() "" "p | q" 
Left (line 1, column 3): 
unexpected "|" 
expecting space or "&" 

如果我註釋掉定義連詞解析器行,那麼解析器拆分會起作用(但其餘部分仍然會失敗)。將它們全部放入單個列表(即具有相同的優先級)也不起作用:同樣的問題仍然表現出來。

任何人都可以指出我做錯了什麼?非常感謝。


感謝Daniel Fischer對此提示和幫助。

爲了完成使這個解析器正常工作,我也需要處理否定符號的重複應用,使如~~p會解析正確。 This SO answer教我怎麼做,我給解析器所做的更改可以發現here

回答

8

您的問題是

binary n c = Infix (spaces >> string n >> spaces >> return c) AssocRight 

的第一次嘗試綴操作消耗空間也失敗過,所以後來的可能性沒有試過。 (秒差距有利於消費的解析器,並<|>只嘗試運行第二個解析器,如果第一個失敗沒有消耗任何輸入。)

要讓其他綴運營商試圖如果第一個失敗了,你既可以包裹binary解析器在一個try

binary n c = Infix (try $ ...) AssocRight 

,使得當這樣的解析器失敗,它不消耗任何輸入,或者,更好地,和傳統的解決這一問題,從它的初始spaces

binary n c = Infix (string n >> spaces >> return c) AssocRight 

,並把所有的解析器佔用空間他們解析

variable = do c <- letter 
       spaces 
       return $ Variable (Var c) 
     <?> "variable" 

parens p = do char '(' 
       spaces 
       x <- p 
       char ')' 
       spaces 
       return x 
     <?> "parens" 

當然,如果你有一個可以使用通用前綴解析運營商的解析器,你仍然需要包裝那些在令牌之後try因此,如果如解析>=失敗,>>=仍然可以嘗試。

懲戒開命題一個數據類型和改變佔用空間的行爲如上面所指出的,

*PropositionalParser Text.Parsec> head $ runPT expr() "" "p | q -> r & s" 
Right (Conditional (Disjunction (Variable (Var 'p')) (Variable (Var 'q'))) (Conjunction (Variable (Var 'r')) (Variable (Var 's')))) 

甚至更​​複雜的表達式進行解析。

+0

非常感謝Daniel的回答。解決問題並解釋它。我非常感激。 –

相關問題