Perché gli identificatori non dovrebbero iniziare con un numero?

31

La maggior parte dei linguaggi di programmazione sembra progettata per non consentire a uno di dichiarare un identificatore che inizia con un numero. Ero solo curioso di sapere il motivo. Ho già cercato nel web, ma non sono riuscito a trovare una spiegazione soddisfacente.

    
posta Sivasubramaniam Arunachalam 05.02.2012 - 06:09
fonte

9 risposte

50

In C / C ++, un numero seguito da una lettera è considerato una costante numerica e la stringa che segue, qualifica il tipo di costante. Quindi per esempio (questi sono VC ++, non sono sicuro di come siano standard):

  • 0 - numero intero con segno
  • 0l - numero intero con segno
  • 0u - numero intero senza segno
  • 0i64 - intero con segno a 64 bit

Quindi a) è più facile per il lexer come ha detto Daniel, ma anche b) fa una distinzione esplicita poiché 0y potrebbe essere una variabile ma 0u non lo sarebbe mai. Inoltre altri qualificatori, come "i64" sono stati aggiunti molto più tardi di "l" o "u" e vogliono mantenere l'opzione aperta di aggiungerne altri se necessario.

    
risposta data 05.02.2012 - 06:23
fonte
49

La comodità delle persone che implementano il lexer. (No, sul serio, questo è tutto. Varie lingue hanno altri motivi, ma alla fine si riduce a quello.)

    
risposta data 05.02.2012 - 06:10
fonte
20

Considera i seguenti 2 casi:

Caso 1

Supponiamo che un identificatore possa iniziare con un numero.

Quindi una dichiarazione come di seguito sarebbe valida (dal momento che un identificatore può avere uno o più caratteri):

int 3;

Quando provo a usare la variabile sopra in un programma, si otterrà l'ambiguità del compilatore:

int 3,a;
3=5;
a=3;

Nell'istruzione a=3 qual è il ruolo di 3 (è una variabile con valore 5 o è il numero 3)?

Caso 2

Contrariamente all'esempio sopra, si assume che una lingua consenta effettivamente agli identificatori di iniziare con un numero mentre ancora non consente l'uso di numeri come identificatori. Ciò può causare i seguenti problemi:

  • Le regole linguistiche relative alla variabile che dice che una variabile può consistere di 1 o più caratteri dovranno essere ridefinite in una regola complessa come: Una variabile può avere uno o più caratteri e deve essere univoco se non inizia con un numero mentre non può essere di lunghezza di un singolo carattere quando inizia con un numero (ecc.)

  • Il compilatore dovrà controllare e segnalare casi di errore quando tutti i numeri (ad es. 333) e i suffissi validi dell'alfabeto (ad es. 34L) vengono usati come nomi di variabili. In linguaggi generici come Python e JS in cui è possibile utilizzare le variabili al volo senza dichiararle, potrebbe persino essere impossibile verificare i casi speciali che coinvolgono tutti i numeri, ad es. if (33==5) Qui, 33 potrebbe essere una errata variabile non dichiarata che l'utente ha dichiarato. Ma il compilatore non sarà in grado di identificare questo e segnalare l'errore.

Questa restrizione impedirà al programmatore di utilizzare i numeri come nomi identificativi.

    
risposta data 05.02.2012 - 09:32
fonte
11

Per la maggior parte questo non ha nulla a che fare con la semplificazione per gli scrittori di compilatori e l'efficienza di analisi, ma, più, con la progettazione di una sintassi che incoraggia un codice chiaro leggibile e univoco.

I designer del linguaggio hanno pensato che sarebbe stato bello poter scrivere letterali numerici come il numero 1 semplicemente come 1 .

Sarebbe del tutto possibile progettare una sintassi del linguaggio in cui i letterali numerici fossero citati in qualche modo per esempio tilde, quindi il letterale numerico per il numero uno era codificato come ~ 1 ~ e qualsiasi cosa non fosse una parola chiave e non racchiuso tra virgolette è stato trattato come un nome di variabile.

Quindi potresti codificare dichiarazioni come:

1 = ~2~
two = 1 * ~2~

Ma anche:

2 = ~3~
six = 2 + 2

Qualsiasi sintassi tu scelga codice ambiguo e difficile da seguire è inevitabile.

Il linguaggio C e la maggior parte dei linguaggi "parentesi graffe" discendenti da C ritenevano sia una buona idea consentire ai programmatori di codificare direttamente letterali ottali ed esadecimali e, per specificare il tipo di letterale, se ciò era importante. Quindi

010  // Octal 10 = 8;
0x10 // Hexadecimal 10 = 16;
5l   // long integer with decimal value 5
2.0d // double float with value 2

Quindi, anche se hai permesso che i nomi delle variabili iniziassero con un numero seguito da una combinazione di numeri e lettere che includeva almeno una lettera, avresti presentato al programmatore il problema di decidere se un dato gruppo formasse un nome di variabile o un valore letterale numerico quindi

2lll = 22 // OK
2ll  = 2  // compiler error

Tale ambiguità non aiuterebbe nessuno a scrivere o leggere un programma.

Per un esempio del mondo reale strettamente correlato puoi guardare al linguaggio PL / 1 i cui progettisti pensavano che essere in grado di usare le parole chiave come nomi di variabili fosse una buona idea in modo che:

IF THEN THEN THEN = ELSE; ELSE ELSE = THEN;
IF IF THEN ELSE = IF; ELSE THEN = ELSE;
DO WHILE (WHILE = DO); END = WHILE + DO; END;

È un codice valido che compila ed esegue.

    
risposta data 06.02.2012 - 08:02
fonte
10

Fortran ha avuto un enorme impatto sul modo in cui sono state progettate le lingue successive. Presto (alcuni di questi problemi sono stati risolti) Fortran aveva quasi nessuna regola che limitasse il nome che potevi dare a un identificatore. Ciò ha reso il linguaggio estremamente difficile da analizzare sia per i compilatori che per i programmatori. Ecco un esempio classico:

if if .eq. then then = else else else = endif endif
K  I   K   K    I      I    K    I      I     K

Qui ho segnato le "parole chiave della lingua" con K e gli identificatori (nomi delle variabili) I. Dato che non c'è differenza nell'ortografia, penso che tu possa probabilmente capire quanto possa essere confuso. Ovviamente, questo è un esempio estremo ed è improbabile che qualcuno abbia mai scritto un codice del genere apposta. A volte le persone hanno "riciclato" le parole chiave della lingua come nomi di identificatori - e in molti casi un semplice errore di battitura potrebbe causare codice che le specifiche della lingua avrebbero dovuto essere analizzate in questo modo, anche se non era non inteso affatto. Per un altro esempio ben noto, confronta questo:

do 10 i = 1,10

a questo:

do 10 i = 1.10

Il primo è un ciclo do - iterando un blocco di codice 10 volte. Il secondo, tuttavia, ha modificato la virgola in un punto decimale, quindi assegna il valore 1.10 a una variabile denominata do 10 i .

Questo significava anche che scrivere un parser Fortran era relativamente difficile - non si poteva essere certi che il do all'inizio della riga fosse davvero una parola chiave fino a quando non si arrivava alla fine della linea, e verificato che erano presenti tutti gli altri elementi di un ciclo do . Generalmente il parser doveva essere pronto per "tornare indietro", ri-analizzare la riga dall'inizio per arrivare alla risposta "corretta" (ma spesso non voluta) di ciò che era realmente lì.

Dopo alcuni anni, i progettisti di linguaggi (la maggior parte comunque) sono andati all'estremo opposto, limitando quasi tutto il linguaggio il più possibile senza che gli utenti si lamentassero troppo .

Il BASIC iniziale, ad esempio, in pratica diceva che non si poteva nemmeno usare una parola chiave come parte di un identificatore - ad esempio, fora=1 sarebbe analizzato come for a = 1 (cioè, l'inizio di un for loop, non un incarico). Questo a quanto pare ha generato abbastanza lamentele da non durare molto a lungo. La regola sull'avvio di un identificatore con una cifra apparentemente non ha generato molti reclami, quindi continua ad essere utilizzata (almeno nella maggior parte delle lingue).

    
risposta data 06.02.2012 - 18:01
fonte
1

È probabile che questa convenzione si sia evoluta dalle primissime decisioni di progettazione del linguaggio storico, poiché sulle prime macchine l'intero compilatore, inclusa l'analisi lessicale, doveva essere eseguito in pochi kWords, con una memoria inferiore a quella della cache dei dati del processore di primo livello su corrente dispositivi mobili, quindi i nomi delle variabili consentiti erano molto limitati e dovevano essere facili da distinguere dalle costanti numeriche in pochissimi codici op.

Quindi, la convenzione è diventata ciò a cui sono abituate le generazioni di programmatori.

    
risposta data 05.02.2012 - 06:20
fonte
1

Non è una regola logicamente richiesta per il linguaggio di programmazione, ma solo la convenzione utilizzata da molti progettisti di linguaggi.

Posso progettare un linguaggio radicalmente diverso che consente a tutti i caratteri di identificatori. Per tutte le righe di codice, i primi 20 caratteri descriveranno il tipo di istruzione, quindi il prossimo 20 caratteri definirà il primo simbolo per l'istruzione e il prossimo 20 caratteri è l'operando per l'istruzione. Questo linguaggio verrà eseguito su un processore stack.

01234567890123456789 01234567890123456789 01234567890123456789

decl symbol          12345                
assign value         12345                12345
decl symbol          99999                
assign value         99999                12345
push                 12345
push                 99999
add
print top

Questo codice potrebbe essere tradotto in C come segue:

int i12345 = 12345;
int i99999 = 12345;
printf("%d", i12345+i9999);

Questo è tutto. È privo di significato e la regola del numero senza numero di identificatori è anche priva di fondamento logico.

    
risposta data 06.02.2012 - 06:23
fonte
0

Oltre alla "convenienza per il lexer", penso valga anche la pena considerare "la convenienza per il lettore".

Durante la lettura del codice, è necessario identificare rapidamente e ripetutamente quali parole sono identificatori e quali sono numeri. Cercare una cifra all'inizio è più facile nel nostro abbinamento di modelli visivi; sarebbe un compito arduo se dovessimo controllare attentamente tutti i personaggi per essere sicuri.

    
risposta data 06.02.2012 - 20:32
fonte
0

La risposta a questa domanda si trova negli automi o in automi più precisamente finiti che definiscono l'espressione regolare. La regola è che ... i compilatori hanno bisogno di algoritmi o regole esatte per decidere su ogni personaggio che analizzano. Se agli identificatori fosse permesso di iniziare con un numero, il compilatore sarà in una correzione ... sulla natura del token in arrivo ... sarà un numero o un identificatore ... e come i compilatori possono tornare indietro alle posizioni precedenti. .so..per chiarire al compilatore che il token in arrivo è precisamente un identificatore o un numero ... questa limitazione è lì ... coz di questo ... il compilatore sa solo scansionando il primo carattere che il token in arrivo è un identificatore o un numero.

    
risposta data 09.02.2012 - 19:09
fonte

Leggi altre domande sui tag