2015-06-16 12 views
12

La grammatica in chapter 18 di JLS v7 sembra differire dai costrutti altrove nella documentazione, ma a me sembrano esserci differenze. In particolare nel capitolo 15 le regole sono:Le grammatiche nelle specifiche Java7 sono davvero equivalenti?

RelationalExpression: 
    ShiftExpression 
    RelationalExpression < ShiftExpression 
    RelationalExpression > ShiftExpression 
    RelationalExpression <= ShiftExpression 
    RelationalExpression >= ShiftExpression 
    RelationalExpression instanceof ReferenceType 

che rende foo instanceof Bar un RelationalExpression (e quindi un EqualityExpresson), che a sua volta può essere utilizzato come LHS nella regola EqualityExpression che rende foo instanceof Bar == false un EqualityExpression.

Ma quando guardando la grammatica nel capitolo 18 hanno semplificato un po ':

Expression2: 
    Expression3 [Expression2Rest] 

Expression2Rest: 
    { InfixOp Expression3 } 
    instanceof Type 

che sembra strano, il che significa che siamo in grado di concatenare Expression3 s con gli operatori binari o siamo in grado di controllare il tipo di di uno Expression3. Specificamente ora foo instanceof Bar è un Expression2, ma non vedo che sarebbe valido utilizzare un Expression2 come LHS di un confronto di uguaglianza.

Ho dimenticato qualcosa nella grammatica del capitolo 18 che rende foo instanceof Bar == false un'espressione valida? Si noti che è un'espressione valida secondo le regole nel capitolo 15 e secondo il mio compilatore.

+4

Sembra un bug nelle specifiche per me. Si noti che la [sezione equivalente della specifica Java 8] (https://docs.oracle.com/javase/specs/jls/se8/html/jls-19.html) utilizza la stessa grammatica del capitolo 15. –

+1

Perché è un problema che 'foo instanceof Bar == false' è un'espressione valida? L'ho appena controllato e il compilatore lo accetta. – Clashsoft

+1

@Clashsoft Non è un problema, tranne che secondo la grammatica successiva non lo è: 'foo instanceof Bar' è un 'Expression2' e in quello, ma il LHS di' x == y' dovrebbe essere un' Expression3'. A meno che, naturalmente, non mi sia sfuggito qualcosa - che (quello che ho perso) sarebbe stata una risposta alla mia domanda. – skyking

risposta

2

Questa domanda merita una buona risposta, quindi diamo un'occhiata da vicino.

basa unicamente sulla grammatica in Capitolo 18:

Tutto ciò con un InfixOp (ad esempio ==) sia adatta Expression2Rest o si adatta nulla. E Expression2Rest appartiene solo all'interno di Expression2. Quindi, se foo instanceof Bar == false è legale Java, ciò significa che foo instanceof Bar deve essere un Expression3.

Expression2:
espressione 3 [Expression2Rest]

Expression2Rest:
{InfixOp espressione 3}
instanceofTipo

Ma foo instanceof Bar non è un Expression3. Non c'è PrefixOp e nessun cast, per essere un Expression3 dovrebbe essere un primario. Ma non va bene.

espressione 3:
PrefixOp espressione 3
((Espressione | Type))espressione 3
primaria {Selettore} {} PostfixOp

primaria:
letterale
ParExpression
questo[Argomenti]
SuperSuperSuffix
nuovoCreatore
NonWildcardTypeArguments (ExplicitGenericInvocationSuffix | questo argomenti)
Identifier {. Identifier} [IdentifierSuffix]
BasicType {[]} * .class
void.class

Conclusione: basata esclusivamente sulla grammatica presentato nel capitolo 18, è foo instanceof Bar == false non è un'espressione Java legale. !?!?!

Ovviamente non ha senso. foo instanceof Bar produce un risultato booleano e questo risultato può essere certamente paragonato a false. L'espressione viene compilata e eseguita.

Migliore conclusione: il capitolo 18 non è autorevole, ma il resto del libro è.

Sezione 2.3 Stati che

Un grammatica sintattica per il linguaggio di programmazione Java è dato nei capitoli 4, 6-10, 14, e 15. ... Capitolo 18 dà anche una grammatica sintattica per il linguaggio di programmazione Java, più adatto all'implementazione rispetto all'esposizione.

Con le regole grammaticali presentate in Capitolo 15, foo instanceof Bar == falseè un'espressione Java legale. Ma controlla l'ultima frase prima della sezione 15.20.1: "Il tipo di un'espressione relazionale è sempre booleano."Che è in conflitto direttamente con la RelationalExpression loro regole in 15.20 (In particolare, ciò implica che il LHS di instanceof deve restituire booleano.) Non può forse essere vero

Bestest conclusione:.. Questo libro ha problemi. Se volete sapere se qualcosa è Java legale, è necessario compilare ed eseguirlo, preferibilmente su implementazione di riferimento di Oracle. e anche allora ci potrebbe essere bug. si tratta, dopo tutto, solo il software.

e Penso che se avessero modificato la regola Expression2 solo un po ', il capitolo 18 potrebbe essere corretto. In questo modo:

* Expression2:
espressione 3 [instanceofType]
Espressione2 {InfixOp espressione 3}

Ma chi lo sa, che potrebbe causare altri problemi. In ogni caso, è riparato in Java 8.

Problemi correlati