2010-06-03 20 views

Respuesta

14

C y C++ lo hacen para facilitar el análisis. De esta forma, cuando tocan un comentario de inicio de/*, el analizador puede escanear trivialmente hasta el final. De lo contrario, tendría que configurar y mantener una pila, y luego informar los errores si los tokens de comentarios no coinciden.

En cuanto a por qué lo hace Java, la respuesta es simple: la sintaxis de Java fue diseñada para emular C y C++, para engañar a las personas haciéndolas creer que era igual de rápido (al principio, Java fue puramente interpretado) necesario para obtener tracción). Si se permitieran los comentarios anidados, podrían tropezar a algunos programadores de C, ¡y se escribirían muchas publicaciones de blog enojadas!

+0

¿Por qué necesitarías una pila para manejar los comentarios anidados? Simplemente mantenga un contador, incrementándolo cada vez que encuentre un '/ *' y disminuyéndolo cada vez que encuentre un '* /'. Cuando el contador es mayor que cero, arrojas los caracteres que encuentres (mientras sigues haciendo un seguimiento de '/ *' y '* /'); cuando el contador es cero, lee los tokens normalmente y se los entrega al analizador sintáctico; si el contador se vuelve negativo, informa una discrepancia entre los delimitadores de comentarios. Lo hace durante el análisis léxico, por lo que el analizador ni siquiera ve los comentarios. –

3

Conformidad/compatibilidad con C.

+1

¿Acaso C no utilizó originalmente el símbolo // de comentario? Además, ¿por qué Java debería ajustarse al estándar C? – tloach

+3

@tloach: '//' no existe en C antes de C99. – kennytm

+7

C originalmente solo se usaba/* * /, y Java se diseñó intencionalmente después de C (y C++) para que sea más familiar para los programadores existentes. Conform es probablemente una palabra demasiado fuerte aquí, pero no estoy seguro de qué sería mejor. – ergosys

8

Al menos para C++ que es sólo parcialmente cierto, no hay problema:

/* 
// 
// 
*/ 

Sin embargo, si usted ya tiene un * Comentarios/en una sección que desee comente que podría hacerlo rodeándolo con un #if 0 que creo que muchos compiladores optimizan. Como en:

#if 0 
/* 

*/ 
#endif 
+1

TODOS los compiladores optimizan eso, de la misma manera que "optimizan" múltiples veces, incluso cuando se usan protectores de encabezado, ya que es parte del paso de preproceso. –

+4

Los compiladores no verán este bloque, el * preprocesador * lo habrá eliminado antes de que un compilador ponga sus ojos en el código :). – Pieter

+0

@wowus: Sí, tienes razón, por supuesto. Estaba pensando en 'if (0)', que creo que depende del compilador. –

3

Es diferente para cada idioma (-familia) pero en general no están 'prohibidos', simplemente no son compatibles. Respaldarlos es una opción de diseño.

Una de las razones para la elección (para idiomas más antiguos) puede haber sido la facilidad de análisis.

Nota: Recuerdo un compilador de C++ en el que era una opción dejarlos anidar. Fue marcado como 'no estándar'.

2

Consideremos el siguiente ejemplo:

/* This is a comment /* Nested Comments */ are not allowed. */ 

Cualquier cosa que se encuentra entre /* y */ se trata como un comentario. En el ejemplo anterior desde This hasta Comments, todo se trata como comentarios, incluido /*. Por lo tanto, are not allowed. */ no se encuentra en el comentario. Esto es un error de sentencia C incorrecto.

Mientras que considere este ejemplo:

// This is an /* valid */ comment 

Lo que se encuentra en la línea después de // se trata como comentario. Dado que /* valid */ se encuentra en la misma línea después de //, se trata como parte del comentario.

0

En los idiomas que permiten comentarios de longitud arbitraria, es muy común que los programadores comenten accidentalmente o, en algunos casos raros, "vuelvan a descomentar" en más o menos código de lo deseado. En muchos casos, tales errores darán lugar a errores de compilación, pero en otros casos pueden dar como resultado un código que simplemente se rompe. Con los editores modernos de resaltado de sintaxis, una regla que cada /* incrementaría un contador de comentarios anidados y cada */ que lo disminuiría podría no causar demasiados problemas, pero sin resaltar la sintaxis, incluso tratando de descubrir qué código se comenta y qué código no fue No podría ser un gran dolor de cabeza.

Si se diseñó un lenguaje desde cero, un buen enfoque podría ser especificar marcas de inicio de comentario y fin de comentario que incluyan una cadena opcional, y hacer que el lenguaje exija un requisito de que la cadena en un La marca de fin de comentario debe coincidir con la cadena en su correspondiente marca de inicio de comentario. Suponiendo que la sintaxis era <|String| y |String|>, un compilador podría aceptar <|1| <|2| |2|> |1|>, pero rechazar <|1| <|2| |1|> |2|>. Incluso si se favorece el uso de las directivas #if en lugar de comentarios, la capacidad de adjuntar marcadores para garantizar que cada directiva final se vincule con la directiva de inicio prevista sería útil.

-1

El problema es que no se puede simplemente "omitir" bloques. los bloques tienen un número desconocido de bloques dentro de ellos, por lo que para saber cuándo se completa ese bloque, no puedes usar un lenguaje común, debes usar una pila y caminar por cada bloque hasta que la pila esté vacía, en ese punto usted sabe que el bloqueo está hecho.

La razón por la que no puede omitir bloques es que la expresión regular del bloque solo puede hacer coincidir el/* con "el primero */ve luego" o "el último */ve luego" o "enésimo */ve después".

Si vamos con el primer "* /" señal que vemos, podemos tener un código como

/* 
    /* 

    */ 
    the compiler matched /* with */ and this line and the next one will confuse it. 
*/ 

Si vamos con el último "* /" señal que vemos, tenemos código en el compilador omitirá las cosas entre el primer comentario en el archivo y el último comentario del final del archivo. En este caso, el siguiente código se analizaría como una cadena vacía.

/* 
    /* hello, world! */ 
*/ 
int main(int argc, char ** argv) { 
    return 0; 
} 
/* end of file */ 

No podemos ir con la tercera opción de omisión de n bloques interiores sin obligar a todos los comentarios de tener el número exacto de la profundidad, de lo contrario no encontrará el comentario interior y confundirse.

En realidad, hay una cuarta opción que establece explícitamente que un comentario puede ser un comentario único, un comentario de 2 ámbitos, un comentario de 3 ámbitos, etc .; Pero hacer esto es feo, y cada nivel de profundidad requiere una expresión significativamente más larga, y este enfoque limita los comentarios a una profundidad específica que puede adaptarse a algunas personas y no a otras: ¿Qué pasaría si comenta un código que ha sido comentado? ¿3 veces?

La solución general se puede implementar con un pre-preprocesador tales como:

<?php 
function stripComments($code) { 
    $stack = array(); 
    $codeOut = ''; 
    $stringStream = fopen('php://memory', 'r+'); 
    fwrite($stringStream, $code); 
    rewind($stringStream); 

    while (!feof($stringStream)) { 
     $ch = fgetc($stringStream); 

     $nextChar = fgetc($stringStream); 
     if ($nextChar === false) { 
      break; 
     } 

     if ($ch == '/' && $nextChar == '*') { 
      array_push($stack, '/*');   
     } else if ($ch == '*' && $nextChar == '/') { 
      if (count($stack) > 0) { 
       array_pop($stack); 
      } else { 
       die('cannot pop from empty stack'); 
      } 
     } else { 
      if (count($stack) == 0) { 
       $codeOut .= $ch; 
       fseek($stringStream, -1, SEEK_CUR); 
      } 
     }    

     $prevChar = $ch; 
    } 
    return $codeOut; 
}; 
?> 

que es un poco más complicado que lo que C utiliza actualmente:

function stripComments($code) { 
    return preg_replace('/\/\*[^\*\/]*\*\//', '', $code); 
} 

Esto no toma en consideración /**/ bloques dentro de comillas, se requiere una pila un poco más complicada que puede distinguir entre el alcance "/ *" y el "\" ".

El beneficio de tener comentarios dentro de los comentarios es que puedes comentar los bloques que contienen comentarios sin eliminar los comentarios manualmente, lo que es particularmente frustrante para los bloques que tienen comentarios en cada línea.

Sumario: Se puede hacer, pero la mayoría de los idiomas no desean tratar los comentarios como si fueran sus propios ámbitos, ya que requiere más esfuerzo analizarlos.

Cuestiones relacionadas