2015-11-10 3 views
9

mi chiedo il motivo per cui questo codice non viene compilato:Java errore di compilazione espressione

int x=-3; 
    System.out.println(x-----x); 

considerando che tale codice fa:

int x=-3; 
    System.out.println(x--- --x); 

Credo che la priorità è per la pre e poi posterò decrementi poi la sottrazione dovrebbe essere applicata.

+1

C'è una differenza tra x --- xe x-- - x. In che modo il compilatore dovrebbe sapere se intendete x - --x o x-- - x? – Stultuske

risposta

12

x-----x viene valutata da sinistra a destra:

((x--)--)-x 

I primi x-- rendimenti -3, e non è possibile applicare l'operatore su un -- valore (-3), solo su una variabile (come x).

Ecco perché ottieni l'errore Invalid argument to operation ++/--.

Quando si aggiunge uno spazio - x--- --x

E 'valutata come (x--)- (--x)

   -3 - -5 = 2 
+0

C'è una ragione per cui ha scelto di valutare 'x -----' come '(x -) -) -' e non '(x -) -) - '? – Keale

+0

Possiamo aggiungere quello alla risposta? : 3 – Keale

+3

@Keale. No, perché non ha nulla a che fare con la precedenza degli operatori. La precedenza dell'operatore viene attivata solo quando sappiamo già quali operatori si verificano in quale posizione nell'input e qui è ambiguo. – Hoopje

0

Il primo esempio è come una sottrazione

int x=-3; 
System.out.println(x-----x); 

La seconda è come minimizzare x -> è la stessa come

x++ => x=x+1 

Quello che hai fatto c'è qualcosa di simile

x-- => x=x-1 

e la seconda parte:

--x 

si mette prima a sottrarre -1 dalla variabile

+2

Questo non risponde alla domanda. –

+0

@UmaKanth hai ragione, ma ho pensato che fosse chiaro dopo questa spiegazione –

4

x-----x viene scandito come (x--) -- -x, e qui -- viene applicata a un'espressione che non è una variabile. Questo non è permesso.

Il motivo è il seguente. La prima fase di analisi consiste nel tokenizzare il flusso di input: il flusso di input, che consiste di caratteri, è raggruppato in blocchi chiamati token. I token sono stringhe che sono significative per Java, ad es. parole chiave, operatori o identificatori.

Tokenizing è greedy: finché un altro carattere può essere aggiunto al token in modo che sia ancora un token valido, il carattere viene aggiunto. Pertanto, ad esempio forLoop viene considerato come un identificatore singolo e non come la parola chiave for seguita dall'identificatore Loop.

Le stringhe - e -- sono entrambi token validi in Java. Quindi, quando il tokenizer incontra ---, legge il primo carattere. Sebbene sappia che - è un token valido, prima guarda il prossimo carattere e decide che -- è anche un token valido, quindi il primo token restituito sarà --, non -.

4

Questa è coperto direttamente dal linguaggio Java Specification, §3.2. Lexical Translations

Il più lungo possibile traduzione è utilizzato ad ogni passo, anche se il risultato non in ultima analisi, fare un programma corretto, mentre un altro traduzione lessicale sarebbe. Vi è un'eccezione: se la traduzione lessicale si verifica in un contesto di tipo (§4.11) e il flusso di input ha due o più caratteri consecutivi > seguiti da un carattere non >, ogni carattere > deve essere tradotto nel token per il numero operatore di confronto >.

I caratteri immessi a--b sono token (§3.5) come a, --, b, che non è parte di qualsiasi programma grammaticalmente corretto, anche se la tokenizzazione a, -, -, b potrebbe essere parte di un grammaticalmente corretto programma.

Quindi dal momento che questo non è un contesto di tipo e non circa > caratteri sia, la regola del token più lunga si applica. Quindi x-----x viene tokenizzato come x, --, --, -, x come nell'esempio citato.