6

J'essaie d'apprendre les bases de la Lemon parser generator, mais j'ai bloqué rapidement.Résoudre des conflits d'analyse dans une minuscule grammaire Lemon

Voici une petite grammaire:

%right PLUS_PLUS. 
%left DOT. 

program ::= expr. 

member_expr ::= expr DOT IDENTIFIER. 

lhs_expr ::= member_expr. 

expr ::= lhs_expr. 
expr ::= PLUS_PLUS lhs_expr. 

Il provoque 1 conflit analyse syntaxique:

State 3: 
     (3) expr ::= lhs_expr * 
     (4) expr ::= PLUS_PLUS lhs_expr * 

          DOT reduce  3  expr ::= lhs_expr 
          DOT reduce  4  ** Parsing conflict ** 
        {default} reduce  4  expr ::= PLUS_PLUS lhs_expr 

considérant que, si je réécris la dernière règle comme suit:

expr ::= PLUS_PLUS expr DOT IDENTIFIER. 

Ensuite, il provoque pas de conflits. Mais je ne pense pas que ce soit la bonne voie à suivre.

Je serais reconnaissant si quelqu'un pouvait expliquer ce qui est la bonne façon, et pourquoi.

+0

Je vous suggère de penser à cela sans les noms supplémentaires pour les choses. Partout où vous avez 'lhs_expr', vous pouvez simplement écrire' expr DOT IDENTIFIER' pour voir clairement ce qui est vraiment demandé. Si tout est en termes de 'expr ', vous pouvez voir le conflit plus clairement. –

+0

En d'autres termes, 'lhs_expr' peut être autre chose que' expr DOT IDENTIFIER'. Cette grammaire particulière ne contient pas d'autres règles, parce que je voulais que ce soit très minime, mais cela peut aussi être par exemple. 'IDENTIFIER', ou' expr LBRACKET expr RBRACKET', etc. Et je veux écrire la règle 'PLUS_PLUS lhs_expr' juste une fois, et couvrir toutes les expressions possibles du côté gauche étant pré-incrémentées. –

Répondre

5

Alors vous avez écrit une grammaire ambiguë, qui dit accepter:

++ x . y 

avec deux interprétations:

[++ x ] . y 

et

++ [x . y] 

où le [] sont juste ma façon montrer aux groupements. Lemon est un analyseur L (AL) R, et de tels analyseurs ne gèrent tout simplement pas les ambiguïtés (interprétations multiples). Le conflit réduire-réduire rapporté est ce qui se passe lorsque l'analyseur frappe ce point du milieu; Est-ce que le groupe "++ x" est "[++ x]"? ou comme "++ [x.]"? Les deux choix sont valides, et il ne peut pas choisir en toute sécurité.

Si vous restez avec Lemon (ou un autre générateur d'analyseur LALR), vous devez vous débarrasser du problème en changeant la grammaire. [Vous pouvez utiliser un générateur d'analyseur GLR; il accepterait et vous donnerait les deux analyses. Mais tout ce que vous avez fait est de pousser le problème de la résolution de l'ambiguïté vers l'expression post-analyse. Comme vous ne voulez pas d'ambiguïté, vous pourriez aussi bien l'éviter pendant l'analyse si vous le pouvez. Dans ce cas je pense que vous pouvez.]

Je pense que vous essayez de construire un langage de type C. Donc, vous voulez quelque chose comme ceci:

primitive_target ::= IDENTIFIER ; 
primitive_target ::= IDENTIFIER '[' expr ']' ; 
access_path ::= primitive_target ; 
access_path ::= access_path '.' primitive_target ; 

lhs ::= access_path ; 
lhs ::= PLUS_PLUS access_path ; 
lhs ::= access_path PLUS_PLUS ; 

program ::= expr ; 

expr ::= term ; 
expr ::= expr '+' term ; 
term :::= '(' expr ')' ; 
term ::= lhs ; 
term ::= lhs '=' expr ; 
term ::= constant ; 
+0

Merci pour la réponse. Mais, ne devrait pas l'ambiguïté de '++ x. y' être résolu par les priorités de 'PLUS_PLUS' et' DOT'? Compte tenu de ma grammaire, 'DOT' a une priorité plus élevée (car il apparaît après' PLUS_PLUS'). –

+0

Je ne connais pas les déclarations% ANTLR et% left. Ce que vous voulez essentiellement, c'est quelque chose qui force un changement lorsque vous rencontrez un point avec le contexte gauche contenant ++. Il n'est pas clair pour moi que% right et% ont quitté la force; my * guess * force-t-il l'associativité sur les opérateurs binaires, mais PLUS_PLUS n'est pas un opérateur binaire, donc cela peut être sans signification.Mon remède consistait à éviter ces déclarations spéciales et à forcer la grammaire à faire ce que je voulais (tu veux). –

+0

Ce n'est pas ANTLR, mais Lemon. Quoi qu'il en soit, merci beaucoup! –