Question

I'm trying to make a grammar that doesn't have operator precedence, but requires that either you use one operator or enclose them in parenthesis. (Using test instead of id|int_literal etc and + instead of a list of valid operators here for simplicity). So for example:

test + test ///valid!
(test + test) + test ///valid!
(test + test) + (test + test) /// valid!
test + test + test /// invalid!

Is there any way to write a grammar for this that doesn't require backtrack=true? I don't think left-factoring really makes sense here and I'm not sure how a syntactic predicate would help.

Here's what I have (requires backtrack=true):

fragment
bexpr : 'test' | '(' cbebr ')';

fragment
cbexpr : bexpr '+' bexpr;

expr : bexpr | cbexpr;
Était-ce utile?

La solution

You might want to look at How to remove global backtracking from your grammar.

The ambiguity lies in the fact that both alternatives of expr can start with a bexpr. You need to get rid of this ambiguity. The key lies in the observation that a + only occurs without parentheses if it is the entire expression. So we end up with:

expr : operand ('+' operand)?;
operand : '(' expr ')' | 'test';

In other words: if an operator expression occurs as an operand, then it must be enclosed in parentheses.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top