La grammaire non contextuelle suivante présente une ambiguïté de type "balançant le reste" (imaginez que représente et b représente et c représente un autre type d'instruction ou de bloc):
Sif expr then
else
Par exemple,aacbcpeut être analysé comme(a(acbc))ou comme(a(ac)bc)(c'est le mot ambigu le plus simple / le plus court pour cette grammaire).
La manière "standard" de résoudre cette ambiguïté "pendant pendant" oblige l' instruction "else" ( ) à s'apparier avec le "if-then" ( a ) le plus proche / le plus proche . Cela peut être accompli comme suit: S Cette grammaire est sans ambiguïté. Dans l'exemple ci-dessus, il force l'analyse(a(acbc)).
Question: Existe - t-il un autre moyen naturel de résoudre l'ambiguïté qui forcerait l' analyse de a a c b c ? En d'autres termes, je recherche une grammaire qui génère le même langage que les deux ci-dessus, qui est sans ambiguïté, et qui analyse a a c b c comme ( a ( a c ) b c ) .
Remarque: Ma première tentative a été la suivante: qui résout l'ambiguïté deaacbcselon les besoins - mais cette grammaire est toujours ambiguë:aacbacbcpeut être analysée comme(a(ac)b(acbc))ou comme(a(acb(ac))bc).
la source
Réponses:
Ce problème est un analogue exact du problème de correspondance des parenthèses dans une expression dans laquelle certaines des parenthèses fermées ont été omises. Ici, un "si" (ou dans la grammaire représentative) est une parenthèse ouverte et un "autre" ( b ) est une parenthèse étroite. (À partir de la séquence de a s et b s, vous pouvez insérer mécaniquement c s en plaçant un avant chaque b et un à la fin.) Parce que cela correspond mieux à mon cerveau entre parenthèses, j'écris comme si c'était le problème.a b a b c b
La résolution traditionnelle "Correspondance la plus proche", sinon correspond à chaque fermeture avec l'ouverture la plus récente encore inégalée. Cela signifie qu'il n'y a jamais d'ouverture ouverte (ou de fermeture, d'ailleurs) entre une ouverture correspondante et sa fermeture correspondante.
Une alternative possible serait de faire correspondre chaque fermeture avec l'ouverture la plus rapprochée possible et inégalée. "Faisable" signifie ici que l'ouverture peut être mise en correspondance sans violer l'imbrication entre parenthèses (par exemple, la première dans ( ) ( ) ne peut pas correspondre à la dernière ) ).( ()() )
Cette correspondance doit être effectuée de l'extérieur vers l'intérieur, de sorte qu'aucune correspondance pour une fermeture ne soit tentée tant que toutes les paires englobantes n'ont pas été mises en correspondance. Ce fait rend impossible la production d'une analyse avec un algorithme d'anticipation bornée, car l'analyse doit fonctionner vers l'intérieur à partir des deux extrémités, après avoir divisé la chaîne en segments complètement correspondants (car ceux-ci limitent efficacement la plage de correspondances potentielles).
Cependant, le fait qu'il n'existe pas d'analyseur de gauche à droite en ligne n'implique pas qu'il n'y a pas de CFG sans ambiguïté. (Évidemment: une langue palindromique doit être analysée des deux extrémités vers le milieu, mais il est facile d'écrire une grammaire non ambiguë).
Pour produire une grammaire pour le problème de parenthèse "le plus éloigné", je me suis appuyé sur le fait qu'une ouverture sans correspondance ne peut pas être suivie d'une ouverture avec correspondance. Si tel était le cas, la propriété de correspondance la plus éloignée ne s'appliquerait pas car l'ouverture sans correspondance aurait pu correspondre à la fermeture de l'ouverture correspondante, donc le fait qu'elle ne soit pas correspondante viole la propriété de correspondance la plus éloignée.
Voici donc la grammaire légèrement maladroite:
Il existe probablement une meilleure solution de contournement que celle que j'ai choisie. Mais celui-ci semble fonctionner, et il fonctionne bien avec l'analyseur GLR de Bison que j'ai utilisé pour le tester; cet analyseur se plaint des analyses ambiguës sauf si vous écrivez du code supplémentaire pour gérer l'ambiguïté, et j'étais trop paresseux pour le faire. Je l'ai testé avec des chaînes allant jusqu'à 20 ouvert + ferme, et il semble avoir produit une analyse sans ambiguïté pour chaque séquence correctement imbriquée, sans produire d'analyses pour les séquences incorrectement imbriquées.
la source
Prenez a + b + c + d + e et abcde. Il existe deux façons évidentes comment une grammaire pourrait les analyser, mais il y a une façon que nous utilisons.
Dans le cas du "balançoire d'autre", ce n'est pas vraiment la façon dont les gens le voient. Au lieu de cela, la syntaxe est interprétée comme "si", suivi de zéro, d'un ou plusieurs "else si", suivi d'un "else" facultatif.
la source