À un niveau élevé, la différence entre l'analyse syntaxique LL et l'analyse syntaxique LR est que les analyseurs LL commencent au symbole de départ et essaient d'appliquer des productions pour arriver à la chaîne cible, alors que les analyseurs LR commencent à la chaîne cible et essaient de revenir au symbole de départ.
Une analyse syntaxique LL est une dérivation de gauche à droite et de gauche à droite. C'est-à-dire que nous considérons les symboles d'entrée de gauche à droite et essayons de construire une dérivation la plus à gauche. Cela se fait en commençant par le symbole de départ et en développant de manière répétée le non terminal le plus à gauche jusqu'à ce que nous arrivions à la chaîne cible. Une analyse syntaxique LR est une dérivation de gauche à droite, la plus à droite, ce qui signifie que nous balayons de gauche à droite et essayons de construire une dérivation la plus à droite. L'analyseur choisit continuellement une sous-chaîne de l'entrée et tente de l'inverser en un non-terminal.
Pendant une analyse LL, l'analyseur choisit continuellement entre deux actions :
-
Prévoir : Sur la base du non terminal le plus à gauche et d'un certain nombre de tokens lookahead, choisir quelle production doit être appliquée pour se rapprocher de la chaîne d'entrée.
-
Match : Faire correspondre le symbole terminal deviné le plus à gauche avec le symbole non consommé le plus à gauche de l'entrée.
A titre d'exemple, étant donné cette grammaire :
- S → E
- E → T + E
- E → T
- T →
int
Puis, étant donné la chaîne de caractères int + int + int
un analyseur LL(2) (qui utilise deux tokens de lookahead) analyserait la chaîne comme suit :
Production Input Action
---------------------------------------------------------
S int + int + int Predict S -> E
E int + int + int Predict E -> T + E
T + E int + int + int Predict T -> int
int + E int + int + int Match int
+ E + int + int Match +
E int + int Predict E -> T + E
T + E int + int Predict T -> int
int + E int + int Match int
+ E + int Match +
E int Predict E -> T
T int Predict T -> int
int int Match int
Accept
Remarquez qu'à chaque étape, nous examinons le symbole le plus à gauche de notre production. Si c'est un terminal, nous le faisons correspondre, et si c'est un non-terminal, nous prédisons ce qu'il va être en choisissant une des règles.
Dans un analyseur LR, il y a deux actions :
-
Équipe : Ajouter le prochain jeton d'entrée à un tampon pour considération.
-
Réduire : Réduire une collection de terminaux et de non-terminaux dans ce tampon à un certain non-terminal en inversant une production.
Par exemple, un analyseur LR(1) (avec un token de lookahead) pourrait analyser cette même chaîne comme suit :
Workspace Input Action
---------------------------------------------------------
int + int + int Shift
int + int + int Reduce T -> int
T + int + int Shift
T + int + int Shift
T + int + int Reduce T -> int
T + T + int Shift
T + T + int Shift
T + T + int Reduce T -> int
T + T + T Reduce E -> T
T + T + E Reduce E -> T + E
T + E Reduce E -> T + E
E Reduce S -> E
S Accept
Les deux algorithmes d'analyse syntaxique que vous avez mentionnés (LL et LR) sont connus pour avoir des caractéristiques différentes. Les analyseurs LL ont tendance à être plus faciles à écrire à la main, mais ils sont moins puissants que les analyseurs LR et acceptent un ensemble de grammaires beaucoup plus restreint que les analyseurs LR. Les analyseurs LR existent en plusieurs versions (LR(0), SLR(1), LALR(1), LR(1), IELR(1), GLR(0), etc.) et sont beaucoup plus puissants. Ils ont également tendance à être beaucoup plus complexes et sont presque toujours générés par des outils tels que yacc
ou bison
. Les analyseurs syntaxiques LL existent également sous de nombreuses formes (y compris LL(*), qui est utilisé par le module ANTLR
), bien qu'en pratique, LL(1) soit le plus largement utilisé.
Si vous souhaitez en savoir plus sur l'analyse syntaxique LL et LR, je viens de terminer un cours sur les compilateurs et j'ai des documents et des diapositives de cours sur l'analyse syntaxique sur le site web du cours. Je serais heureux de développer l'un d'entre eux si vous pensez que cela peut être utile.