Pourquoi dois-je réduire un changement / conflit sur la « ) » et non « ( »?
-
11-09-2019 - |
Question
Je syntaxe comme
%(var)
et
%var
(Var)
Mes règles sont quelque chose comme
optExpr:
| '%''('CommaLoop')'
| '%' CommaLoop
CommaLoop:
val | CommaLoop',' val
Expr:
MoreRules
| '(' val ')'
Le problème est il ne semble pas être en mesure de dire si) appartient à %(CommaLoop)
ou % (val)
mais il se plaint de la) au lieu de (. Que diable? On doit bien se plaindre sur (
et comment dois-je corriger l'erreur? Je pense fais %(
un jeton est une bonne solution, mais je veux être sûr de savoir pourquoi $(
nest pas une erreur avant de le faire.
La solution
Ceci est dû à la façon dont fonctionne parsing LR. LR est effectivement l'analyse syntaxique ascendante, le regroupement des jetons ensemble selon l'ERS de vos règles de grammaire, et les remplacer par le LHS. Lorsque l'analyseur « déplace », il met un jeton sur la pile, mais ne correspond pas à une règle encore. , Il suit plutôt que partiellement adapté règles par l'état actuel. Quand il arrive à un état qui correspond à la fin de la règle, il peut réduire, éclater les symboles de l'ERS de la pile et de repousser un symbole indiquant la LHS. Donc, s'il y a des conflits, ils ne se présentent pas jusqu'à ce que l'analyseur arrive à la fin d'une règle et ne peut pas décider de réduire (ou quoi réduire).
Dans votre exemple, après avoir vu % ( val , qui est ce qui sera sur la pile ( dessus est à droite ici) Lorsque l'est préanalyse ) , il ne peut pas décider si elle devrait apparaître le val et réduire par la règle CommaLoop. val , ou si elle doit déplacer le ) il peut alors pop 3 choses et réduire 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 pas à quoi que ce soit et le bison / yacc se plaindra non-terminaux inutilisés
Autres conseils
En ce moment, votre explication et votre grammaire ne semblent pas correspondre. Dans votre explication, vous montrez tous les trois phrases comme ayant « var », mais votre grammaire montre ceux commençant par « % » en permettant une liste séparée par des virgules, alors que l'un sans permet qu'un seul « val ».
Pour l'instant, je suppose tous 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 avez probablement pas l'intention que commencer. J'ai assez étoffé ceci pour l'exécuter par byacc; il ne produit pas d'avertissements ou d'erreurs.