2010-10-30 4 views
1

J'essaye de faire une règle d'analyseur qui permet de zéro ou plus d'un jeton avant une seconde règle et pour lequel chaque jeton successif - de ceux qui faisaient partie de la fermeture - est, dans l'AST, un enfant du jeton précédent, et la deuxième règle est aussi un enfant du dernier symbole.Faire d'un noeud AST le descendant le plus bas d'une règle récursive

plus facile à expliquer par exemple ...

expression11 : ((NOT | COMPLEMENT)^)* expression12; 

Par exemple, compte tenu de la règle de l'analyseur ci-dessus, si j'ai l'expression !! x (où x est un ID), je veux, dans mon AST , le x est l'enfant du second opérateur bang qui est l'enfant du premier.

souhaitee:

! 
    \ child 
    ! 
     \ child 
     x 

au lieu de mon comportement souhaité, la ligne ci-dessus produit un AST pour lequel le deuxième opérateur bang est un enfant de la première, mais le x est un enfant du premier opérateur bang, un frère de la deuxième. Évidemment pas ce que je veux pour un opérateur unaire.

comportement Rencontrés:

 ! 
child/ \ child 
    x -sib- ! 

Si j'ajoute un troisième opérateur (comme dans « !!! x ») le troisième devient un enfant du second, comme prévu, et x reste un enfant du d'abord, le frère de la seconde.

Je pensais que je pouvais résoudre ce problème en entourant toute la partie de l'opérateur avec parenthèses et en ajoutant un autre caret, comme

expression11 : (((NOT | COMPLEMENT)^)*)^ expression12; 

dans un effort pour forcer expression12 d'être un enfant de la fermeture ensemble des opérateurs, espérant en vain que cela serait interprété comme «l'enfant de toute la fermeture signifie l'enfant du plus descendu», mais ce n'était pas le cas et cela n'a pas du tout changé le comportement. Ma question est "Comment puis-je obtenir l'analyseur pour traiter la règle de telle sorte que le résultat de expression12 devienne l'enfant du nœud" NOT "ou" COMPLEMENT "le plus descendant au lieu du nœud ancêtre le plus élevé? "

J'aurais pensé que ce serait simple, mais je ne peux pas le comprendre à partir des ressources Antlr sur antlr.org ni en plaidant avec Google. Cela doit être fait tout le temps, ou y a-t-il une façon différente de structurer entièrement la règle que je néglige?

Voici les règles suivantes pour l'exhaustivité. Ils ne sont pas encore finis et seront modifiés, mais ils sont complets et fonctionnent pour les tests et tout va bien avec eux - comme prévu, car ils sont simples. 12 est pour les appels de longueur et de méthode de tableau, 13 pour les nouvelles classes et tableaux, 14 pour l'indexation de tableau et 15 pour les terminaux/parenthèses.

expression12 : expression13 (DOT (LENGTH | (ID LPAREN (expression (COMMA expression)*)? RPAREN)))?; 
expression13 : expression14 | (NEW^ ((ID LPAREN RPAREN) | (INTTYPE LSQBRACK expression RSQBRACK))); 
expression14 : expression15 (LSQBRACK expression RSQBRACK)*; 
expression15 : (LPAREN expression RPAREN) | INTLIT | TRUE | FALSE | ID | THIS; 

Merci à tous ceux qui peuvent vous aider; votre temps est très apprécié.

+0

Je dois dire que votre choix de noms de règles est plutôt déroutant. En plus de cela, une bonne question et détaillée!+1 –

+0

@Bart Kiers: Cela fait partie de ma règle de plus grande expression, et chaque règle expressionN est un niveau de priorité différent, avec expression1 étant mon opérateur de priorité la plus basse (OR logique), et expression15 étant le plus élevé. Peut-être pas la façon dont les autres s'y prennent, mais je n'ai pas fait cela depuis longtemps et j'apprends toujours. – Loduwijk

Répondre

2

Vous ne devez pas utiliser l'étoile Kleene si vous ne voulez pas que les opérateurs apparaissent en tant que frères et sœurs. Essayez quelque chose comme (non testé)

expression11 : (NOT | COMPLEMENT)^ expression11 
      | expression12; 
+0

Après avoir utilisé votre réponse, j'ai finalement trouvé la réponse dans la liste de diffusion antlr (http://antlr.1301665.n2.nabble.com/A-little-trouble-with-parsing-unary-operators-td5067826.html# a5067826). Je pensais que ça devait exister quelque part. Quoi qu'il en soit, simple et fonctionne bien; Merci beaucoup. – Loduwijk

Questions connexes