2009-12-02 9 views
2

Je syntaxe commePourquoi dois-je un changement réduire/conflit sur la ')' et non '('?

%(var) 

et

%var 

et (var)

Mes règles sont quelque chose comme

optExpr: 
    | '%''('CommaLoop')' 
    | '%' CommaLoop 

CommaLoop: 
    val | CommaLoop',' val 

Expr: 
    MoreRules 
    | '(' val ')' 

Le pr oblem est il ne semble pas pouvoir dire si) appartient à %(CommaLoop) ou % (val) mais il se plaint sur le) au lieu du (. Que diable? Ne devrait-il pas se plaindre au (? et comment devrais-je corriger l'erreur? Je pense que faire un jeton %( est une bonne solution, mais je veux être sûr pourquoi $( n'est pas une erreur avant de le faire.

+0

La solution était de faire% (un jeton, plus tard j'ai dû enlever '%' CommaLoop –

Répondre

3

Ceci est dû à la façon dont l'analyse syntaxique LR fonctionne. L'analyse LR est en fait ascendante, regroupant des jetons selon l'ERS de vos règles grammaticales et les remplaçant par le LHS. Lorsque l'analyseur 'décale', il place un jeton sur la pile, mais ne correspond pas encore à une règle. Au lieu de cela, il suit les règles partiellement appariées via l'état actuel. Quand il arrive à un état qui correspond à la fin de la règle, il peut réduire, faire sauter les symboles du RHS de la pile et repousser un seul symbole indiquant le LHS. Donc, s'il y a des conflits, ils n'apparaissent pas jusqu'à ce que l'analyseur arrive à la fin d'une règle et ne puisse pas décider s'il doit réduire (ou quoi réduire).

Dans votre exemple, après avoir vu %(val, c'est-ce qui sera sur la pile (en haut est à droite ici). Lorsque la préanalyse est ), il peut ne décidez pas si elle doit sauter le val et réduire via la règle CommaLoop: val, ou si elle doit décaler le ) afin qu'il puisse alors pop 3 choses et réduire avec la règle Expr: '(' val ') '

Je suppose ici que vous avez des règles supplémentaires telles que CommaLoop: Expr, sinon votre grammaire ne correspond à rien et bison/yacc se plaindra des non-terminaux inutilisés.

0

À l'heure actuelle, votre explication et votre grammaire ne semblent pas correspondre. Dans votre explication, vous montrez les trois expressions comme ayant 'var', mais votre grammaire montre celles commençant par '%' comme autorisant une liste séparée par des virgules, tandis que celle qui ne l'est pas n'autorise qu'un seul 'val'.

Pour l'instant, je suppose que les trois devraient permettre une liste séparée par des virgules. Dans ce cas, je facteur la grammaire plus comme ceci:

optExpr: '%' aList 

aList: CommaLoop 
    | parenList 

parenList: '(' CommaLoop ')' 

CommaLoop: 
    | val 
    | CommaLoop ',' val 

Expr: MoreRules 
    | parenList 

J'ai changé optExpr et Expr donc ne peut correspondre à une séquence vide - je suppose que vous est probablement n'a pas l'intention que de commencer par . Je l'ai étoffé assez pour le faire passer à travers; il ne produit aucun avertissement ou erreur.