Question

Je travaille sur un analyseur et je suis vraiment frustré.Dans le langage, on peut avoir une expression comme :

new int[3][][]

ou

new int[3]

La plupart sont analysés correctement, à l'exception des tableaux vides à la fin.Dans mon analyseur j'ai :

Expression : int
             char
             null
             (...many others...)
             new NewExpression

et puis une NewExpression est :

NewExpression : NonArrayType '[' Expression ']' EmptyArrays
              | NonArrayType '[' Expression ']' 

et puis EmptyArrays est une ou plusieurs accolades vides - si EmptyArrays dérive la chaîne vide, il ajoute 20 conflits de décalage/réduction :

EmptyArrays : EmptyArrays EmptyArray
            | EmptyArray
EmptyArray  : '[' ']'

Cependant, quand je regarde dans .info fichier pour l'analyseur, j'obtiens ceci :

State 214¬
¬
▸   NewExpression -> NonArrayType lbrace Expression rbrace . EmptyArrays    (rule 80)¬
▸   NewExpression -> NonArrayType lbrace Expression rbrace .    (rule 81)¬
¬
▸   dot            reduce using rule 81¬
▸   ';'            reduce using rule 81¬
▸   ','            reduce using rule 81¬
▸   '+'            reduce using rule 81¬
▸   '-'            reduce using rule 81¬
▸   '*'            reduce using rule 81¬
▸   '/'            reduce using rule 81¬
▸   '<'            reduce using rule 81¬
▸   '>'            reduce using rule 81¬
▸   '<='           reduce using rule 81¬
▸   '>='           reduce using rule 81¬
▸   '=='           reduce using rule 81¬
▸   '!='           reduce using rule 81¬
▸   ')'            reduce using rule 81¬
▸   '['            reduce using rule 81    --I expect this should shift
▸   ']'            reduce using rule 81¬
▸   '?'            reduce using rule 81¬
▸   ':'            reduce using rule 81¬
▸   '&&'           reduce using rule 81¬
▸   '||'           reduce using rule 81

Je m'attends cependant à ce que si nous sommes dans l'état 214 et que nous voyons une accolade gauche, nous devrions la déplacer sur la pile et continuer à analyser EmptyArrays.

Je ne suis pas exactement sûr de ce qui se passe, car lorsque je retire tout l'excédent du bagage (par exemple) en commençant l'analyse avec NewExpression, les crochets supplémentaires sont analysés correctement.Il n'est pas possible qu'une expression, une instruction ou tout autre non-terminal de la grammaire commence par une accolade gauche.Surtout parce que j'ai une règle similaire pour les instructions if/else, qui génère un conflit shift/reduce, mais choisit de décaler si le jeton suivant est un else (ce problème est bien documenté).

Pouvez-vous m'aider à comprendre ce qui ne va pas ?J'apprécie vraiment votre aide, je m'attaque vraiment aux moulins à vent pour essayer de comprendre le problème.

Était-ce utile?

La solution

Vous avez probablement une priorité définie pour '[' et/ou ']' avec quelque chose comme %left '[' ce qui provoque ce comportement.Supprimez cette déclaration de priorité, et cela révélera le conflit de décalage/réduction que vous avez ici.Quant à savoir pourquoi il s'agit d'un conflit décalage/réduction, vous avez probablement aussi une règle :

Expression: Expression '[' Expression ']'

pour un accès au tableau.Le problème étant que depuis un NewExpression est un Expression il peut être suivi d'un index comme celui-ci, et lorsque l'on regarde l'anticipation de '[', il ne peut pas dire s'il s'agit du début d'une expression d'index ou du début d'une expression d'index. EmptyArray -- cela nécessiterait une anticipation de 2 jetons.

Une chose que vous pourriez essayer pour ce cas spécifique serait de demander à votre lexer d'effectuer l'anticipation supplémentaire nécessaire ici et de reconnaître [] comme un seul jeton.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top