Documentos de Académico
Documentos de Profesional
Documentos de Cultura
5 Sintáxis
5 Sintáxis
if, while
o Literales o constantes:
o Símbolos especiales:
o Identificadores:
x24 o monthly_balance
Se llaman palabras reservadas porque un identificador no puede tener la misma cadena de caracteres que una palabra
reservada.
A veces existe confusión en un lenguaje entre las palabras reservadas y los identificadores predefinidos (aquellos a los
cuales se les ha dado una interpretación inicial para todos los programas en el lenguaje, pero pueden ser capaces de redefinición,
como pueden ser integer o boolean).
En algunos lenguajes los identificadores tienen un tamaño máximo fijo, en tanto que en la mayoría de los lenguajes los
identificadores pueden tener una longitud arbitraria.
Los identificadores de longitud variable pueden presentar problemas con las palabras reservadas, esto es, el identificador
doif puede verse como un simple identificador o como dos palabras reservadas do e if. Por ello, se utiliza el principio de la
subcadena de mayor longitud o principio de trozo máximo.
Este principio es una regla estándar en la determinación de tokens, en cada punto se reúne en un solo token la cadena
más larga posible de caracteres, requiriendo que ciertos tokens vengan separados por delimitadores de tokens o
espacios en blanco.
Esto significa que doif sería tratado como un único token y por tanto un identificador.
El formato de un programa puede afectar la forma en la que se recogen los tokens:
o Formato fijo:
Los tokens deben aparecer en localizaciones preespecificadas sobre la página (FORTRAN).
(a|b)*c
A menudo, la notación de expresiones regulares se amplía mediante operaciones adicionales y caracteres especiales
como:
o [ - ] Indican rango de caracteres.
o + Indica una o más repeticiones.
o ? Indica un elemento opcional, es decir, que la expresión a la que sigue, aparece como mucho una vez:
ob?curo obscuro
oscuro
[0-9]+(\.[0-9]+)?
Una gramática libre de contexto consiste en un conjunto de reglas gramaticales, cada una de las cuales están formadas
de:
o Un lado izquierdo que es un solo nombre de estructura y a continuación el meta símbolo (a veces se
reemplaza por “:=”).
o Un lado derecho formado por una secuencia de elementos que pueden ser símbolos u otros nombres de
estructuras.
Las cursivas sirven para distinguir los nombres de las estructuras de las palabras reales, es decir, de los tokens que
pudieran aparecer en el lenguaje (sees).
La barra vertical | es también un metasímbolo y significa “o”.
Algunas veces un metasímbolo es un símbolo real en un lenguaje, en cuyo caso, es recomendable entrecomillar el
símbolo para distinguirlo del metasímbolo, o de lo contrario, el metasímbolo puede escribirse en un tipo de letra diferente.
Algunas notaciones también se apoyan en metasímbolos (<, >), en cuyo caso también se reemplaza la flecha por el
metasímbolo (::=):
Para indicar que una oración debe estar seguida por algún tipo de marcador final, se hace mediante el signo $:
entrada oración $
E=E+E N
Las soluciones a ecuaciones recursivas aparecen frecuentemente en las descripciones formales en los lenguajes de
programación donde se conocen como puntos fijos mínimos.
Expresión +
Expresión + Expresión 3 *
Dígito Dígito
3
4 5
Para el programador los árboles de sintaxis abstractas no son importantes (algunas veces la sintaxis ordinaria se distingue de
la sintaxis abstracta por el nombre de sintaxis concreta).
No ocurre así con los diseñadores del lenguaje y para los autores de traductores, ya que es la sintaxis abstracta y no la
concreta la que expresa la estructura esencial del lenguaje.
Sin embargo, diferentes derivaciones también pueden conducir a diferentes árboles de análisis gramaticales:
4 5 3 4
3+4*5 3+4*5
Una gramática para la cual sean posibles dos árboles diferentes para un mismo análisis sintáctico se dice que es
ambigua.
Ciertas derivaciones construidas en un orden especial corresponden al mismo árbol de análisis sintáctico.
Una derivación que tienes esta propiedad es la derivación por la izquierda, que consiste en tomar como reemplazo el no
terminal restante más a la izquierda.
Una forma de determinar si una gramática es ambigua es buscar dos derivaciones por la izquierda distintas de una
misma cadena.
Una gramática para que sea útil no puede ser ambigua, por lo que si lo fuera habría que aplicarle alguna regla para
eliminar dicha ambigüedad.
Para eliminar dicha ambigüedad se debe revisar la gramática o incluir nuevas reglas que eliminen la ambigüedad.
La forma más habitual de revisar este tipo de gramáticas es escribiendo una nueva regla gramatical (llamada un
“término”) que establece una “cascada de precedencia”.
Por ejemplo, la siguiente gramática es ambigua:
Algunas veces el proceso de volver a escribir una gramática para eliminar ambigüedad hace que sea extremadamente
compleja, y en estos casos preferimos enunciar una regla de no ambigüedad.
6 Longinos Recuero Bustos (http://longinox.blogspot.com)
5.5 EBNF y diagramas sintácticos
EBNF (Backus-Naur extendida) surge para dotar al BNF de una notación especial para el tipo de reglas gramaticales que
expresan con mayor claridad la naturaleza repetitiva de su estructura:
Una representación gráfica a veces es útil para una regla gramatical es el diagrama sintáctico, el cual refleja la
secuencia de terminales y no terminales que se encuentran en el lado derecho de la regla.
Estos diagramas:
o Utilizan círculos u óvalos para representar los terminales y rectángulos para representar los no terminales,
conectándolos entre sí mediante líneas y flechas con el fin de indicar la secuencia apropiada.
o Pueden condesar varias reglas gramaticales en un solo diagrama.
o Se escriben siempre partiendo de una notación EBNF, y nunca de una BNF.
o Son atractivos visualmente pero ocupan mucho espacio por lo que actualmente son poco utilizados a favor de
las notaciones EBNF y BNF.
El analizador de abajo arriba es más poderoso que el otro, por lo que es más utilizado generalmente por los
generadores de analizadores sintácticos (o compiladores de compiladores).
Un generador ampliamente utilizado es el YACC o su versión libre Bison.
Otro método más antiguo de general analizadores a partir de su gramática que resulta muy efectivo, es el análisis
sintáctico por descenso recursivo:
o El segundo error es que no hay forma de determinar que opción tomar, si expresión + término o término, por lo
tato para seguir manteniendo la asociatividad por la izquierda y eliminar la recursividad, utilizamos la notación
EBNF en la que las llaves representan la eliminación de la recursión por la izquierda:
En el caso de la recursividad por la derecha no se presenta el problema señalado anteriormente para el análisis recursivo
descendente, sin embargo se da la situación de que el código para una regla de recursión por la derecha:
Por lo tanto en situaciones de recursión por la izquierda y en la factorización por la izquierda, las reglas EBNF o los
diagramas sintácticos corresponden con el código de un analizador sintáctico por descenso recursivo, siendo esta una de
las razones de amplia utilización.
Un analizador sintáctico que basa su acción únicamente en el token disponible en el flujo de entrada, se conoce como
analizador sintáctico predictivo.
Este uso de un solo token para dirigir la acción del analizador sintáctico se conoce con el nombre preanálisis de un
solo símbolo.
Estos analizadores requieren que las gramáticas a analizar cumplan ciertas condiciones:
o La primera condición que requiere es la capacidad de escoger entre varias alternativas en una regla gramatical:
A | | |…|
Para decidir cual elegir, los tokens que inician cada tienen que ser distintos:
donde Primero es la función que devuelve el conjunto de tokens que pueden presentarse al principio de cada .
o La segunda condición se presenta con las reglas gramaticales que contienen estructuras opcionales:
Si @ se presenta como token en la entrada, pudiera ser el comienzo de una parte opcional, o pudiera ser un
token que aparece después de la expresión completa, por lo que para que esto no se de se tiene que cumplir:
Primero( ) Siguiente( ) =
El proceso de convertir reglas en gramaticales en un analizador sintáctico puede automatizarse, es decir puede
construirse un programa que traduzca un programa en un analizador sintáctico.
Estos generadores de analizadores sintácticos, es decir, “compiladores de compiladores”, toman como entrada una
versión de las reglas BNF o EBNF y dan como salida un programa de analizador sintáctico en algún lenguaje.
Dar una gramática a un generador del analizador sintáctico dará como resultado un reconocedor y para que un
analizador construya un árbol sintáctico o que lleve a cabo otras operaciones, debemos proporcionarles operaciones o
acciones a llevar a cabo asociadas a cada regla gramatical, esto es, un esquema dirigido por la sintaxis.
Uno de estos generadores más conocidos es el YACC.
de programación.
o Léxico:
3. m. Vocabulario, conjunto de las palabras de un idioma, o de las que pertenecen al uso de una región,
Una gramática libre de contexto típicamente incluye una descripción de los tokens de un lenguaje al incluir en las reglas
gramaticales las cadenas de caracteres que forman los tokens.
Algunas clases típicas de tokens, como las literales o constantes y los identificadores no son por sí mismos secuencias
fijas de caracteres, sino que se elaboran a partir de un conjunto fijo de caracteres, como los dígitos del 0 al 9.
Estas clases de tokens pueden tener su estructura definida por la gramática, sin embargo, es posible e incluso deseable
utilizar un analizador léxico para reconocer estas estructuras, pues puede hacerlo mediante una operación repetitiva
simple.
Los límites entre la sintaxis y el léxico no están claramente definidos, ya que si utilizamos la notación BNF, EBNF o
diagramas sintácticos, se pueden incluir las estructuras léxicas como parte de la descripción del lenguaje.
Se ha definido la sintaxis como todo lo que se puede definir mediante una gramática libre de contexto, y semántica como
todo lo demás que no se puede definir así.
Algunos autores incluyen como sintaxis, la declaración de variables antes de que sean utilizadas y la regla de que no se
pueden declarar identificadores dentro de un procedimiento. Estas son reglas sensibles al contexto y por lo tanto un
analizador sintáctico debería tener información sobre el contexto.
Otro conflicto es cuando un leguaje requiere que ciertas cadenas sean identificadores predefinidos y no palabras
reservadas.
La diferencia de ambos es que las palabras reservadas son cadenas fijas de caracteres, que son tokens ellas mismas y
que no pueden utilizarse como identificadores, mientras que identificadores predefinidos son cadenas fijas de caracteres
a las que se les ha dado un significado predefinido en el lenguaje, pero este significado puede ser redefinido.
Por estas razones, el analizador sintáctico debería tener información del contexto sobre los identificadores disponibles a
fin de eliminar ambigüedades.