Je comprends que LR et LALR sont des algorithmes d'analyse ascendante, mais quelle est la différence entre les deux?
Quelle est la différence entre l'analyse syntaxique LR (0), LALR (1) et LR (1)? Comment savoir si une grammaire est LR (0), LALR (1) ou LR (1)?
À un niveau élevé, la différence entre LR (0), LALR (1) et LR (1) est la suivante:
Un analyseur syntaxique LALR (1) est une version "mise à niveau" d'un analyseur syntaxique LR (0) qui garde la trace d'informations plus précises pour lever la ambiguïté de la grammaire. Un analyseur syntaxique LR (1) est un analyseur syntaxique considérablement plus puissant qui garde la trace d'informations encore plus précises qu'un analyseur syntaxique LALR (1).
Les analyseurs syntaxiques LALR (1) sont un facteur constant plus grand que les analyseurs syntaxiques LR (0) et les analyseurs syntaxiques LR (1) sont généralement plus grands que les analyseurs syntaxiques LALR (1).
Toute grammaire pouvant être analysée avec un analyseur LR (0) peut être analysée avec un analyseur LALR (1) et toute grammaire pouvant être analysée avec un analyseur LALR (1) peut être analysée avec un analyseur LR (1). Il existe des grammaires LALR (1) mais pas LR (0) et LR (1) mais pas LALR (1).
Plus formellement, un analyseur syntaxique LR (k) est un analyseur syntaxique ascendant qui fonctionne en maintenant une pile de terminaux et de non-terminaux. L’analyseur est contrôlé par un automate fini qui détermine, en fonction de l’état actuel de l’analyseur et des k prochains jetons, si shift un nouveau jeton sur la pile ou réduire les symboles supérieurs de la pile en appliquant une production en sens inverse.
Afin de conserver suffisamment d'informations pour pouvoir déterminer si un décalage ou une réduction est nécessaire, les analyseurs syntaxiques LR (k) font en sorte que chaque état correspond à un "ensemble de configuration", un ensemble de productions annotées avec les informations suivantes:
La première de ces informations est utilisée pour déterminer si l'analyseur doit éventuellement effectuer une réduction - si aucune des productions dans l'état actuel n'est terminée, il n'y a aucune raison de procéder à une réduction. La deuxième de ces informations est utilisée lors d’une réduction pour déterminer si elle doit être effectuée ou non. Lorsqu'il décide de réduire ou non, un analyseur LR (k) examine les k prochains jetons du flux d'entrée. S'ils correspondent aux jetons lookahead, l'analyseur réduira et sinon, l'analyseur ne fera rien.
Des problèmes surviennent dans un analyseur LR (k) lorsqu'il existe des conflits sur ce que l'analyseur doit faire dans un état donné. Un type de conflit, un décalage/réduction du conflit, survient lorsque l'analyseur est dans un état où une production est terminée, mais les symboles d'apparence de ce conflit de production sont également utilisés par une autre production inachevée. Etat. Cela signifie que l'analyseur ne peut pas dire s'il faut ou non effectuer la réduction. Un deuxième type de conflit est un {réduire/réduire le conflit}, où l'analyseur sait qu'il doit effectuer une réduction, mais deux réductions ou plus sont possibles et il ne sait pas laquelle faire.
Intuitivement, au fur et à mesure que k grandit, l'analyseur dispose de plus en plus d'informations précises pour déterminer quand changer et quand réduire. Si une grammaire n'est pas LR (0), par exemple, l'analyseur peut avoir un état dans lequel il n'est pas possible de déterminer s'il doit être décalé ou réduit. Cependant, cette grammaire pourrait encore être LR (1) car, avec un gage supplémentaire d'anticipation, elle pourrait peut-être reconnaître qu'elle devrait définitivement changer et ne pas réduire ou réduire définitivement et non pas changer.
Le problème des analyseurs syntaxiques LR (k) est que, lorsque k augmente, le nombre d'états peut augmenter de manière exponentielle. La lecture anticipée dans les analyseurs syntaxiques LR (k) est gérée en construisant de plus en plus d’états dans l’analyseur pour correspondre à différentes combinaisons de productions et d’indifférences, de sorte que le nombre d’observations possibles augmente également. Par conséquent, les analyseurs syntaxiques LR (1) sont généralement trop volumineux pour être pratiques, et LR (2) ou une version supérieure est pratiquement inconnue dans la pratique.
LALR (1) a été inventé comme un compromis entre l’efficacité spatiale des analyseurs syntaxiques LR (0) et le pouvoir d’expression des analyseurs syntaxiques LR (1). Il y a plusieurs façons de penser à ce qu'est un analyseur LALR (1). À l'origine, les analyseurs syntaxiques LALR (1) étaient spécifiés comme une transformation qui convertissait les automates LR (1) en automates plus petits. Bien qu'un analyseur syntaxique LR (1) puisse avoir beaucoup plus d'états qu'un automate LR (0), la seule différence est qu'un analyseur syntaxique LR (1) peut avoir plusieurs copies d'un état particulier dans un automate LR (0), chacune annotée avec différentes informations de prévision. Un analyseur LALR (1) peut être formé en commençant par un analyseur LR (1), puis en combinant tous les états ayant le même "noyau" (l'ensemble des productions et leurs positions), puis en agrégeant toutes les informations d'anticipation. Cela se traduit par un analyseur qui a le même nombre d'états qu'un analyseur LR (0) mais conserve une quantité d'informations sur les anticipations pour éviter les conflits entre LR.Une autre vue des grammaires LALR (1) utilise la méthode "LALR-by-SLR". Les analyseurs LALR (1) peuvent être construits en commençant par un analyseur LR (0) pour une grammaire, puis en créant une nouvelle grammaire pour le langage qui annote les non-finales avec des informations sur les états de l'analyseur LR (0) auquel elles correspondent. Les informations sur les ensembles FOLLOW des non-finaux de cette grammaire peuvent ensuite être utilisées pour calculer les valeurs d'anticipation dans l'analyseur LR (0).
Le résultat net est que.
J'espère que cela t'aides!.
Hope this helps!
L'algorithme d'analyse d'un bon analyseur LALR (1) est différent de deux manières: (1) il doit comporter des actions de décalage de réduction, ce qui réduit le nombre d'états d'environ 30% et accélère l'analyse, et (2) il doit effectuez une ou plusieurs réductions lors de la détection d'une erreur de syntaxe, ce qui rend la récupération d'erreur plus compliquée.
L'algorithme d'analyse d'un analyseur syntaxique LR (1) canonique (1) ne comporte pas d'actions de réduction de décalage et (2) n'effectue aucune réduction lors de la détection d'une erreur de syntaxe, ce qui simplifie la récupération d'erreur.
Il existe un autre cas, appelé minimal LR (1), qui utilise les mêmes algorithmes d’analyse syntaxique et de récupération d’erreur que LALR (1). Les analyseurs syntaxiques LR (1) minimaux offrent la puissance de LR (1) et leur taille est presque aussi petite que celle de LALR (1). Le générateur d’analyseur LRSTAR crée un nombre minimal d’analyseurs LR (1) pour les programmeurs C++.
Les analyseurs syntaxiques LR (0), SLR (1), LALR (1) ont tous le même nombre d'états. Les analyseurs syntaxiques LR (1) minimaux auront quelques états supplémentaires si la grammaire le requiert, pour éviter les conflits de réduction à réduction.
Les analyseurs syntaxiques LR (1) de Canonical auront beaucoup plus d'états, trop pour les langages informatiques moyens ou grands.
Les générateurs d’analyse syntaxique SLR (1) construisent une machine à états LR (0) et déterminent les valeurs k = 1 en examinant la grammaire (qui peut signaler des conflits erronés).
Les générateurs d’analyse syntaxique LALR (1) construisent une machine à états LR (0) et déterminent les valeurs k = 1 en examinant la machine à états LR (0) (ce qui est très compliqué).
Les générateurs d’analyseur LR (1) Canonical construisent une machine à états LR (1).
Les générateurs d’analyseur LR (1) minimaux construisent une machine à états LR (1) et fusionnent des états compatibles au cours du processus de construction.