I have written a parser in Haskell, which parses formulas in the form of string inputs and produces a Haskell data
type defined by the BNF below.
formula ::= true
| false
| var
| formula & formula
| ∀ var . formula
| (formula)
var ::= letter { letter | digit }*
Now I would like to create an instance of Show
so that I can nicely print the formulas defined by my types (I don't want to use deriving (Show)
). My question is: How do I define my function so that it can tell when parentheses are necessary? I don't want too many, nor too little parentheses.
For example, given the formula ∀ X . (X & Y) & (∀ Y . Y) & false
which, when parsed, produces the data structure
And (And (Forall "X" (And (Var "X") (Var "Y"))) (Forall "Y" (Var "Y"))) False
we have
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
Is there a way to gauge how many parenthesis are necessary so that the semantics is never ambiguous? I appreciate any feedback.