Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell whether parentheses are necessary or not?

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.

like image 414
Luke Collins Avatar asked Dec 02 '18 22:12

Luke Collins


People also ask

Do you know how to use parentheses?

Part of being a good writer means knowing how to use parentheses. Parentheses are a great tool to use to add extra information to a sentence. There are several grammatical reasons why you’d use parentheses in your writing. Along with the rules, there are some special cases and exceptions.

Do you put a period inside parenthesis?

Inside parenthesis, you may have just one word, a fragment, or a complete sentence. A lot of people get confused about whether or not to add a period inside parentheses. This is another topic we will cover! Parentheses are always used in pairs, so if you open them up, you have to close them with the other half.

How do you write a sentence without parentheses?

The best way to make sure your sentence is correct without the parentheses is to read the sentence and ignore the content in the parentheses. If the sentence makes sense, then it can stand as is. For example, here’s a correct and incorrect usage of parentheses:

How do you know if a parenthetical statement is correct?

Parenthetical text must stand completely outside of the grammar of the main sentence. To test this, simply remove or insert the parenthetical text. If the sentence’s grammar becomes incorrect or its meaning changes, your parenthetical text is not truly parenthetical.


1 Answers

Untested pseudocode:

instance Show Formula where
   showsPrec _p True  = "True"
   showsPrec _p False = "False"
   showsPrec p (And f1 f2) = showParen (p > 5) $
      showsPrec 5 f1 . (" & " ++) . showsPrec 5 f2
   showsPrec p (Forall x f) = showParen (p > 8) $
      ("forall " ++ x ++) . showsPrec 8 f
   ...

(I should probably use showString instead of those ++ above. It should work anyway, I think.)

Above, the integer p represents the precedence of the context where we are showing the current formula. For example, if we are showing f inside f & ... then p will have the precedence level of &.

If we need to print a symbol in a context which has higher precedence, we need to add parentheses. E.g. if f is a | b we can't write a | b & ..., otherwise it is interpreted as a | (b & ...). We need to put parentheses around a | b. This is done by the showParen (p > ...).

When we recurse, we pass the precedence level of the symbol at hand to the subterms.

Above, I chose the precedence levels randomly. You need to adjust them to your tastes. You should also check that the levels you choose play along the standard libraries. E.g. printing Just someFormula should not generate things like Just a & b, but add parentheses.

like image 192
chi Avatar answered Oct 27 '22 00:10

chi