2016-03-14 3 views
0

J'utilise l'outil JavaCUP pour produire un analyseur pour ma langue. J'essaie d'écrire une grammaire qui correspond à des instructions if_else imbriquées et multiples.Parsing shift-reduce conflict

fichier d'entrée

// matches 
if() 
    if() 

    else 

    if() 

    else 
else 

// no match -> modifying grammar leads to shift/reduce conflict 
if() 

else 

Grammaire

expr ::= if_then_else_statement; 

if_then_else_statement ::= IF LPAREN RPAREN if_then_else_statement ELSE if_then_else_statement 
         | ; 

Cette grammaire correspond à des déclarations if_else imbriquées. Cependant, il ne reconnaît que la première instruction if_else imbriquée de mon fichier d'entrée.

J'ai modifié ma grammaire afin de faire correspondre plusieurs déclarations comme ceci:

expr ::= expr if_then_else_statement; 
     | ; 

if_then_else_statement ::= IF LPAREN RPAREN if_then_else_statement ELSE if_then_else_statement 
         | ; 

Le résultat a été un changement/réduire les conflits causés par la règle vide (je suppose). Comment puis-je le modifier pour prendre en charge les instructions imbriquées et multiples if_else sans utiliser la priorité?

+0

Avez-vous une règle qui correspond à plusieurs instructions? – rici

+0

Oui, après l'avoir modifié, expr pourrait être réduit à expr if_then_else_statement qui pourrait être réduit à expr if_then_else_statement if_then_else_statement et finalement à if_then_else_statement if_then_else_statement. Mais cela ne fonctionne qu'en théorie – pirox22

Répondre

0

La solution habituelle serait quelque chose comme ceci:

expr_list ::= | expr_list expr ; 
expr ::= if_then_else_statement ; 
if_then_else_statement ::= IF LPAREN RPAREN expr ELSE expr ; 

Cela ne permet pas vide else clauses (ou then clauses vides), car une clause else vide est ambigu: il n'y a aucun moyen de savoir si le s2 dans if() s1 else s2 est la clause else ou une instruction qui suit une instruction if complète avec une clause else vide.

Pour résoudre cette ambiguïté, vous avez besoin terminateurs de déclaration (par exemple.) Ou points-virgules if terminateurs déclaration (fi et end sont des choix communs) ou autre chose.

+0

Cela ne fonctionne pas non plus. Avertissement: *** Shift/Réduire le conflit trouvé dans l'état # 10 entre if_then_else_statement :: = SI LPAREN RPAREN expr_list ELSE expr_list (*) et if_then_else_statement :: = (*) SI LPAREN RPAREN expr_list ELSE expr_list sous le symbole IF Résolue en faveur du décalage. – pirox22

+0

Remplacé la réponse stupide impraticable avec une explication de l'ambiguïté. Les grammaires ambiguës sont difficiles à analyser à moins que votre ordinateur ne possède une interface de lecture d'esprit, que vous n'avez pas encore. Bonne chance. Je suis afk jusqu'à la semaine prochaine, probablement. – rici