Je suis nouveau chez CFG,
Quelqu'un peut-il me donner des conseils pour la création de CFG qui génère du langage?
Par exemple
L = {am bn | m >= n}
Ce que j'ai c'est:
So -> a | aSo | aS1 | e
S1 -> b | bS1 | e
mais je pense que cette zone est fausse, car il est possible que le nombre deb
soit supérieur àa
.
L = {am bn | m> = n}.
Description du langage: am bn composé de a
suivi de b
où le nombre de a
est égal ou supérieur au nombre de b
.
quelques exemples de chaînes: {^, a, aa, aab, aabb, aaaab, ab......}
Donc, il y a toujours un a
pour un b
mais des a
supplémentaires sont possibles. La chaîne infectée peut être constituée de a
uniquement. Notez également que ^
null est un membre du langage car dans ^
NumberOf(a) = NumberOf(b) = 0
Comment écrire une grammaire qui accepte le langage formé par des chaînes am bn?
Dans la grammaire, il devrait exister des règles telles que, si vous ajoutez un symbole b
, vous ajoutez également un symbole a
.
et cela peut être fait avec quelque chose comme:
S --> aSb
Mais ceci est incomplet car nous avons besoin d’une règle pour générer des a
s supplémentaires:
A --> aA | a
Combinez deux règles de production dans une même grammaire CFG.
S --> aSb | A
A --> aA | a
Ainsi, vous pouvez générer n’importe quelle chaîne composée de a
ainsi que a
et b
dans (am bn) modèle.
Mais dans la grammaire ci-dessus, il existe un moyen no de générer la chaîne ^
.
Alors, changez cette grammaire comme ceci:
S --> B | ^
B --> aBb | A
A --> aA | a
cette grammaire peut générer {am bn | m> = n} langue.
Note: pour générer ^
chaîne nulle, j'ai ajouté une première étape supplémentaire à la grammaire en ajoutant S--> B | ^
. Vous pouvez donc ajouter ^
ou votre chaîne de symbole a
et b
. (maintenant B
joue le rôle de S
de la grammaire précédente pour générer un nombre égal de a
et b
)
Edit: Merci à @Andy Hayden
Vous pouvez également écrire une grammaire équivalente pour la même langue {am bn | m> = n}:
S --> aSb | A
A --> aA | ^
remarque: ici A --> aA | ^
peut générer zéro ou un nombre quelconque de a
. Et cela devrait être préférable à ma grammaire, car elle génère un arbre d'analyse plus petit pour la même chaîne.
(plus petit en hauteur, préférable en raison d’une analyse efficace)
Les tips suivants peuvent être utiles pour écrire Grammar dans un langage formel:
- Vous devez expliquer clairement au langage ce qu'il décrit (sens/modèle).
- Vous pouvez vous rappeler des solutions à certains problèmes de base (l’idée étant que vous pouvez écrire de nouvelles grammaires).
- Vous pouvez écrire des règles pour les langages fondamentaux comme J'ai écrit pour RE dans cet exemple pour écrire Right-Linear-Grammmar . Les règles vous aideront à écrire Grammar for New Languages.
- Une approche différente consiste à dessiner d'abord automates, puis à convertir les automates en grammaire. Nous avons des techniques prédéfinies pour écrire de la grammaire à partir d’automates de toute classe de langage formel.
- Comme un bon programmeur qui apprend en lisant le code des autres, on peut également apprendre à écrire des grammaires pour des langages formels.
La grammaire que vous avez écrite est également fausse.
vous voulez créer une grammaire pour la langue suivante
L= {an bm | m>=n }
cela signifie que le nombre de 'b' devrait être supérieur ou égal au nombre de 'a' .__ ou vous pouvez dire que pour chaque 'b', il pourrait y avoir au plus un 'a' pas autrement.
voici la grammaire pour cette langue
S-> aSb | Sb | b | ab
dans cette grammaire pour chaque "a", il y a un "b". mais b peut être généré sans générer de 'a'.
vous pouvez aussi essayer ces langues:
L1= {an bm | m > n }
L2= {an bm | m >= 2n }
L3= {an bm | 2m >= n }
L4= {an bm | m != n }
je donne la grammaire pour chaque langue.
pour L1
S-> aSb | Sb | b
pour L2
S-> aSbb | Sb | abb
pour L3
S-> AASb | Sb | aab | ab | b
pour L4
S-> S1 | S2
S1-> aS1b | S1b | b
S2-> aS2b | aS2 | a
Moins variables: S -> a S b | un S | e
avec moins de variables:
S -> a S b | un S | a b | e