2008-12-30 15 views
11

Proste wyrażenie jakW jaki sposób kompilator Java analizuje typecasts?

(x) - y 

jest interpretowane różnie w zależności od tego, czy x jest nazwą typu, czy nie. Jeśli x nie jest nazwą typu, (x) - y odejmuje tylko y od x. Ale jeśli x jest nazwą typu, (x) - y oblicza wartość ujemną z y i rzuca otrzymaną wartość na typ x.

W typowym kompilatorze C lub C++ pytanie, czy x jest typem, czy też nie, jest odpowiedzialne, ponieważ parser przekazuje takie informacje do leksera, gdy tylko przetworzy deklarację typedef lub struct. (Myślę, że takie wymagane naruszenie poziomów było najprzykrzejszą częścią projektu C.)

Ale w Javie x może nie zostać zdefiniowany później w kodzie źródłowym. W jaki sposób kompilator Java rozróżnia takie wyrażenie?

Jest oczywiste, że kompilator Java wymaga wielu przejść, ponieważ Java nie wymaga deklaracji przed użyciem. Ale to wydaje się sugerować, że pierwsze przejście musi wykonać bardzo niechlujne zadanie podczas analizowania wyrażeń, a następnie w późniejszym przejściu wykonać kolejną, dokładniejszą analizę składni wyrażeń. To wydaje się marnotrawstwem.

Czy istnieje lepszy sposób?

Odpowiedz

8

Myślę, że znalazłem rozwiązanie, które mnie satysfakcjonuje. Dzięki mmyerom zdałem sobie sprawę, że muszę sprawdzić formalną specyfikację składni dla rzutów typowych.

Niejednoznaczność jest spowodowana przez + i - zarówno jako operatorów jednoargumentowych, jak i binarnych. Java rozwiązuje ten problem przez ten gramatyki:

CastExpression: 
     (PrimitiveType Dimsopt) UnaryExpression 
     (ReferenceType) UnaryExpressionNotPlusMinus 

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

Więc '+' i '-' są wyraźnie zabronione natychmiast po ')' w gipsie chyba obsada używa prymitywny typ - które są znane przez kompilator a priori.

+0

Byłem zbyt leniwy, aby sprawdzić specyfikację (i nie wiedziałem, gdzie i tak spojrzeć). +1 –

+1

Rozważ zaakceptowanie tej odpowiedzi. –

2

Właśnie testowałem go na zewnątrz, a ten kod:

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

daje błąd kompilacji:

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

Umieszczenie nawiasów wokół -y czyni go skompilować w porządku. Tak więc najwyraźniej Java rozwiązuje ten problem, po prostu nie dopuszczając go do gramatyki (jeśli jest to właściwa terminologia, nie jestem ekspertem od kompilatorów).

+0

Nie spadłem, ale zamiast Podwójnego użyłeś podwójnie, na co pozwoliłby kompilator, ponieważ _operator -_ może być zastosowany do podwójnych. Uważam, że zostało ono odrzucone z powodu tego nieprzyjęcia. –

+0

Od wersji Java 1.5 można używać dowolnego operatora arytmetycznego z podwójnymi, pływającymi itp. (Z powodu autoboxingu). Jak już powiedziałem, dodanie nawiasów sprawiło, że kompilacja przebiegła bez błędów. –

+0

+1, ponieważ nie widzę żadnego powodu, dla którego ta odpowiedź powinna zostać poddana pod głosowanie. – dancavallaro

Powiązane problemy