我正在尝试使用 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"
我省略了变量、术语和括号表达式的解析器,但如果您认为它们可能与问题相关,您可以阅读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 提供了如此迅速而有帮助的答案。
为了使这个解析器正常工作,我还需要处理否定符号的重复应用,以便 eg~~p
能够正确解析。这个 SO answer向我展示了如何做到这一点,我对解析器所做的更改可以在这里找到。