¿Hay compiladores que intenten corregir los errores de sintaxis por su cuenta? [cerrado]

13

Hace un tiempo escuché que solía haber un compilador que intentaba corregir errores de sintaxis analizando el contexto e inferiendo lo que se pretendía.

¿Existe realmente este compilador? Obviamente tiene poco valor práctico, pero sería muy interesante jugar y aprender de él.

    
pregunta Nathan Osman 27.12.2010 - 08:09

12 respuestas

23

En cierto sentido, el acto de compilar es inferir lo que se supone que debe hacer cierta sintaxis, y por lo tanto, un error de sintaxis es cuando el compilador no puede resolverlo. Puede agregar más "adivinanzas" para que el compilador infiera más cosas y sea más flexible con la sintaxis, pero debe hacer esto inferiendo mediante un conjunto específico de reglas. Y esas reglas se convierten en parte del lenguaje y ya no son errores.

Entonces, no, no hay tales compiladores, en realidad, porque la pregunta no tiene sentido. Adivinar qué errores de sintaxis se deben hacer de acuerdo con un conjunto de reglas se convierte en parte de la sintaxis.

En ese sentido, hay un buen ejemplo de un compilador que hace esto: Cualquier compilador de C. A menudo, simplemente imprimen una advertencia de algo que no es como debería ser, y luego asumen que te referías a X y continúan. De hecho, esto es "adivinar" un código poco claro (aunque en su mayoría no es una sintaxis propiamente dicha), algo que también podría haber detenido la compilación con un error y, por lo tanto, calificar como error.

    
respondido por el Lennart Regebro 27.12.2010 - 12:19
23

Suena realmente peligroso. Si un compilador intenta inferir su intención, lo infiere mal, corrige el código y luego no le dice (o le advierte en alguna advertencia que usted, como todo el mundo, ignora), entonces está a punto de ejecutar un código que puede seriamente hacer un poco de daño.

Un compilador como este es probablemente algo que intencionalmente NO ha sido creado.

    
respondido por el nganju 27.12.2010 - 08:30
9

El IDE para un lenguaje de programación por lo general en estos días tiene un compilador que se ejecuta en segundo plano de alguna manera, por lo que puede proporcionar servicios de análisis como coloración de sintaxis, IntelliSense, errores, etc. Obviamente, tal compilador debe ser capaz de dar sentido a un código profundamente dañado; La mayoría de las veces cuando se edita, el código no es correcto. Pero todavía tenemos que darle sentido.

Sin embargo, normalmente la función de recuperación de errores solo se utiliza durante la edición; no tiene mucho sentido permitir eso para la compilación real en escenarios de "línea principal".

Curiosamente, construimos esa característica en el compilador JScript.NET; Básicamente, es posible poner el compilador en un modo en el que permitimos que el compilador continúe incluso si se encuentra un error, si el IDE se hubiera recuperado de él. Puede escribir el código de Visual Basic , ejecutar el compilador JScript.NET en él y tener una posibilidad razonable de que un programa operativo esté saliendo por el otro lado.

Esta es una demostración divertida, pero resulta que no es una característica muy buena para los escenarios de "línea principal" por muchas razones. Una explicación completa sería bastante larga; La breve explicación es que hace para los programas que funcionan de forma impredecible y por accidente , y hace que sea difícil ejecutar el mismo código a través de varios compiladores o varias versiones del mismo. compilador. Los grandes gastos que agrega la función no están justificados por los pequeños beneficios.

Peter Torr, quien PM hizo la función en su época, lo analiza brevemente en este blog publicado desde 2003 .

Aunque exponemos esta función a través de las API de hospedaje de scripts del motor .NET de JScript, no conozco a ningún cliente real que la haya utilizado alguna vez.

    
respondido por el Eric Lippert 27.12.2010 - 20:00
8

Lo primero que me viene a la mente es el inserción automática de punto y coma de Javascript. Una característica horrible, horrible que nunca debería haberse introducido en el lenguaje.

Eso no quiere decir que no podría haber hecho un mejor trabajo. Si miraba hacia el futuro en la siguiente línea, podría hacer una mejor estimación de la intención del programador, pero al final del día, si hay varias formas válidas que podría tener la sintaxis desaparecido, entonces realmente no hay sustituto para que el programador sea explícito.

    
respondido por el Dean Harding 27.12.2010 - 08:47
7

Me parece que si un compilador puede corregir una sintaxis incorrecta, esa sintaxis debería estar documentada en el idioma.

El motivo de los errores de sintaxis es que un analizador no pudo crear el árbol de sintaxis abstracta fuera del programa. Esto sucede cuando una ficha está fuera de lugar. Para adivinar dónde debería estar ese token, si debe eliminarse, o si se debe agregar algún otro token para corregir el error, necesitará algún tipo de computadora que pueda adivinar la intención de un programador. ¿Cómo podría una máquina adivinar que:

int x = 5 6;

Se suponía que era:

int x = 5 + 6;

Podría fácilmente ser cualquiera de los siguientes: 56 , 5 - 6 , 5 & 6 . No hay manera de que un compilador sepa.

Esa tecnología aún no existe.

    
respondido por el jjnguy 27.12.2010 - 08:39
4

Aunque no es exactamente lo mismo, esto es una especie de por qué HTML se convirtió en el desastre que es. Los navegadores toleraron el marcado incorrecto y lo siguiente que sabías es que el navegador A no podía mostrarse de la misma manera que el navegador B (sí, existen otras razones, pero esta fue una de las pocas más importantes, especialmente hace unos 10 años, antes de que algunas de las reglas de flexibilidad se convirtieran en convenciones ).

Como dice Eric Lippert, muchas de estas cosas son mejor manejadas por el IDE, no por el compilador. Eso te permite ver lo que los bits automáticos están intentando estropear para ti.

La estrategia que creo que predomina ahora es el perfeccionamiento continuo del lenguaje en lugar de aflojar el compilador: si realmente es algo que el compilador puede descubrir automáticamente, entonces introduzca una construcción de lenguaje bien definida a su alrededor.

El ejemplo inmediato que viene a la mente son las propiedades automáticas en C # (no es el único lenguaje que tiene algo similar): dado que la mayoría de los captadores / definidores en cualquier aplicación son realmente envoltorios alrededor de un campo, solo permiten al desarrollador Para indicar su intención y dejar que el compilador inyecte el resto.

Lo que luego me hace pensar: la mayoría de los lenguajes de estilo C ya lo hacen en cierta medida. Para las cosas que se pueden resolver automáticamente, simplemente refine la sintaxis:

 if (true == x)
 {
    dothis();
 }
 else
 {
    dothat();
 }

Se puede reducir a:

if (true == x)
    dothis();
else
    dothat();

Al final, creo que todo se reduce a esto: la tendencia es que no se hace el compilador "más inteligente" o "más flojo". Es el idioma que se hace más inteligente o más flexible.

Además, demasiada "ayuda" puede ser peligrosa, como el error clásico "if":

if (true == x)
    if (true == y)
       dothis();
else
    dothat();
    
respondido por el MIA 27.12.2010 - 20:46
1

Cuando estaba codificando FORTRAN y PL / I a finales de los 80 y principios de los 90 en los sistemas de minicomputadoras y mainframe de DEC y IBM, me parece recordar que los compiladores solían cerrar mensajes como "blah blah error; asumiendo que blah blah and continuo...". En aquel entonces, este era un legado de los días (incluso antes, antes de mi época) de procesamiento de lotes y tarjetas perforadas, cuando era probable que hubiera una enorme espera entre el envío de su código y la devolución de los resultados. Así que tenía mucho sentido para los compiladores hacer un intento de adivinar el programador y continuar en lugar de abortar en el primer error encontrado. Eso sí, no recuerdo que las "correcciones" fueran particularmente sofisticadas. Cuando finalmente me cambié a estaciones de trabajo Unix interactivas (Sun, SGI, etc.), noté que la característica parecía estar totalmente ausente en sus compiladores de C.

    
respondido por el timday 27.12.2010 - 17:48
0

El objetivo de un compilador es producir ejecutables que se comporten como se desea. Si un programador escribe algo que no es válido, incluso si el compilador puede con un 90% de probabilidad adivinar lo que se pretendía, generalmente sería mejor requerir que el programador arregle el programa para aclarar la intención, que hacer que el compilador siga adelante y produzca un ejecutable. lo que tendría una gran posibilidad de ocultar un error.

Por supuesto, los idiomas generalmente deben diseñarse de modo que el código que exprese claramente la intención sea legal, y el código que no exprese claramente la intención debería estar prohibido, pero eso no significa que lo sean. Considere el siguiente código [Java o C #]

const double oneTenth = 0.1;
const float  oneTenthF = 0.1f;
...
float f1 = oneTenth;
double d1 = oneTenthF;

Sería útil tener un compilador que agregue un typecast implícito para la asignación a f1 , ya que solo hay una cosa lógica que el programador podría desear que contenga f1 (el valor de float más cercano a 1/10). Sin embargo, en lugar de alentar a los compiladores a aceptar programas impropios, sería mejor para spec permitir conversiones implícitas de doble a flotante en algunos contextos. Por otro lado, la asignación a d1 puede o no ser lo que realmente pretendía el programador, pero no hay una regla de lenguaje que lo prohíba.

El peor tipo de reglas de lenguaje son aquellas en las que los compiladores harán inferencias en los casos en que algo no podría compilarse legítimamente de otra manera, pero un programa podría ser "accidentalmente" válido en un caso en el que se pretendía hacer una inferencia. Muchas situaciones que involucran el fin de la declaración implícita caen dentro de esta categoría. Si un programador que intenta escribir dos declaraciones separadas omite el terminador de una instrucción, un compilador generalmente podría inferir el límite de la declaración, pero en ocasiones podría considerar como una declaración algo que se suponía que debía procesarse como dos.

    
respondido por el supercat 22.02.2014 - 17:35
0

Los errores de sintaxis son especialmente difíciles de corregir. Tomemos el caso de un error faltando ) : Sabemos que podemos reparar el código insertando uno, pero generalmente hay muchos lugares donde podemos insertar uno y obtener un programa sintácticamente correcto.

Un punto mucho más fácil son los identificadores mal escritos (pero tenga en cuenta que no son errores de sintaxis). Uno puede calcular la distancia de edición entre el identificador no resoluble y todos los identificadores en el alcance, y reemplazando la palabra no resuelta por la que el usuario probablemente quiso decir, uno podría encontrar un programa correcto en muchos casos. Sin embargo, resulta que aún es mejor marcar el error y dejar que el IDE sugiera reemplazos válidos.

    
respondido por el Ingo 23.02.2014 - 00:29
-1

Tal compilador simplemente sería una implementación relajada y no estándar de cualquier lenguaje que esté compilando.

    
respondido por el Rei Miyasaka 27.12.2010 - 18:06
-2

Se ha intentado varias veces, pero a menudo no logró el efecto deseado: piense en HAL 9000 o GlaDOS.

    
respondido por el cbrandolino 28.12.2010 - 01:50
-3

En C, no puedes pasar matrices por valor, pero el compilador te permite escribir:

void foo(int array[10]);

que luego se reescribe silenciosamente como:

void foo(int* array);

¿Qué tan estúpido es eso? Preferiría un error difícil aquí en lugar de una reescritura silenciosa, porque esta regla especial ha llevado a muchos programadores a creer que los arreglos y los punteros son básicamente lo mismo. No lo son.

    
respondido por el fredoverflow 31.01.2011 - 20:13

Lea otras preguntas en las etiquetas