2008-12-30 2 views
11

Une expression simple commeComment un compilateur Java analyse-t-il les données typographiques?

(x) - y 

est interprétée différemment selon que x est un nom de type ou non. Si x n'est pas un nom de type, (x) - y soustrait seulement y de x. Mais si x est un nom de type, (x) - y calcule le négatif de y et convertit la valeur résultante en type x.

Dans un C typique ou le compilateur C, la question de savoir si x est un type ou non est responsable parce que l'analyseur communique ces informations au lexer dès qu'il traite une déclaration typedef ou struct. (Je pense que cette violation des niveaux était la plus mauvaise partie de la conception de C.)

Mais en Java, x ne peut être défini que plus tard dans le code source. Comment un compilateur Java désambiguise-t-il une telle expression?

Il est clair qu'un compilateur Java nécessite plusieurs passages, car Java ne nécessite pas de déclaration avant utilisation. Mais cela semble impliquer que le premier passage doit faire un travail très bâclé sur l'analyse syntaxique des expressions, et ensuite dans un passage ultérieur, faire une autre analyse plus précise des expressions. Cela semble inutile.

Y a-t-il un meilleur moyen?

Répondre

8

Je pense que j'ai trouvé la solution qui me satisfait. Grâce à mmyers, j'ai réalisé que j'avais besoin de vérifier la spécification formelle de la syntaxe pour les distributions de type.

L'ambiguïté est provoquée par + et - étant à la fois des opérateurs unaires et binaires. Java résout le problème par cette grammaire:

CastExpression: 
     (PrimitiveType Dimsopt) UnaryExpression 
     (ReferenceType) UnaryExpressionNotPlusMinus 

(voir http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#238146)

Ainsi, '+' et '-' sont explicitement non agréés, immédiatement après la ')' d'un casting à moins que le casting utilise un type primitif - qui sont connus par le compilateur a priori.

+0

J'étais trop paresseux pour réellement rechercher les spécifications (et je ne savais pas où chercher de toute façon). +1 –

+1

Envisagez d'accepter cette réponse. –

2

Je viens de tester dehors, et ce code:

Double y = new Double(0.1); 
System.out.println((Double)-y); 

donne une erreur de compilation:

operator - cannot be applied to Double, java.lang.Double .

La mise entre parenthèses autour de la -y fait compiler correctement. Donc, apparemment Java résout ce problème en ne l'autorisant pas dans la grammaire (si c'est la bonne terminologie, je ne suis pas un expert sur les compilateurs).

+0

Je n'ai pas downvote, mais si au lieu de Double vous aviez utilisé double, le compilateur l'aurait autorisé, puisque _operator -_ peut être appliqué aux doubles. Je crois qu'il a été déprécié pour cette imprécision. –

+0

Depuis Java 1.5, vous pouvez utiliser n'importe quel opérateur arithmétique avec Doubles, Floats, etc. (à cause de l'autoboxing). Comme je l'ai dit, l'ajout de parenthèses l'a fait compiler sans erreurs. –

+0

+1 parce que je ne vois aucune raison pour laquelle cette réponse devrait être votée dans les négatifs – dancavallaro

Questions connexes