2017-11-14 3 views
4

für ein Array x sind folgende grammatische Ausdrücke:Warum ist '[f x [1]]' unggrammatisch während '[1 + x [1]]' ist?

  • puts x[1]
  • [puts(x[1])]
  • [1 + x[1]]

aber diese:

  • [puts x[1]]

irgendwie analysieren:

syntax error, unexpected tIDENTIFIER, expecting keyword_do or '{' or '(' 

Warum kann der Parser Figur aus dieser Syntax?

+0

Was ist 'x'? Bitte hinzufügen. –

+0

Sie können die [Ruby-Grammatik] (https://stackoverflow.com/a/16629318/125816) einsehen, herausfinden und uns mitteilen! –

+3

@SagarPandya: Es ist völlig irrelevant, denn diese Frage betrifft Syntax, nicht Semantik. –

Antwort

6

In Ruby können Sie oft, aber nicht immer die Klammern um Methodenaufrufe weglassen. Sie haben einen Fall gefunden, in dem Sie nicht können. Manchmal ist es für Ruby zu vieldeutig, um genau zu verstehen, was Sie wollen, und Sie müssen genauer sein.

Die gültige Schreibweise ist hier:

[puts(x[1])] 

Obwohl als puts immer nil gibt, dies zu tun, wirklich eine seltsame Sache.

+0

Richtig, ich benutze 'puts' nur als Platzhalter. Es ist nur komisch, weil zum Beispiel CoffeeScript keine Probleme mit dieser Syntax hat. Ich frage mich, warum Ruby es mehrdeutig betrachtet. – chickenburgers

+0

Es ist Sache des Ruby-Parsers, dies zu verstehen. Während der [Lexer] (https://en.wikipedia.org/wiki/Lexical_analysis) die von Ihnen verwendeten Komponenten verstehen kann, ist der [Parser] (https://en.wikipedia.org/wiki/Parsing#Computer_languages) kann mit der Mehrdeutigkeit nicht umgehen. Es erwartet nicht, dass diese Tokens in dieser Reihenfolge sind. Vielleicht könntest du das Ruby-Kernteam darum bitten, das zu beheben, aber so wie es aussieht, ist es eine Konsequenz davon, wie Rubys Parser implementiert ist. – tadman

+0

Dies beantwortet die Frage überhaupt nicht: Warum kann Ruby 'puts x [1]]' nicht parsen? Für mich scheint es unzweideutig, und ich bin sehr überrascht von dem Fehler. – Max

8

Ich glaube, dass dieses Parsing-Verhalten absichtlich ist - kein Fehler. Es ist ein unglücklicher Nebeneffekt, dass Ruby weggelassene Klammern erlaubt. Dieser Code ist natürlich in Ordnung:

def f x, y=0 
    x + y 
end 

f 2 # 2 
f 2, 3 # 5 

Aber was ist das Ergebnis dieses Codes?

[f 2, 3] 

[2,3] oder [5]? Damit der syntaktische Analysator diesen Code handhaben kann, müsste er die Komplexität der Methode verstehen. Aber weil Ruby dynamisch ist, kann nicht bestimmt werden, bis der Methodenaufruf tatsächlich ausgeführt wird.

Anstatt den mehrdeutigen Fall zuzulassen, der sicherlich zu überraschenden Situationen während der Laufzeit führen würde, entschieden sich die Entwickler für den (immer noch überraschenden, aber leicht zu behebenden) Fehler beim Parsen.

Hinweis: Sie kann immer noch argumentieren, dass in dem Fall, in dem es das letzte Element gibt es keine Zweideutigkeit ist

[3, f 2] 
# should be [3, 2] 

aber ich kann meine Haare vorstellen, herausziehen, wenn Rubys ich lassen, dass schreiben und dann Klapse Ich habe einen Syntaxfehler, wenn ich am Ende des Arrays ein weiteres Element hinzufüge. Ich kann die Entscheidung verstehen, nicht weggelassene Klammern innerhalb von Arrays zuzulassen.

+2

Es ist erwähnenswert (vielleicht), dass es Fälle gibt, in denen Ruby Sie mit einem Syntaxfehler schlägt, wenn Sie einem Array ein anderes Element hinzufügen, und es ist tatsächlich frustrierend: 'a = [2, foo:: bar] # fine' while 'a = [2, foo:: bar, 3] # Syntaxfehler' –

+1

Sie können auch' f 2, f 3, 4' haben, was besonders verwirrend ist. – tadman

+0

@SimpleLime ewww. In diesem Beispiel würde ich sagen, Ruby sollte auch keine geschweiften Klammern in einem Array zulassen – Max