This is a continuation to this question I asked earlier about a BNFC-grammar for propositional logic. I got it working with parentheses, as per the definition, but I would now like to extend the grammar to work without parentheses, with a catch however: no unnecessary outer parentheses allowed.
For example, the atomic sentence a
should be allowed, but (a)
should not be recognized. The sentence (a => b) & c
should also be allowed, but ((a => b) & c)
not, and so forth. The last example highlights the necessity for paretheses. The precedence levels are
- equivalence
<=>
and implication=>
, - conjuction
&
and disjunction|
- negation
-
and - atoms.
The higher the level, the earlier it will be parsed.
I got the grammar working with the unnecessary parentheses, by setting precedence levels to the different operators via recursion:
IFF . L ::= L "<=>" L1 ;
IF . L ::= L "=>" L1 ;
AND . L1 ::= L1 "&" L2 ;
OR . L1 ::= L1 "|" L2 ;
NOT . L2 ::= "-" L3 ;
NOT2 . L2 ::= "-" L2 ;
P . L3 ::= Ident ;
_ . L ::= L1 ;
_ . L1 ::= L2 ;
_ . L2 ::= L3 ;
_ . L3 ::= "(" L ")" ;
Now the question is, how do I not allow the outer parentheses, the allowance of which is caused by the last rule L3 ::= "(" L ")";
? It is strictly necessary for allowing parentheses inside an expression, but it also allows them on the edges. I guess I need some extra rule for removing ambiguity, but what might that be like?
This grammar also results in about 6 reduce/reduce conflicts, but aren't those pretty much inevitable in recursive definitions?