I am trying to write a parser for calculating statements using Parsec. The parser uses the buildExpressionParser function from Text.Parsec.Expr . Here is the code where I define the logical operators.
operators = [ [Prefix (string "~" >> return Negation)] , [binary "&" Conjunction] , [binary "|" Disjunction] , [binary "->" Conditional] , [binary "<->" Biconditional] ] binary nc = Infix (spaces >> string n >> spaces >> return c) AssocRight expr = buildExpressionParser operators term <?> "compound expression"
I skipped parsers for variables, terms, and expressions in parentheses, but if you think they might be related to the problem, you can read the full source for the parser .
The parser succeeds for expressions that use only negation and compound, i.e. the only prefix operator and the first infix operator.
*Data.Logic.Propositional.Parser2> runPT expr () "" "p & ~q" Right (p ∧ ¬q)
Expressions using any other operators fail with the first character of the operator with an error similar to the following:
*Data.Logic.Propositional.Parser2> runPT expr () "" "p | q" Left (line 1, column 3): unexpected "|" expecting space or "&"
If I comment on the line defining the parser for the conjunctions, then the parser for the disjunction will work (but the rest will still fail). Inclusion of all of them in one list (i.e., of the same priority) does not work either: the same problem still appears.
Can someone point out what I'm doing wrong? Many thanks.
Thanks to Daniel Fisher for such a quick and helpful answer.
To finish this analyzer, I also need to handle repetitive negation symbol applications, so that, for example, ~~p will parse correctly. This "SO" answer showed me how to do this, and the change I made for the analyzer can be found.