stringtranslate.com

colgando más

El else colgante es un problema en la programación de generadores de analizadores sintácticos en el que una cláusula else opcional en una declaración if-then(-else) da como resultado que los condicionales anidados sean ambiguos. Formalmente, la gramática libre de contexto de referencia del lenguaje es ambigua , lo que significa que hay más de un árbol de análisis correcto .

En muchos lenguajes de programación se puede escribir código ejecutado condicionalmente en dos formas: la forma si-entonces y la forma si-entonces-else; la cláusula else es opcional:

si a entonces s si b entonces s1 si no s2

Esto da lugar a una ambigüedad en la interpretación cuando hay declaraciones anidadas, específicamente cuando aparece una forma si-entonces como s1si-entonces-si no:

si a entonces  si b entonces s si no s2

En este ejemplo, sse ejecuta sin ambigüedades cuando aes verdadero y bes verdadero, pero se puede interpretar s2como ejecutado cuando aes falso (adjuntando así el else al primer if) o cuando aes verdadero y bes falso (adjuntando así el else al segundo if). ). En otras palabras, uno puede ver la afirmación anterior como cualquiera de las siguientes expresiones:

si a entonces ( si b entonces s) más s2 si a entonces ( si b entonces s más s2)

El problema de los demás pendientes data de ALGOL 60 , [1] y se ha resuelto de varias maneras en idiomas posteriores. En los analizadores LR , el else colgante es el ejemplo arquetípico de un conflicto de cambio-reducción .

Evitar la ambigüedad manteniendo la sintaxis.

Este es un problema que surge a menudo en la construcción de compiladores , especialmente en el análisis sin escáner . La convención cuando se trata del else colgante es adjuntar el else a la declaración if cercana, [2] permitiendo gramáticas inequívocas y libres de contexto, en particular. Los lenguajes de programación como Pascal, [3] C [4] y Java [5] siguen esta convención, por lo que no hay ambigüedad en la semántica del lenguaje , aunque el uso de un generador de analizador puede dar lugar a gramáticas ambiguas . En estos casos, la agrupación alternativa se logra mediante bloques explícitos, como begin...enden Pascal [6] y {...}en C.

Dependiendo del enfoque de construcción del compilador, se pueden tomar diferentes acciones correctivas para evitar ambigüedades:

Evitar la ambigüedad cambiando la sintaxis

El problema también se puede resolver haciendo explícito el vínculo entre un else y su if, dentro de la sintaxis. Esto suele ayudar a evitar errores humanos. [7]

Las posibles soluciones son:

Ejemplos

A continuación se presentan ejemplos concretos.

C

En C , la gramática dice, en parte:

declaración =... | declaración de selección declaración-de-selección = ... | Declaración IF (expresión) | Declaración IF (expresión) Declaración ELSE

Así, sin más reglas, la declaración

si ( a ) si ( b ) s ; más s2 ;      

podría analizarse ambiguamente como si fuera:

si ( a ) { si ( b ) s ; más s2 ; }      

o:

si ( a ) { si ( b ) s ; } más s2 ;     

En la práctica, en C se elige el primer árbol, asociando el elsecon el más cercano if.

Evitar el conflicto en los analizadores LR

El ejemplo anterior podría reescribirse de la siguiente manera para eliminar la ambigüedad:

declaración: declaración_abierta | declaración_cerrada  ;open_statement: Declaración IF '(' expresión ')' | IF '(' expresión ')' declaración_cerrada ELSE declaración_abierta  ;declaración_cerrada: declaración_no_si | IF '(' expresión ')' declaración_cerrada ELSE declaración_cerrada  ;declaración_no_si: ...  ;

Es posible que también sea necesario duplicar de esta manera otras reglas gramaticales relacionadas con declaraciones si pueden terminar directa o indirectamente con a statemento selection-statementno terminal.

Sin embargo, damos gramática que incluye declaraciones if y while.

declaración: declaración_abierta | declaración_cerrada  ;open_statement: Declaración IF '(' expresión ')' | IF '(' expresión ')' declaración_cerrada ELSE declaración_abierta | MIENTRAS '(' expresión ')' declaración_abierta  ;declaración_cerrada: declaración_simple | IF '(' expresión ')' declaración_cerrada ELSE declaración_cerrada | MIENTRAS '(' expresión ')' declaración_cerrada  ;declaración_simple: ...  ;

Finalmente, damos la gramática que prohíbe declaraciones IF ambiguas.

declaración: declaración_abierta | declaración_cerrada  ;declaración_abierta: IF '(' expresión ')' declaración_cerrada | IF '(' expresión ')' declaración_abierta | IF '(' expresión ')' declaración_cerrada ELSE declaración_abierta | MIENTRAS '(' expresión ')' declaración_abierta  ;declaración_cerrada: declaración_simple | IF '(' expresión ')' declaración_cerrada ELSE declaración_cerrada | MIENTRAS '(' expresión ')' declaración_cerrada  ;declaración_simple: ...  ;

Con esta gramática el enunciado if (a) if (b) c else dsólo puede analizarse de una manera, porque la otra interpretación ( if (a) {if (b) c} else d) se produce como

declaracióndeclaración_abiertaIF '(' expresión ')' declaración_cerrada ELSE declaración_abierta'si' '(' 'a' ')' declaración_cerrada 'de lo contrario' 'd'

y luego el análisis falla al intentar hacer coincidir closed_statement"si (b) c". Un intento closed_statementfalla de la misma manera. El otro análisis, if (a) {if (b) c else d}) tiene éxito:

declaracióndeclaración_abiertaIF '(' expresión ')' declaración_cerradaIF '(' a ')' (IF '(' expresión ')' declaración_cerrada ELSE declaración_cerrada)SI '(' a ')' (SI '(' b ')' c ELSE 'd')

Ver también

Referencias

  1. ^ Abrahams, PW (1966). "Una solución final al resto de ALGOL 60 y lenguajes relacionados". Comunicaciones de la ACM . 9 (9): 679–682. doi : 10.1145/365813.365821 . S2CID  6777841.
  2. ^ ab "5.2 Cambiar/Reducir conflictos". Bisonte 3.7.6 . Consultado el 7 de agosto de 2021 . {{cite book}}: |website=ignorado ( ayuda )
  3. ^ ISO 7185:1990 (Pascal) 6.8.3.4: Una declaración if sin una parte else no irá seguida inmediatamente por el token else.
  4. ^ ISO 9899:1999 (C): 6.8.4.1(3): "Un else está asociado con el precedente léxico más cercano si la sintaxis lo permite.", disponible en WG14 N1256, p. 134
  5. ^ "Declaraciones de la especificación del lenguaje Java, edición Java SE 9, 14.5".
  6. ^ Dale, Nell B.; Weems, Chip (noviembre de 1996). "Colgando más". Introducción a Pascal y el diseño estructurado. Aprendizaje de Jones y Bartlett. págs. 160-161. ISBN 9780763703974.
  7. ^ Ambigüedad de colgar otra cosa: las gramáticas no libres de contexto son semánticamente opacas
  8. ^ 4.5.1 Declaraciones condicionales: sintaxis en P. Nauer (ed.), Informe revisado sobre el lenguaje algorítmico ALGOL 60 , CACM 6,1, 1963 págs.
  9. ^ Ambigüedad de colgar else: requiere llaves cuando else sigue si
  10. ^ Davie, Antonio JT; Ronald Morrison (1981), Brian Meek (ed.), Recursive Descent Compiling , serie de Ellis Horwood sobre computadoras y sus aplicaciones, Chichester, West Sussex: Ellis Horwood, p. 20, ISBN 0-470-27270-8