Perché non più lingue supportano i commenti ricorsivi / nidificati? [duplicare]

14

La maggior parte delle lingue con cui ho lavorato non supportano i commenti ricorsivi / nidificati.

  1. C'è qualche motivo per cui i progettisti di linguaggio dovrebbero scegliere di non implementare questo?
  2. È ingannevolmente complesso?
  3. Avrebbe risultati indesiderati?

So che potrebbero esserci problemi come:

/*
    string Str = "aslfkalfksnflkn/*aslkfasnflkn";

*/

Console.WriteLine("asdoadokn");

Tuttavia, possiamo ancora ottenere lo stesso problema con quelli non ricorsivi (si consideri * / in una stringa in un commento) quindi non ritengo che sia un buon argomento contro.

    
posta George Duckett 26.10.2011 - 10:27
fonte

7 risposte

25

Il problema è che i commenti ricorsivi ti costringono a analizzare la sezione dei commenti, spingendola al di fuori dell'ambito di un lexer normale e probabilmente introducendo più problemi.

Come aggiornamento: un compilatore di solito ha un numero di fasi distinte con lavori diversi, ei primi sono i lexer, che ottiene il programma di input e lo separa in una sequenza di token (ognuno dei quali contiene una parola chiave, e identificatore o operatore) e il parser, che struttura questa sequenza di token in un albero di sintassi astratto (AST).

Per quanto riguarda l'ambito di un lexer, ricorda che il lexing può normalmente essere fatto da espressioni regolari. Strutture simili a quelle di un ripetitore come i commenti ricorsivi non possono essere analizzate con espressioni regolari (vedi grammatiche senza contesto), quindi il lexer dovrebbe avere molta più complessità, ad es. avrebbe bisogno di essere implementato tramite un parser ricorsivo-discendente.

Inoltre, per C e linguaggi simili (che hanno usato la sintassi / ** / dei commenti più famosi) non è mai emersa la necessità di commentare grandi blocchi di codice, poiché avevano il pre-processore e blocchi di codice inutilizzati appena avvolti da

#if 0
....
#endif

che eludeva il problema di analisi delegando il problema a un secondo compilatore molto più semplice (il pre-processore).

Riassumere: poiché i commenti ricorsivi renderebbero la compilazione più complicata, di solito non sono consentiti e solo le lingue con commenti in stile C, ma senza un preprocessore, ne hanno davvero bisogno. Che Java sia tra loro è sfortunato, naturalmente.

Modifica: questo non significa che i commenti ricorsivi sarebbero impossibili o addirittura molto difficili da fare. Potresti usare un lexer ricorsivo-discendente o avere un preprocessore prima del lexer per filtrare i commenti. Tuttavia, entrambi gli approcci hanno un costo considerevole rispetto al modello standard (usa RE per auto-compilare il lexer e un EBNF per auto-compilare il parser), e il guadagno è piuttosto piccolo.

    
risposta data 26.10.2011 - 10:46
fonte
8

Sono con te su questo. Quando lavori con basi di codice grandi e vecchie, queste sono disseminate di commenti relativi a hack, codice commentato e altro sporco e grinta, per non parlare delle interfacce C documentate in /*...*/ commenti. Se devi commentare qualcosa, usare /*...*/ commenti non è quasi mai un'opzione, perché non annidano.

Non credo che "complicare ulteriormente il compilatore" sia una ragione, perché rispetto alla complessità del C ++, l'analisi dei commenti per /* , */ (e forse // ) dovrebbe essere ridicolmente facile. In effetti, mi sembra di ricordare Borland C ++ (negli anni '90) che offre l'opzione di analizzare commenti nidificati - e che il compilatore era noto per la sua velocità di illuminazione.

Ma il problema con le soluzioni non standard è che non è possibile utilizzarle se è necessario portare il codice in un secondo momento. (E, in C ++, chi lo escluderebbe mai?)

Quindi sono d'accordo che sarebbe un miglioramento se fosse standardizzato.

Nel frattempo, utilizzo // commenti per commentare frammenti di codice. Fortunatamente, la maggior parte degli editor / IDE moderni ha la possibilità di applicarlo a più righe contemporaneamente.

    
risposta data 26.10.2011 - 11:31
fonte
4

Ho modificato un compilatore C per farlo una volta, non è stato terribilmente difficile. È tutto a posto nello scanner lessicale, quindi non devi perdere tempo con il fegato del parser. Si tratta semplicemente di tenere traccia del livello di annidamento e ignorare qualsiasi cosa all'interno dei delimitatori di stringhe.

    
risposta data 26.10.2011 - 13:01
fonte
3

Newspeak ha commenti strutturati che possono annidare. E ha una grammatica molto semplice, quindi ovviamente non è "ingannevolmente complesso".

    
risposta data 26.10.2011 - 11:34
fonte
3

I commenti che si estendono su più righe dovrebbero essere l'eccezione, non la regola.

Anche in C, uso lo stile C ++ // invece dello standard /* */ .

Se devo assolutamente commentare una grande porzione di codice, utilizzo la direttiva #if 0 preprocessore, che supporta la nidificazione.

    
risposta data 26.10.2011 - 11:08
fonte
1

Questa è la ricorsione:

public void recursion()
{
    recursion();
}

Non ho idea di come sarebbero i commenti ricorsivi.

I commenti nidificati, d'altra parte, avrebbero senso, e in realtà già funziona in una certa misura. Puoi annidare i commenti a riga singola all'interno di più commenti di riga.

/* No longer use this!
// This is a method.
public void method()
{
}
*/

Supportare ciò che stai chiedendo, dal punto di vista del programmatore, sarebbe perfettamente sensato.

/* No longer use this!
// This is a method.
public void method()
{
    /* Disabled!
       doInterestingStuff();
       ...
    */
}
*/

Considerando che i linguaggi di programmazione sono solo strumenti in cui i programmatori possono esprimere le loro intenzioni, il supporto di questa intenzione sarebbe un valore aggiunto.

Non posso commentare a memoria gli aspetti tecnici, ma sembra che alcune delle altre risposte abbiano già fornito informazioni su questo.

    
risposta data 26.10.2011 - 11:31
fonte
1

Una ragione è probabilmente la compatibilità con le basi di codice esistenti; I linguaggi C-like tipicamente fanno tutto proprio come C, anche cose stupide come 031 == 25 (letterali ottali, chi ne ha mai avuto bisogno?)

Un altro motivo è più filosofico: un commento inizia con (ad es.) / * e termina con il prossimo * /, e qualunque cosa ci sia in mezzo, non ha importanza per niente . I commenti nidificati richiedono anche la definizione di una sintassi per i commenti.

BTW, se non hai più bisogno di quel codice pezzo, perché non rimuoverlo completamente e lasciarlo al VCS per mantenere la versione precedente? Il codice commentato è un odore di codice.

    
risposta data 26.10.2011 - 18:02
fonte

Leggi altre domande sui tag