1

Look at the following recursive BNF rule

(1) X = Xa | b

This produces sentences like

X = b
X = ba
X = baa
X = baaa
...

This can be written as

(2) X = b a*

where the right hand side is not recursive

Now take a look at the following recursive BNF rule

(3) X = { X } | b

This produces sentences like

X = b
X = {b}
X = {{b}}
X = {{{b}}}
...

Is there some way to rewrite rule (3) in a non recursive way, analogous as we did when we rewrote rule (1) to rule (2).

Observe that X = {* b }* is no good since the parenthesis need to be balanced.

Bob Ueland
  • 1,804
  • 1
  • 15
  • 24
  • It's a bit guess but: x = (, ab)* a – Adam Ocsvari Apr 20 '15 at 22:39
  • BTW: for rule (3): x = {ab I'm not sure if it's good. – Adam Ocsvari Apr 20 '15 at 22:40
  • 1
    @AdamOcsvari , you don't have the brackets. And there is no comma involved. – ROMANIA_engineer Apr 20 '15 at 22:40
  • @helpYou: True! That's more simple: x = ab* a – Adam Ocsvari Apr 20 '15 at 22:43
  • He wants something like this `{(ab{)*a(})*}` or `({ab)*{a}(})*` but with more control - to have the same number as a replacement for `*` in both sides. (the number of open brackets should be equal to the number of closed brackets) – ROMANIA_engineer Apr 20 '15 at 22:45
  • Unless you extend EBNF with additional features to extract the number of '{' on the left and constrain the number of '}' on the right, there isn't. But there is nothing wrong with using pure BNF and recursion. As the string to analyze is not itself infinite, analysis will never perform infinite recursive descent, it will hit the bottom quickly. – David Tonhofer Jan 16 '17 at 23:58

1 Answers1

0

I do not know if the question above is possible to answer. The reason for the question above was that I wanted to avoid infinite loop in my parser (written in Java). One way was to insure that the BNF rules are not recursive, hence my question. But another way is to use the recursive rule, but avoid the infinite loop inside my (Java) program. Turns out that you can avoid loops by lazy instantiation.

For instance look at the following rules:

expression = term ('+' term)*;
term       = factor ('*' factor)*;
factor     = '(' expression ')' | Num;

expression() calls term(), which calls factor(), which calls expression(), thus we can end up with infinite loop. To avoid that we can use lazy instantiation, so instead of writing something like:

public Parser expression() {
    expression = new ...
    return expression;
}

we instead write:

public Parser expression() {
    if (expression == null) {
        expression = new ...
    }
    return expression;
}

Observe that you must declare expression as an instance variable to get this to work.

Bob Ueland
  • 1,804
  • 1
  • 15
  • 24
  • Maybe I am wrong, but an infinite loop in parsers means that a given rule calls itself over and over without consuming any input. This is what happens when a Left recursive rule is implemented using a recursive descent approach. It is not the case of the above grammar, since the parser has to consume the "(" before it calls empression again. No infinite loop. (edited:typo) – Branco Medeiros Apr 21 '15 at 18:47