0

Mein aktuelles Projekt (nur eine Spielzeug-Sprache wirklich) ist eine funktionale Skriptsprache. Und ich möchte das Methodenaufrufen zulassen, ohne Klammern für die Gruppierung zu benötigen.Implementieren Methode aufrufen ohne Klammern

sum 1 2 3 

Hier ist der Haken, und ich bin mir nicht sicher, ob das eine gemeinsame Sache ist oder nicht, um ehrlich zu sein. Aber in meiner Sprache kann eine Methode Parameter definieren, die den Bezeichner ausführen.

def (a) plus (b) 
    a + b 
end 

Welche enden würde

1 plus 2 

zu sein, aber was ist, wenn ich für diese Parameter Variablen/Funktionen? Wie würde ich wissen, zum Beispiel, dass „plus“ ist die Methode, ich rufe und nicht „getNum“ in dem folgenden

getnum plus 2 

Und mehr weiter, wie kann ich wissen, dass getNum ein Parameter von plus und nicht umgekehrt? (Ist es einfach durch Überprüfung der Parametersignaturen?) EDIT: Ich habe mich einfach selbst wiederholt. Hoppla.

Und schließlich, sollte ein Lexer etwas Besonderes für diese Art von Sache tun? Wenn ja, wie würde die IT wissen, welche den "Methodenkopf" genannt wird? Oder pumpt der Lexer einfach Sachen wie "Identifiertoken" und "Literaltoken" raus und überlässt es der Laufzeit, herauszufinden, dass es sich um einen Methodenaufruf handelt?

+1

Noch schlimmer, was ist, wenn 'getnum' und' plus' * beide * Funktionen sind? Im Allgemeinen klingt das wie eine mehrdeutige Grammatik. –

+1

Was ich meine, ist, wenn Sie 'def f (x)' und 'def (x) g' haben, was sollte dann' f g' auflösen? –

+0

Ich vermute, geschachtelte Funktionsaufrufe müssten Klammern (oder eine andere Gruppe von Gruppierungszeichen) verwenden, es sei denn, es könnte basierend auf der Tatsache, dass getnum keine Parameter benötigt. – RoyalPotato

Antwort

3

Ihr Problem ist ein Parsing-Problem. Das größere Problem ist jedoch, dass Ihre Sprache nicht syntax-directed ist. Dies bedeutet, dass die Syntax Ihrer Sprache nicht mit ihrer Semantik übereinstimmt. Betrachten wir zum Beispiel das folgende Programm in Ihrer Sprache:

f g 

Dies kann auf zwei Arten analysiert werden, f-g oder g-f angelegt. Die Syntax der Sprache macht es jedoch nicht ersichtlich, welcher der beiden Syntaxbäume generiert wird. Als EJP korrekt erwähnt, "es ist mehr als ein Parsing-Problem, es ist ein semantisches Feedback-Problem".

Also, wie Sie Ihre Sprache syntaxgesteuert machen? Lassen Sie uns von objektorientierten Sprachen sprechen.Zum Beispiel:

1 plus 2 

In einer objektorientierten Sprache wie JavaScript könnte dies geschrieben werden als:

Number.prototype.plus = function (n) { 
 
    return this + n; 
 
}; 
 

 
var sum = (1) .plus (2); 
 

 
alert(sum);

Vergleicht man die Syntax der beiden Sprachen sehen wir, dass die einzige große Differenz ist der Punkt vor der Kennung plus. Das ist alles, was wir brauchen, um Ihre Sprache syntaxgesteuert zu machen. Jetzt können Sie die normalen Funktionen haben:

.sum 1 2 3 

Sie können jedoch auch Syntax-directed Infix Funktionen haben:

1 .plus 2 

Nun werden die folgenden Ausdrücke sind nicht mehr zweideutig:

.f g 
f .g 

Sie benötigen jedoch noch Klammern, um einige Ausdrücke zu disambiguieren:

(.getnum) .plus 2 

Dies ist, weil getnum aufgerufen wird, bevor plus angewendet wird. Es bedeutet plus(getnum(), 2). Auf der anderen Seite getnum .plus 2 würde plus(getnum, 2) bedeuten, was ein Fehler wäre, weil Sie plus nicht auf eine Funktion anwenden können.

Denken Sie an den Punkt als "apply" -Operator Ihrer Sprache. den Punkt verwenden, können auch Sie Funktionen höherer Ordnung haben:

1 .(true .plus-or-minus) 2 

Dies ist die gleiche wie plus-or-minus(true)(1, 2) ist.


Eine andere Alternative ist, die Daten wie in Lisp zu zitieren. Diese Syntax ist viel weniger verrauscht:

  1. Normale Funktion Anwendung, sum 1 2 3.
  2. Infix-Funktion Anwendung, 1 plus 2.
  3. Angegebene Bezeichner, f 'g bedeutet f angewendet auf g und 'f g bedeutet g angewendet auf f.
  4. Angegebene Funktion Anwendung, 'getnum' plus 2 wo 'getnum' implizit zitiert wird.
  5. Funktion der höheren Ordnung Anwendung, 1 (true plus-or-minus) 2.

Hoffe, dass hilft.

+0

Also im Grunde die Periode/Zitate angeben, wen wir anrufen? – RoyalPotato

+0

... und bei Bedarf (wie in verschachtelten Funktionsaufrufen) können wir einfach auf die Verwendung von Klammern zurückgreifen? – RoyalPotato

+0

Auch, tut mir leid für wahrscheinlich ahnungslos. Sprachdesign ist eines der vielen Informatik/Software-Gebiete, die mich interessieren. Obwohl ich noch kein College-Student bin, dachte ich, ich würde damit herumspielen;). Erzähl mir nicht, dass ich unerfahren bin/ungebildet, dies zu tun, weil es meine Zeit ist und ich es verschwenden kann, wie ich es für richtig halte: p. – RoyalPotato

1

Was Sie suchen, ist operator precendence und operator associativity. Im Falle eines Aufrufs ohne Klammerung ist das Leerzeichen der Funktionsoperator.

Mixfix expressions komplizieren Sie dies ein wenig, aber schließlich müssen Sie nur einige Regeln für Ihre Sprache entwickeln und einige mehrdeutige Ausdrücke verbieten. In Ihrem Beispiel würden Sie plus als Infix-Operator deklarieren und allen Infix-Operatoren einen höheren Vorrang geben als Präfixoperatoren.

Dies ist die Aufgabe des Parsers, nicht der Tokenizer oder Lexer.

+0

Also dann würde mein Lexer gehen- ahead und analysiere Identifier/Literal-Tokens an solchen Orten? Ab diesem Moment steht meine derzeitige Implementierung so. Aber dann hörte ich auf und fragte mich, wie zum Teufel ich einen Methodenaufruf auflösen würde (einfach so tun, als ob die Klammern und Kommas Leerzeichen wären) wie diese "Methode (Methode2 (123), irgendeine Variable)". Der einzige Weg, an den ich denken konnte, war die Zeit zu verbringen, um die Gültigkeit der Parameter/Parameter zu überprüfen. Ist das der einzige Weg? Ich habe auch das Gefühl, dass mir eine logische Abkürzung fehlt, die ich verwenden könnte. – RoyalPotato

+2

@RoyalPotato Lexer analysieren nicht. Dir wurde von drei verschiedenen Leuten gesagt, dass dies ein Parsing-Problem ist, kein lexikalisches Analyseproblem. – EJP

+0

@RoyalPotato: Ihr Lexer muss nicht wissen, ob es sich um einen Methodenaufruf handelt oder nicht. – Bergi

Verwandte Themen