La plupart des langages de programmation semblent être conçus pour ne pas permettre de déclarer un identifiant commençant par un nombre. J'étais simplement curieux de connaître la raison. J'ai déjà cherché sur le Web, mais je n'ai pas trouvé d'explication satisfaisante.
32
Réponses:
En C / C ++, un nombre suivi d'une lettre est considéré comme une constante numérique et la chaîne qui suit qualifie le type de la constante. Ainsi, par exemple (ce sont VC ++, je ne sais pas à quel point ils sont standard):
Donc a) c'est plus facile pour le lexer comme Daniel l'a dit mais aussi b) ça fait une distinction explicite puisque 0y pourrait être une variable mais 0u ne le serait jamais. De plus, d'autres qualificatifs, comme «i64», ont été ajoutés bien plus tard que «l» ou «u» et ils veulent garder l'option ouverte d'en ajouter plus si nécessaire.
la source
La commodité des personnes implémentant le lexer. (Non, sérieusement, c'est à ce sujet. Diverses langues ont d'autres raisons, mais cela se résume finalement à cela.)
la source
0flu
était un littéral et0glu
un identifiant local.int 0u = 5; unsigned int x = 0u;
Cependant, vous choisissez de définir l'interprétation de ce code (probablement x == 0 ou x == 5), les gens vont être confus à cause de l'ambiguïté. Même s'il était trivial d'implémenter le compilateur de cette façon, un bon concepteur ne le ferait probablement pas.Considérez les 2 cas suivants:
Cas 1
Supposons qu'un identifiant puisse commencer par un nombre.
Une déclaration comme ci-dessous serait donc valide (puisqu'un identifiant peut avoir 1 ou plusieurs caractères):
Lorsque j'essaie d'utiliser la variable ci-dessus dans un programme, cela entraîne une ambiguïté du compilateur:
Dans l'énoncé,
a=3
quel est le rôle de 3 (est-ce une variable de valeur 5 ou est-ce le chiffre 3)?Cas 2
Contrairement à l'exemple ci-dessus, supposons qu'une langue devait réellement autoriser les identifiants commençant par un nombre tout en interdisant l'utilisation de chiffres comme identifiants. Cela peut provoquer les problèmes suivants:
Les règles de langage concernant la variable qui dit qu'une variable peut comprendre 1 ou plusieurs caractères devront être redéfinies en une règle complexe comme: Une variable peut avoir un ou plusieurs caractères et doit être unique si elle ne commence pas par un nombre tandis que il ne peut pas avoir une longueur de caractère unique en commençant par un nombre (etc.)
Le compilateur devra vérifier et signaler les cas d'erreur lorsque tous les chiffres (par exemple 333) et les suffixes d'alphabet valides (par exemple 34L) sont utilisés comme noms de variables. Dans des langages mal typés comme Python et JS où vous pouvez utiliser des variables à la volée sans les déclarer, il peut même être impossible de vérifier les cas spéciaux impliquant tous les chiffres, par exemple
if (33==5)
ici, 33 pourrait être une variable non déclarée erronée que l'utilisateur a déclarée. Mais le compilateur ne pourra pas identifier cela et signaler l'erreur.Cette restriction empêchera le programmeur d'utiliser des nombres comme noms d'identificateurs.
la source
int char = float
serait désastreux ?int
s'agit d'un mot-clé et non d'un identifiant? Eh bien,int
a une priorité plus élevée, tout comme les lexèmes numériques.int 3,a; 3=5; a=3;
Dans l'énoncé a = 3, 3 est-il interprété comme un identifiant ou comme un nombre? Cela crée une ambiguïté. J'espère que c'est clair.Pour la plupart, cela n'a rien à voir avec la facilité pour les rédacteurs du compilateur et l'efficacité de l'analyse, mais plutôt avec la conception d'une syntaxe qui encourage un code clair et lisible et sans ambiguïté.
Ses concepteurs de langage ont pensé qu'il serait bien de pouvoir écrire des littéraux numériques comme le chiffre 1 comme tout simplement 1 .
Il serait tout à fait possible de concevoir une syntaxe de langage dans laquelle les littéraux numériques seraient cités d'une certaine manière, par exemple les tildas, de sorte que le littéral numérique pour le numéro un serait codé comme ~ 1 ~ et tout ce qui n'est pas un mot-clé et non entre guillemets serait traité comme un nom de variable .
Vous pouvez donc coder des instructions comme:
Mais aussi:
Quelle que soit la syntaxe que vous choisissez, le code ambigu et difficile à suivre est inévitable.
Le langage C et la plupart des langages "accolades" issus de C pensaient également que c'était une bonne idée de permettre aux programmeurs de coder directement les littéraux octal et hexadécimal, et de spécifier le type du littéral si cela était important. Alors
Donc, même si vous autorisez les noms de variables à commencer par un nombre suivi d'une combinaison de chiffres et de lettres qui comprenait au moins une lettre, vous poseriez au programmeur le problème de décider si un groupe donné formait un nom de variable ou un littéral numérique afin
Une telle ambiguïté n'aiderait personne à écrire ou à lire un programme.
Pour un exemple proche du monde réel, vous pouvez regarder le langage PL / 1 dont les concepteurs pensaient que pouvoir utiliser des mots clés comme noms de variable était une bonne idée, de sorte que:
Est un code valide qui compile et exécute.
la source
Fortran a eu un effet énorme sur la conception des langages ultérieurs. Très tôt (certains de ces problèmes ont depuis été corrigés), Fortran n'avait pratiquement pas de règles limitant le nom que vous pouviez donner à un identifiant. Cela a rendu le langage extrêmement difficile à analyser à la fois pour les compilateurs et pour les programmeurs. Voici un exemple classique:
Ici, j'ai marqué les «mots clés de la langue» avec K et les identifiants (noms de variables) I. Étant donné qu'il n'y a pas de différence d'orthographe, je pense que vous pouvez probablement comprendre à quel point cela peut être déroutant. Bien sûr, ceci est un exemple extrême, et il est peu probable que quelqu'un ait jamais écrit du code comme ça exprès. Parfois , les gens ont « recycler » langue des mots clés comme noms d'identification si - et dans beaucoup de cas , une simple faute de frappe pourrait donner lieu à un code que la spécification de langage dit doit être analysé de cette façon, même si on n'a pas voulu du tout. Pour un autre exemple bien connu, comparez ceci:
pour ça:
Le premier est une boucle do - itérant 10 fois un bloc de code. Le second, cependant, a changé la virgule en virgule décimale, il s'agit donc d'affecter la valeur
1.10
à une variable nomméedo 10 i
.Cela signifiait également que l'écriture d'un analyseur Fortran était relativement difficile - vous ne pouviez pas être sûr que le
do
début de la ligne était vraiment un mot clé jusqu'à ce que vous atteigniez la fin de la ligne, et vérifié que tous les autres éléments d'undo
boucle étaient présents. L'analyseur devait généralement être prêt à "revenir en arrière", en ré-analysant la ligne depuis le début pour arriver à la réponse "correcte" (mais souvent involontaire) de ce qui était vraiment là.Après quelques années, les concepteurs de langage (la plupart d'entre eux de toute façon) sont allés vers l'extrême opposé - restreignant presque tout sur la langue autant que possible sans que les utilisateurs se plaignent trop .
Les premiers BASIC, par exemple, disaient essentiellement que vous ne pouviez même pas utiliser un mot clé dans le cadre d'un identifiant - par exemple,
fora=1
serait analysé commefor a = 1
(c'est-à-dire le début d'unefor
boucle, pas une affectation). Cela a apparemment généré suffisamment de plaintes pour ne pas durer très longtemps. La règle concernant le démarrage d'un identifiant avec un chiffre n'a apparemment pas généré beaucoup de plaintes, donc il continue d'être utilisé (au moins dans la plupart des langues).la source
Cette convention a probablement évolué à partir des premières décisions de conception du langage historique, car sur les premières machines, le compilateur entier, y compris l'analyse lexicale, devait fonctionner sur quelques kWords, moins de mémoire que même le cache de données du processeur de premier niveau sur les appareils mobiles actuels, les noms de variables autorisés étaient donc très limités et devaient être faciles à distinguer des constantes numériques dans très peu de codes op.
Ainsi, la convention est devenue ce à quoi les générations de programmeurs sont habituées.
la source
Ce n'est pas une règle logiquement requise pour le langage de programmation mais juste la convention utilisée par de nombreux concepteurs de langage.
Je peux concevoir un langage radicalement différent qui autorise tous les caractères pour les identifiants. Pour toutes les lignes de code, les 20 premiers caractères décrivent le type d'instruction, puis les 20 caractères suivants définissent le premier symbole de l'instruction et les 20 caractères suivants sont l'opérande de l'instruction. Ce langage sera exécuté sur un processeur de pile.
Ce code pourrait être traduit en C comme ci-dessous:
C'est tout. Cela n'a pas de sens et la règle de non-nombre dans les identificateurs est également inutile sur le plan logique.
la source
En plus de "la commodité pour le lexer", je pense qu'il vaut également la peine de considérer la "commodité pour le lecteur".
Lors de la lecture du code, vous devez identifier rapidement et à plusieurs reprises quels mots sont des identifiants et quels sont des nombres. La recherche d'un chiffre au début est plus facile avec notre correspondance visuelle des motifs; ce serait une corvée si nous devions vérifier soigneusement tous les personnages pour nous en assurer.
la source
La réponse à cette question réside dans les automates ou plus précisément les automates finis qui définissent l'expression régulière. La règle est ... les compilateurs ont besoin d'algorithmes ou de règles exacts pour décider de chaque caractère qu'ils analysent. Si les identifiants étaient autorisés à commencer par un nombre, alors le compilateur sera dans un correctif..à propos de la nature du jeton à venir ... sera-ce un nombre ou un identifiant ... et comme les compilateurs ne peuvent pas revenir en arrière vers des positions antérieures .. .so..pour faire comprendre au compilateur que le jeton à venir est précisément un identifiant ou un nombre ... cette restriction est là ... car ce compilateur ... sait simplement en scannant le premier caractère que le jeton à venir est un identifiant ou un nombre.
la source