Parsec を使用して命題計算用のパーサーを作成しようとしています。パーサーはText.Parsec.ExprbuildExpressionParser
の関数を使用します。論理演算子を定義するコードを次に示します。
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"
変数、用語、および括弧で囲まれた式のパーサーは省略しましたが、それらが問題に関連している可能性があると思われる場合は、パーサーの完全なソースを読むことができます。
パーサーは、否定と論理積のみを使用する式 (つまり、唯一の前置演算子と最初の中置演算子) に対して成功します。
*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 "&"
接続詞のパーサーを定義する行をコメント アウトすると、論理和のパーサーが機能します (ただし、残りは失敗します)。それらすべてを 1 つのリスト (つまり、同じ優先順位) に入れることもできません。同じ問題が依然として現れます。
誰かが私が間違っていることを指摘できますか? どうもありがとう。
このような迅速で役立つ回答をくれた Daniel Fischer に感謝します。
このパーサーを正しく機能させるには、否定記号の繰り返し適用を処理する必要がありました。たとえば、~~p
正しく解析できるようにするためです。This SO answerはそれを行う方法を示しており、パーサーに加えた変更はhereにあります。