我在 Haskell 中编写了一个解析器,它以字符串输入的形式解析公式,并生成data由下面的 BNF 定义的 Haskell 类型。
formula ::= true
| false
| var
| formula & formula
| ∀ var . formula
| (formula)
var ::= letter { letter | digit }*
现在我想创建一个实例,Show以便我可以很好地打印我的类型定义的公式(我不想使用deriving (Show))。我的问题是:如何定义我的函数,以便它可以判断何时需要括号?我不想要太多,也不想要太少的括号。
例如,给定公式∀ X . (X & Y) & (∀ Y . Y) & false,该公式在解析时会生成数据结构
And (And (Forall "X" (And (Var "X") (Var "Y"))) (Forall "Y" (Var "Y"))) False
我们有
Too little parentheses: ∀ X . X & Y & ∀ Y . Y & false
Too much parentheses: (∀ X . (((X) & (Y)))) & (∀ Y . (Y)) & (false)
Just right: ∀ X . (X & Y) & (∀ Y . Y) & false
有没有办法衡量需要多少个括号,以便语义永远不会模棱两可?我很感激任何反馈。