2017-04-13 4 views
0

J'essaye de faire un compilateur et j'essaye maintenant de faire l'analyseur. je reçois un avertissement sur cet état: Etat 89Comment supprimer l'avertissement shift/reduse?

62 expr: '(' expr . ')' 
    66  | expr . '+' expr 
    67  | expr . '-' expr 
    68  | expr . '*' expr 
    69  | expr . '/' expr 
    70  | expr . '%' expr 
    74  | expr . '&' expr 
    75  | expr . '|' expr 
    77 cond: expr . 
    78  | '(' expr . ')' 
    82  | expr . '=' expr 
    83  | expr . "<>" expr 
    84  | expr . '<' expr 
    85  | expr . '>' expr 
    86  | expr . ">=" expr 
    87  | expr . "<=" expr 

    "<>" shift, and go to state 91 
    ">=" shift, and go to state 92 
    "<=" shift, and go to state 93 
    '+' shift, and go to state 94 
    '-' shift, and go to state 95 
    '|' shift, and go to state 96 
    '*' shift, and go to state 97 
    '/' shift, and go to state 98 
    '%' shift, and go to state 99 
    '&' shift, and go to state 100 
    '=' shift, and go to state 101 
    '<' shift, and go to state 102 
    '>' shift, and go to state 103 
    ')' shift, and go to state 119 


$default reduce using rule 77 (cond) 


State 119 

    62 expr: '(' expr ')' . 
    78 cond: '(' expr ')' . 

    "and"  reduce using rule 62 (expr) 
    "and"  [reduce using rule 78 (cond)] 
    "or"  reduce using rule 62 (expr) 
    "or"  [reduce using rule 78 (cond)] 
    ':'  reduce using rule 62 (expr) 
    ':'  [reduce using rule 78 (cond)] 
    ')'  reduce using rule 62 (expr) 
    ')'  [reduce using rule 78 (cond)] 
    $default reduce using rule 62 (expr) 

Ma grammaire pour cette partie est:

expr: 
    T_const | 
    T_char_const | 
    l_value | 
    '(' expr ')' | 
    func_call | 
    '+' expr | 
    '-' expr | 
    expr '+' expr | 
    expr '-' expr | 
    expr '*' expr | 
    expr '/' expr | 
    expr '%' expr | 
    T_true | T_false | 
    '!' expr | 
    expr '&' expr | 
    expr '|' expr 
; 

cond: 
    '(' cond ')' | 
    expr | 
    T_not cond | 
    cond T_and cond | 
    cond T_or cond | 
    expr '=' expr | 
    expr T_not_equal expr | 
    expr '<' expr | 
    expr '>' expr | 
    expr T_greater_equal expr | 
    expr T_less_equal expr 
; 

Quel est le problème ici et comment pourrais-je réparer probablement j'ai déjà fixé? Certains changements/réduire les problèmes, mais en général, je n'ai pas compris ce qu'est ce problème. Merci beaucoup

+0

J'ai oublié ces 2 lignes à la fin de l'état 89: '[réduire en utilisant la règle 77 (cond)] $ par défaut réduire en utilisant la règle 77 (cond) – Nwlis

+1

Utilisez [edit] pour éditer votre message. –

Répondre

1

La grammaire cité par votre question a la production:

cond: '(' cond ')' 

Mais celui cité à partir du fichier de sortie a la production:

cond: '(' expr ')' 

Il y a quelques autres écarts ce qui rend clair que le fichier de sortie n'a pas été généré à partir de la grammaire citée. Cela complique la tâche de répondre à votre question, même si, à la racine, le problème est le même dans les deux cas. J'utilise le fichier de sortie comme référence pour le reste de la réponse.

Puisque vous avez également:

cond: expr 

il y a une ambiguïté dans un contexte dans lequel un cond tire une chaîne parenthésée. (Le conflit montré pour l'Etat 119 montre que très clairement.) Supposons, par exemple, l'analyseur rencontre

not (x) 

x ne peut être réduit à expr (via l_value), mais il y a deux possibilités:

not (expr) => not expr [ from expr: (expr) ] 
      => not cond [ from cond: expr ] 
not (expr) => not cond [ from cond: (eχpr) ] 

Cette ambiguïté existe dans tous les contextes où cond est autorisé. La division des expressions syntaxiquement en expressions booléennes et non booléennes est délicate et généralement inutile. Vous autorisez éventuellement toute expression à être utilisée comme un booléen (cond: expr), et il est fort probable que vous autorisiez (ou que vos utilisateurs s'attendent à ce que vous autorisiez) une valeur booléenne à affecter à une variable. La solution la plus simple et la plus courante consiste donc simplement à dire qu'une valeur est une valeur et une expression est une expression, sans booléens spéciaux.

Si vous ressentez le besoin de séparer syntaxiquement les deux, vous trouverez un exemple dans this recent question.