2015-11-10 6 views
9

Ich frage mich, warum dieser Code nicht funktioniert kompilieren:Java Ausdruck Kompilierungsfehler

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

Während dieser Code tut:

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

ich denke, die Priorität für Pre und dann dekrementiert dann schreiben Sie Die Subtraktion sollte angewendet werden.

+1

Es gibt einen Unterschied zwischen x --- x und x-- - x. Wie soll der Compiler wissen, ob Sie x - --x oder x-- - x meinen? – Stultuske

Antwort

12

x-----x wird von links nach rechts ausgewertet:

((x--)--)-x 

Die ersten x-- kehrt -3, und Sie können den -- Operator auf eine nicht anwenden Wert (-3), nur für eine Variable (wie x).

Deshalb erhalten Sie Invalid argument to operation ++/-- Fehler.

Wenn Sie fügen Sie ein Leerzeichen - x--- --x

Es ausgewertet als (x--)- (--x)

   -3 - -5 = 2 
+0

Gibt es einen Grund, warum es entschied, 'x -----' als '(x -) -) -' und nicht '(x -) -) - '? – Keale

+0

Können wir das zur Antwort hinzufügen? : 3 – Keale

+3

@Keale. Nein, weil es nichts mit der Priorität des Operators zu tun hat. Die Operator-Priorität tritt nur ein, wenn wir bereits wissen, welche Operatoren in welcher Position in der Eingabe vorkommen, und das ist mehrdeutig. – Hoopje

0

Das erste Beispiel ist wie eine Subtraktion

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

Die zweite wie minimieren, ist x -> es ist das gleiche wie

x++ => x=x+1 

Was haben Sie ist es so etwas wie

x-- => x=x-1 

und der zweite Teil:

nicht subtrahieren ersten -1 von der variablen

+2

Dies beantwortet die Frage nicht. –

+0

@UmaKanth Sie haben Recht, aber ich dachte, es ist klar nach dieser Erklärung –

4

x-----x als (x--) -- -x analysiert wird, und hier -- wird auf einen Ausdruck angewendet, die keine Variable ist. Das ist nicht erlaubt.

Der Grund dafür ist der folgende. Die erste Stufe beim Parsen ist das Token des Eingabestroms: Der Eingabestrom, der aus Zeichen besteht, wird in Chunks gruppiert, die Token genannt werden. Token sind Zeichenketten, die für Java bedeutsam sind, z. Schlüsselwörter, Operatoren oder Identifikatoren.

Tokenisierung ist gierig: Solange ein anderes Zeichen zum Token hinzugefügt werden kann, so dass es noch ein gültiges Token ist, wird das Zeichen hinzugefügt. So wird beispielsweise forLoop als eine einzelne Kennung betrachtet und nicht als das Schlüsselwort for, gefolgt von der Kennung Loop. Die Zeichenfolgen - und -- sind beide gültige Token in Java. Wenn der Tokenizer auf --- trifft, liest er das erste Zeichen. Obwohl es weiß, dass - ein gültiges Token ist, schaut es zuerst auf das nächste Zeichen und entscheidet, dass -- auch ein gültiges Token ist, so dass das erste zurückgegebene Token -- ist, nicht .

4

Diese direkt von der Java Language Specification abgedeckt ist, §3.2. Lexical Translations

Die längste mögliche Übersetzung wird bei jedem Schritt verwendet wird, auch wenn das Ergebnis nicht macht schließlich ein richtiges Programm, während eines andere lexikalische Übersetzung würde. Es gibt eine Ausnahme: Wenn eine lexikalische Übersetzung in einem Typkontext auftritt (§4.11) und der Eingabestrom zwei oder mehr aufeinanderfolgende > Zeichen hat, gefolgt von einem nicht > Zeichen, dann muss jedes > Zeichen in das Token für das numerische übersetzt werden Vergleichsoperator >.

die eingegebenen Zeichen a--b Token versehen werden (§3.5) als a, --, b, die nicht Teil eines grammatisch richtigen Programms ist, auch wenn die tokenization a, -, -, b richtigen Teil eines grammatisch sein könnte Programm.

So, da dies nicht eine Art Kontext und nicht etwa > Zeichen entweder die Regel des längsten Token gilt. So wird x-----x als x, --, --, -, x ähnlich wie das zitierte Beispiel tokenisiert.