Re: How detect grammar not derive nonterminals ?

Andy <borucki.andrzej@gmail.com>
Wed, 13 Sep 2023 13:17:35 -0700

          From comp.compilers

Related articles
How detect grammar not derive nonterminals ? borucki.andrzej@gmail.com (Andy) (2023-09-11)
Re: How detect grammar not derive nonterminals ? gah4@u.washington.edu (gah4) (2023-09-12)
Re: How detect grammar not derive nonterminals ? borucki.andrzej@gmail.com (Andy) (2023-09-13)
Re: How detect grammar not derive nonterminals ? 864-117-4973@kylheku.com (Kaz Kylheku) (2023-09-14)
Re: How detect grammar not derive nonterminals ? gah4@u.washington.edu (gah4) (2023-09-14)
| List of all articles for this month |
From: Andy <borucki.andrzej@gmail.com>
Newsgroups: comp.compilers
Date: Wed, 13 Sep 2023 13:17:35 -0700
Organization: Compilers Central
References: 23-09-001
Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="75595"; mail-complaints-to="abuse@iecc.com"
Keywords: parse
Posted-Date: 13 Sep 2023 20:39:05 EDT
In-Reply-To: 23-09-001

wtorek, 12 września 2023 o 19:42:28 UTC+2 Andy napisał(a):
> The simplest this case is grammar :
> it is trap for sequence generator. A->B->A->B->A....
> How detect similar cases, especially without computing First and Follow sets ?


I test my grammars:
above
;A->B->A->B....
A -> B
A -> b B
B -> A
B -> a A


;L grows up infinitely
G -> S
G -> L
G -> s
S -> i b t G
L -> i b t L e G
; if will exists L-: some_terminals it will ok, but not exists


E -> E + i
E -> E * i


S -> i S


S -> S i


I found solution: all w these cases handle computing minimal length of nonterminal and rules.
How correct compute it:
```
Rule {
boolean computeMinLen() {
                int old = minLen;
                minLen = 0;
                for (Symbol symbol : this)
                        if (!symbol.terminal && grammar.getNT(symbol.index).minLen<0) {
                                minLen = -1;
                                return minLen != old;
                        }
                for (Symbol symbol : this)
                        if (symbol.terminal)
                                minLen++;
                        else
                                minLen += grammar.getNT(symbol.index).minLen;
                return minLen != old;
        }
}


Nonterminal {
boolean computeMinLen() {
                int old = minLen;
                boolean changed = false;
                for (Rule rule : rules) {
                        if (rule.computeMinLen())
                                changed = true;
                }
                for (Rule rule : rules) {
                        if (rule.minLen >= 0) {
                                if (minLen<0)
                                        minLen = rule.minLen;
                                else
                                        minLen = Math.min(minLen, rule.minLen);
                        }
                }
                return minLen != old || changed;
        }
}


and loop if not change:
boolean changed = true;
                while (changed) {
                        changed = false;
                        for (Nonterminal nt : nonterminals) {
                                if (nt.computeMinLen())
                                        changed = true;
                        }
                }


and check:
int index = 0;
                for (Nonterminal nt : nonterminals) {
                        if (nt.minLen < 0)
                                throw new NoMinLenGrammarException("not computed minLen for " + getNonTerminalName(index));
                        for (Rule ruleInfo: nt.rules)
                                if (ruleInfo.minLen < 0)
                                        throw new NoMinLenGrammarException("not computed minLen for " + ruleInfo.toString());
                        index++;
                }


```
-----------------
But what doing if grammar is correct but has generator trap :
A->A
A->a
generates "a" but generator , which I write, calls A->A->...
should be transformed by eliminate A->A


A->B
A->a
B->A
B->b


is cycle A->B->A...
should be transformed by eliminate A->B or B->A


how detect all similar cases and how transform it in general case?


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.