Die meisten Programmiersprachen scheinen so konzipiert zu sein, dass man keine Kennung deklarieren kann, die mit einer Zahl beginnt. Ich war nur neugierig, den Grund zu kennen. Ich habe bereits im Internet gesucht, konnte jedoch keine zufriedenstellende Erklärung finden.
32
Antworten:
In C / C ++ wird eine Zahl gefolgt von einem Buchstaben als numerische Konstante betrachtet, und die folgende Zeichenfolge kennzeichnet den Typ der Konstante. Also zum Beispiel (das sind VC ++, nicht sicher, wie Standard sie sind):
So a) es einfacher für den Lexer ist wie Daniel sagte aber auch b) es eine explizite Unterscheidung macht da 0y könnte eine Variable sein , aber 0HE würde nie sein. Außerdem wurden andere Qualifikationsmerkmale wie "i64" viel später als "l" oder "u" hinzugefügt, und sie möchten die Option offen halten, bei Bedarf weitere hinzuzufügen.
quelle
Die Bequemlichkeit der Leute, die den Lexer implementieren. (Nein, im Ernst, das ist es. Verschiedene Sprachen haben andere Gründe, aber letztendlich kommt es darauf an.)
quelle
0flu
ein Literal und0glu
eine lokale Kennung wäre.int 0u = 5; unsigned int x = 0u;
Wenn Sie jedoch die Interpretation dieses Codes definieren (wahrscheinlich entweder x == 0 oder x == 5), werden die Menschen verwirrt sein wegen der Mehrdeutigkeit. Selbst wenn es trivial wäre, den Compiler auf diese Weise zu implementieren, würde ein guter Designer dies wahrscheinlich nicht tun.Betrachten Sie die folgenden 2 Fälle:
Fall 1
Nehmen wir an, dass ein Bezeichner mit einer Zahl beginnen könnte.
Eine Aussage wie die folgende wäre also gültig (da ein Bezeichner 1 oder mehr Zeichen haben kann):
Wenn ich versuche, die obige Variable in einem Programm zu verwenden, führt dies zu einer Mehrdeutigkeit des Compilers:
a=3
Was ist die Rolle von 3 in der Anweisung (ist es eine Variable mit dem Wert 5 oder ist es die Zahl 3)?Fall 2
Im Gegensatz zu dem obigen Beispiel nehmen wir an, dass eine Sprache tatsächlich Bezeichner zulässt, die mit einer Zahl beginnen, und weiterhin die Verwendung von Ziffern als Bezeichner nicht zulässt. Dies kann die folgenden Probleme verursachen:
Die Sprachregeln bezüglich der Variablen, die besagen, dass eine Variable aus einem oder mehreren Zeichen bestehen kann, müssen zu einer komplexen Regel umdefiniert werden: Eine Variable kann ein oder mehrere Zeichen haben und muss eindeutig sein, wenn sie nicht mit einer Zahl beginnt Es darf keine einzelne Zeichenlänge haben, wenn mit einer Zahl (usw.) begonnen wird.
Der Compiler muss nach Fehlern suchen und diese melden, wenn alle Ziffern (z. B. 333) und gültigen Buchstabensuffixe (z. B. 34L) als Variablennamen verwendet werden. In lose geschriebenen Sprachen wie Python und JS, in denen Sie Variablen im laufenden Betrieb verwenden können, ohne sie zu deklarieren, kann es sogar unmöglich sein, nach Sonderfällen zu suchen, die alle Ziffern betreffen
if (33==5)
. Der Compiler kann dies jedoch nicht erkennen und den Fehler melden.Durch diese Einschränkung wird der Programmierer daran gehindert, Zahlen als Bezeichnernamen zu verwenden.
quelle
int char = float
wäre?int
um ein Schlüsselwort und nicht um eine Kennung handelt? Nun,int
hat eine höhere Priorität, genau wie es nummerische Lexeme getan hätten.int 3,a; 3=5; a=3;
in der Anweisung a = 3 3 als Bezeichner oder als Zahl interpretiert? Dies führt zu Mehrdeutigkeiten. Hoffe es ist klar.Dies hat größtenteils nichts damit zu tun, dass es den Compilern leichter fällt und die Effizienz beim Parsen steigt, sondern vielmehr damit, dass eine Syntax entwickelt wird, die klar lesbaren und eindeutigen Code fördert.
Die Sprachdesigner fanden es schön, numerische Literale wie die Nummer 1 als einfache 1 schreiben zu können .
Es wäre durchaus möglich, eine Sprachsyntax zu entwerfen, in der numerische Literale in Anführungszeichen gesetzt werden, z. B. Tildas, sodass das numerische Literal für Nummer eins als ~ 1 ~ codiert und alles, was nicht in Anführungszeichen steht, als Variablenname behandelt wird .
Sie könnten also Anweisungen wie die folgenden codieren:
Aber auch:
Unabhängig davon, welche Syntax Sie für mehrdeutigen und schwer zu verfolgenden Code wählen, ist dies unvermeidlich.
Die C-Sprache und die meisten der von C abgeleiteten "geschweiften Klammern" hielten es auch für eine gute Idee, Programmierern die direkte Codierung von Oktal- und Hexadezimal-Literalen zu ermöglichen und den Typ des Literal anzugeben, wenn dies wichtig ist. So
Selbst wenn Sie also zulassen, dass Variablennamen mit einer Zahl beginnen, gefolgt von einer Kombination aus Zahlen und Buchstaben, die mindestens einen Buchstaben enthält, würden Sie dem Programmierer das Problem stellen, zu entscheiden, ob eine gegebene Gruppe einen Variablennamen oder ein numerisches Literal bildet
Eine solche Mehrdeutigkeit würde niemandem helfen, ein Programm zu schreiben oder zu lesen.
Ein nahe verwandtes Beispiel aus der Praxis finden Sie in PL / 1, dessen Designer die Verwendung von Schlüsselwörtern als Variablennamen für eine gute Idee hielten.
Ist gültiger Code, der kompiliert und ausgeführt wird.
quelle
Fortran hatte einen großen Einfluss darauf, wie spätere Sprachen entworfen wurden. Frühzeitig (einige dieser Probleme wurden inzwischen behoben) hatte Fortran fast keine Regeln, die den Namen eines Bezeichners einschränkten. Dies machte es für Compiler und Programmierer äußerst schwierig, die Sprache zu analysieren. Hier ist ein klassisches Beispiel:
Hier habe ich die "Sprachschlüsselwörter" mit K und den Bezeichnern (Variablennamen) I markiert. Da es keinen Unterschied in der Schreibweise gibt, können Sie wahrscheinlich verstehen, wie verwirrend dies sein könnte. Dies ist natürlich ein extremes Beispiel, und es ist unwahrscheinlich, dass jemals jemand absichtlich einen solchen Code geschrieben hat. Manchmal "recycelten" die Leute jedoch Sprachschlüsselwörter als Bezeichnernamen - und in vielen Fällen könnte ein einfacher Tippfehler dazu führen, dass der Code, der in der angegebenen Sprachspezifikation angegeben ist, auf diese Weise analysiert wird, obwohl dies überhaupt nicht beabsichtigt war. Vergleichen Sie dies für ein anderes bekanntes Beispiel:
dazu:
Die erste ist eine do-Schleife, die einen Codeblock zehnmal durchläuft. Bei der zweiten wurde das Komma jedoch in einen Dezimalpunkt geändert, sodass der Wert
1.10
einer benannten Variablen zugewiesen wirddo 10 i
.Dies bedeutete auch, dass das Schreiben eines Fortran-Parsers relativ schwierig war - Sie konnten nicht sicher sein, dass der
do
Zeilenanfang wirklich ein Schlüsselwort war, bis Sie das Zeilenende erreicht hatten, und überprüften, ob alle anderen Elemente von ado
Schleife waren vorhanden. Der Parser musste im Allgemeinen bereit sein, einen "Backtrack" durchzuführen und die Zeile von Anfang an neu zu analysieren, um zu der "richtigen" (aber häufig unbeabsichtigten) Antwort auf das zu gelangen, was wirklich vorhanden war.Nach ein paar Jahren gingen die Sprachdesigner (die meisten sowieso) in die entgegengesetzte Richtung - sie schränkten fast alles an der Sprache so weit wie möglich ein, ohne dass sich die Benutzer zu sehr beschwerten .
Frühe BASIC-Versionen haben beispielsweise im Grunde gesagt, dass Sie nicht einmal ein Schlüsselwort als Teil eines Bezeichners verwenden können. Sie werden zum Beispiel
fora=1
analysiert alsfor a = 1
(dh als Beginn einerfor
Schleife, nicht als Zuweisung). Das hat anscheinend genug Beschwerden hervorgerufen, dass es nicht sehr lange dauerte. Die Regel, eine Kennung mit einer Ziffer zu beginnen, hat anscheinend nicht viele Beschwerden hervorgerufen, weshalb sie weiterhin verwendet wird (zumindest in den meisten Sprachen).quelle
Wahrscheinlich ist diese Konvention aus sehr frühen Entscheidungen über das Design historischer Sprachen hervorgegangen, da auf frühen Maschinen der gesamte Compiler einschließlich der lexikalischen Analyse in wenigen Kilowatt ausgeführt werden musste, weniger Speicher als selbst der Prozessor-Datencache der ersten Ebene auf aktuellen Mobilgeräten. Daher waren die zulässigen Variablennamen sehr begrenzt und mussten in sehr wenigen Op-Codes leicht von numerischen Konstanten zu unterscheiden sein.
So wurde die Konvention zu dem, was Generationen von Programmierern gewohnt sind.
quelle
Es ist keine logisch vorgeschriebene Regel für die Programmiersprache, sondern nur die Konvention, die von vielen Sprachdesignern verwendet wird.
Ich kann eine radikal andere Sprache entwerfen, die alle Zeichen für Bezeichner zulässt. Für alle Codezeilen beschreiben die ersten 20 Zeichen den Anweisungstyp, die nächsten 20 Zeichen definieren das erste Symbol für die Anweisung und die nächsten 20 Zeichen sind Operanden für die Anweisung. Diese Sprache wird auf einem Stack-Prozessor ausgeführt.
Dieser Code könnte in C wie folgt übersetzt werden:
Das ist alles. Es ist bedeutungslos und die No-Number-In-Identifiers-Regel ist auch aus logischen Gründen sinnlos.
quelle
Neben "Convenience for the Lexer" ist meines Erachtens auch "Convenience for the Reader" zu berücksichtigen.
Wenn Sie Code lesen, müssen Sie schnell und wiederholt feststellen, welche Wörter Bezeichner und welche Zahlen sind. Die Suche nach einer Ziffer am Anfang erleichtert die visuelle Mustererkennung. Es wäre mühsam, wenn wir alle Charaktere sorgfältig prüfen müssten, um sicherzugehen.
quelle
Die Antwort auf diese Frage liegt in Automaten oder genauer gesagt in endlichen Automaten, die den regulären Ausdruck definieren. Die Regel ist ... Compiler benötigen genaue Algorithmen oder Regeln, um bei jedem Zeichen, das sie analysieren, zu entscheiden. Wenn Bezeichner mit einer Zahl beginnen dürfen, dann ist der Compiler in der Klemme ... über die Art des kommenden Tokens ... wird es eine Zahl oder ein Bezeichner sein ... und Compiler können nicht zu früheren Positionen zurückkehren. .so..um dem Compiler klar zu machen, dass das kommende Token genau ein Bezeichner oder eine Zahl ist ... diese Einschränkung gibt es ... coz von diesem ... Compiler weiß nur durch Scannen des ersten Zeichens, dass das kommende Token ist ist eine Kennung oder eine Zahl.
quelle