Está en la página 1de 72

Unidad 3:

Estructuras Sintácticas
Estructura de los Lenguajes

Lic. en Ciencias Informáticas


Facultad Politécnica, Universidad Nacional de Asunción
Notas de lectura revisadas y adaptadas por los profesores:
• Prof. Derlis Zárate (dzarate@pol.una.py) • Prof. Gerardo González (jggonzalez@pol.una.py)
• Prof. Milciades Fernández (mfernandez@pol.una.py) • Prof. Saúl Zalimben (szalimben@pol.una.py)
Índice
1. Sintaxis
2. Métodos formales
3. Semántica
4. Análisis léxico
5. Análisis sintáctico
6. Parseo, parseo descendente recursivo, parseo bottom-up
7. Análisis semántico
8. Conclusiones
9. Bibliografía y referencias
Sintaxis
Sección 1
Definición de un Lenguaje de Programación
• Sintaxis: la forma o estructura de las expresiones, sentencias y
unidades de programas

Unidad 3: Estructuras Sintácticas 4


Definición de un Lenguaje de Programación
• Sintaxis: la forma o estructura de las expresiones, sentencias y
unidades de programas
• Semántica: el significado de las expresiones, sentencias y unidades de
programas

Unidad 3: Estructuras Sintácticas 5


Definición de un Lenguaje de Programación
• Sintaxis: la forma o estructura de las expresiones, sentencias y
unidades de programas
• Semántica: el significado de las expresiones, sentencias y unidades de
programas
• La sintaxis y semántica proveen la definición de un lenguaje
Esta definición es útil para los usuarios del lenguaje
• Usuarios de la definición de un lenguaje:
• Otros diseñadores de lenguajes
• Implementadores del lenguaje
• Programadores (los usuarios del lenguaje)

Unidad 3: Estructuras Sintácticas 6


Métodos formales
Sección 2
Métodos formales para describir la sintaxis: Terminología
• Un alfabeto es un conjunto de caracteres.

Unidad 3: Estructuras Sintácticas 8


Métodos formales para describir la sintaxis: Terminología
• Un alfabeto es un conjunto de caracteres.

• Una sentencia es una cadena de caracteres de algún alfabeto.

Unidad 3: Estructuras Sintácticas 9


Métodos formales para describir la sintaxis: Terminología
• Un alfabeto es un conjunto de caracteres.

• Una sentencia es una cadena de caracteres de algún alfabeto.

• Un lenguaje es un conjunto de sentencias.

Unidad 3: Estructuras Sintácticas 10


Métodos formales para describir la sintaxis: Terminología
• Un alfabeto es un conjunto de caracteres.

• Una sentencia es una cadena de caracteres de algún alfabeto.

• Un lenguaje es un conjunto de sentencias.

• Un lexema es la unidad sintáctica de nivel más bajo de un lenguaje


(ejemplo: *, sum, begin)

Unidad 3: Estructuras Sintácticas 11


Métodos formales para describir la sintaxis: Terminología
• Un alfabeto es un conjunto de caracteres.

• Una sentencia es una cadena de caracteres de algún alfabeto.

• Un lenguaje es un conjunto de sentencias.

• Un lexema es la unidad sintáctica de nivel más bajo de un lenguaje


(ejemplo: *, sum, begin)

• Un token es una categoría de lexemas (ejemplo: identificador)

Unidad 3: Estructuras Sintácticas 12


Métodos formales para describir la sintaxis
• Existen 2 opciones

• Gramáticas libres de contexto o GLC

• Backus-Naur Form o BNF

Unidad 3: Estructuras Sintácticas 13


Métodos formales para describir la sintaxis
• GLC: Gramáticas libres de contexto
• Desarrolladas por Noam Chomsky en mediados de los 50'
• Los generadores de lenguaje intentan describir la sintaxis de lenguajes
naturales.
• Definen una clase de lenguajes llamados lenguajes libres de contexto

• BNF: Backus-Naur Form (1959)


• Inventado por John Backus para describir Algol 58
• BNF es equivalente a las GLC

Unidad 3: Estructuras Sintácticas 14


Métodos formales para describir la sintaxis
• Según estos enfoques (GLC o BNF) un lenguaje está definido con su
Gramática y su Semántica

Unidad 3: Estructuras Sintácticas 15


Métodos formales para describir la sintaxis
• Según estos enfoques (GLC o BNF) un lenguaje está definido con su
Gramática y su Semántica

• La Gramática se define con un conjunto finito y no vacío de reglas


compuestas por símbolos terminales y no terminales
• Símbolos Terminales (lexemas)
• Símbolos No Terminales (tokens)
• Reglas o Producciones para generar sentencias
• Símbolo inicial

Unidad 3: Estructuras Sintácticas 16


Métodos formales para describir la sintaxis
• Fundamentos del BNF
• En BNF, se utilizan abstracciones para representar clases de estructuras sintácticas,
las cuales actúan como variables sintácticas (también llamadas símbolos terminales y
no terminales)
• Los símbolos Terminales son los lexemas o tokens
• Una regla tiene un lado izquierdo (left-hand side, LHS), el cual es un no-terminal y un
lado derecho (right-hand side, RHS), el cual es una cadena de terminales y/o no-
terminales
• Los no-terminales usualmente están encerrados entre <>
• Ejemplos:
<ident_list> → identifier | identifier, <ident_list>
<if_stmt> → if <logic_expr> then <stmt>

• Gramática: puede verse entonces como un conjunto de reglas finito y no vacío.


• Un símbolo inicial es un elemento especial de los no-terminales de una gramática

Unidad 3: Estructuras Sintácticas 17


Ejemplo de una Gramática:
<program> → <stmts>
<stmts> → <stmt> | <stmt> ; <stmts>
<stmt> → <var> = <expr>
<var> → a | b | c | d
<expr> → <term> + <term> | <term> - <term>
<term> → <var> | const
• Terminales: ; = a b c d + - const
• No Terminales: <program> <stmts> <stmt> <var> <expr> <term>
• Símbolo inicial: <program>
• Reglas: R1: <program> à <stmts> R4: <stmt> à <var> = <expr>
R2: <stmts> à <stmt> R5: <var> à a
R3: <stmts> à <stmt> ; <stmts> R6: <var> à b
R7: … R12

Unidad 3: Estructuras Sintácticas 18


BNF Extendido
• Propone más símbolos para describir reglas
escribiendo menos
• Partes opcionales son ubicadas en corchetes [ ]
<proc_call> -> ident [(<expr_list>)]
• Partes alternativas de un RHS son ubicadas entre
paréntesis y separados por barras verticales
<term> → <term> (+|-) const
• Repeticiones (0 o más) se ubican entre llaves { }
<ident> → letter {letter|digit}

Unidad 3: Estructuras Sintácticas 19


Variaciones recientes en EBNF
• RHSs alternativos se ubican en líneas
separadas
• Se usa un : en vez de =>
• Uso de opt para partes opcionales
• Uso de oneof para selecciones

Unidad 3: Estructuras Sintácticas 20


Ejemplo BNF y su equivalente en EBNF
• BNF
<expr> → <expr> + <term>
| <expr> - <term>
| <term>
<term> → <term> * <factor>
| <term> / <factor>
| <factor>
• EBNF
<expr> → <term> {(+ | -) <term>}
<term> → <factor> {(* | /) <factor>}

Unidad 3: Estructuras Sintácticas 21


Diagramas o Grafos Sintácticos
• Es una alternativa a EBNF
• Los símbolos terminales van en círculos
• Los símbolos no terminales en cuadros
• Se dibuja como un autómata finito
• Hoy en día usado más raramente

• Ejemplo de un if descripto en un grafo sintáctico:

Unidad 3: Estructuras Sintácticas 22


Semántica
Sección 3
Semántica
• La determinación del significado de las
sentencias se conoce como semántica del
lenguaje.
• Esto puede realizarse de manera
– Estática
Antes de ejecutar el programa
– Dinámica
Durante la ejecución del programa

Unidad 3: Estructuras Sintácticas 24


Análisis léxico
Sección 4
Análisis Léxico
• Los sistemas de implementación de lenguajes deben analizar el
código fuente, independientemente del enfoque de implementación
específico: traducción, compilación o enfoques híbridos.

Unidad 3: Estructuras Sintácticas 26


Análisis Léxico
• Los sistemas de implementación de lenguajes deben analizar el
código fuente, independientemente del enfoque de implementación
específico: traducción, compilación o enfoques híbridos.

• Todo el análisis léxico está basado en la descripción formal de la


sintaxis del lenguaje (BNF o GLC), es decir en su gramática.

Unidad 3: Estructuras Sintácticas 27


Análisis Léxico
• Los sistemas de implementación de lenguajes deben analizar el
código fuente, independientemente del enfoque de implementación
específico: traducción, compilación o enfoques híbridos.

• Todo el análisis léxico está basado en la descripción formal de la


sintaxis del lenguaje (BNF o GLC), es decir en su gramática.

• El análisis léxico es la etapa de la traducción que valida que todos los


caracteres utilizados en las sentencias, pertenezcan al alfabeto del
lenguaje y los asocia a tu token correspondiente.
Unidad 3: Estructuras Sintácticas 28
Análisis sintáctico
Sección 5
Análisis Sintáctico
• Todo el análisis sintáctico está basado en la descripción formal de la
sintaxis del lenguaje (BNF o GLC), es decir en su gramática.

Unidad 3: Estructuras Sintácticas 30


Análisis Sintáctico
• Todo el análisis sintáctico está basado en la descripción formal de la
sintaxis del lenguaje (BNF o GLC), es decir en su gramática.

• Mediante la notación BNF o GLC, se va describiendo el proceso del


análisis sintáctico.

Unidad 3: Estructuras Sintácticas 31


Análisis Sintáctico
• Todo el análisis sintáctico está basado en la descripción formal de la
sintaxis del lenguaje (BNF o GLC), es decir en su gramática.

• Mediante la notación BNF o GLC, se va describiendo el proceso del


análisis sintáctico.

• El análisis sintáctico es la etapa de la traducción que valida que todos


los tokens de una sentencia están respetando las reglas definidas por
la gramática del lenguaje.

Unidad 3: Estructuras Sintácticas 32


Análisis Sintáctico
• Ventajas de usar BNF para describir la sintaxis

• Provee una descripción clara y concisa de la sintaxis

• Los programas que hacen el análisis léxico y sintáctico pueden basarse


directamente en el BNF

• Los programas que hacen el análisis léxico y sintáctico basados en BNF son
fáciles de mantener

Unidad 3: Estructuras Sintácticas 33


Reglas de BNF
• Una abstracción (o símbolo no-terminal)
puede tener más de un RHS
<stmt> → <single_stmt>
| begin <stmt_list> end

Unidad 3: Estructuras Sintácticas 34


Describiendo Listas en BNF
• Las listas sintácticas se describen usando recursión
<ident_list> → ident
| ident, <ident_list>

• Una derivación es una aplicación repetida de reglas,


comenzando con el símbolo inicial y finalizando en una
sentencia (todos son símbolos terminales)

Unidad 3: Estructuras Sintácticas 35


Gramática de Ejemplo
<program> → <stmts>
<stmts> → <stmt> | <stmt> ; <stmts>
<stmt> → <var> = <expr>
<var> → a | b | c | d
<expr> → <term> + <term> | <term> - <term>
<term> → <var> | const

Unidad 3: Estructuras Sintácticas 36


Ejemplo de Derivación
<program> => <stmts> => <stmt>
=> <var> = <expr>
=> a = <expr>
=> a = <term> + <term>
=> a = <var> + <term>
=> a = b + <term>
=> a = b + const

Unidad 3: Estructuras Sintácticas 37


Derivaciones
• Cada cadena de símbolos en una derivación es una
forma sentencial.
• Una sentencia es una forma sentencial compuesta
únicamente por símbolos terminales
• Una derivación de más a la izquierda (leftmost
derivation) es una en la cual el no-terminal de más a la
izquierda en cada forma sentencial se expande
primero
• Una derivación puede ser leftmost o rightmost
Unidad 3: Estructuras Sintácticas 38
Árbol de Parseo
• Una representación jerárquica de una derivación
<program>

<stmts>

<stmt>

<var> = <expr>

a <term> + <term>

<var> const

b
Unidad 3: Estructuras Sintácticas 39
Ejemplo: Ejemplo 2:

Unidad 3: Estructuras Sintácticas 40


Árboles de Sintaxis Abstracta
• Una representación más compacta del árbol
de parseo
• Condensa el árbol a su estructura esencial,
eliminando muchas “cascadas”.

Unidad 3: Estructuras Sintácticas 41


Árboles de Sintaxis Abstracta
• Una representación más compacta del árbol de parseo
• Condensa el árbol a su estructura esencial, eliminando
muchas “cascadas”.
<program>

<stmts> =

<stmt>
a +
<var> = <expr>

a <term> + <term> const

b
<var> const
Unidad 3: Estructuras Sintácticas 42
b
Ejemplo: Ejemplo 2:

Unidad 3: Estructuras Sintácticas 43


Ejemplo: Ejemplo 2:

Note cómo se compactaron los árboles

Unidad 3: Estructuras Sintácticas 44


Ambigüedad en Gramáticas
• Una gramática es ambigua si y solo si genera una
forma sentencial que tiene 2 o más árboles de parseo

Unidad 3: Estructuras Sintácticas 45


Ejemplo de una Gramática Ambigua
<expr> → <expr> <op> <expr> | const
<op> → / | -
<expr> <expr>

<expr> <op> <expr> <expr> <op> <expr>

<expr> <op> <expr> <expr> <op> <expr>

const - const / const const - const / const

Unidad 3: Estructuras Sintácticas 46


Una gramática no ambigua
• Si usamos el árbol de parseo para indicar los
niveles de precedencia de los operadores, no
podemos tener ambigüedad
<expr> → <expr> - <term> | <term>
<term> → <term> / const| const

<expr>

<expr> - <term>

<term> <term> / const

const const
Unidad 3: Estructuras Sintácticas 47
Asociatividad de Operadores
• La asociatividad de operadores también puede ser
definida en la gramática

<expr> -> <expr> + <expr> | const (ambiguous)


<expr> -> <expr> + const | const (unambiguous)
<expr>
<expr>

<expr> + const

<expr> + const

const
Unidad 3: Estructuras Sintácticas 48
Parseo, parseo descendente
recursivo, parseo bottom-up
Sección 6
Implementación de un Análisis Sintáctico
• El análisis sintáctico es la porción del
procesamiento del lenguaje que consiste en:
– Una parte de bajo nivel llamada analizador lexico
(autómata finito basado en una gramática regular)
– Una parte de alto nivel llamada analizador sintáctico
o parser (un autómata basado en gramáticas libres
de contexto o BNF)

Unidad 3: Estructuras Sintácticas 50


Implementación de un Análisis Sintáctico
• Metas del parser, dado un programa de
entrada:
– Encontrar todos los errores sintácticos; por cada uno
de ellos, producir un diagnóstico y mensaje
apropiado
– Producir el árbol de parseo, o al menos, una traza
del árbol de parseo para el programa

Unidad 3: Estructuras Sintácticas 51


Implementación de un Análisis Sintáctico
• Los lexers y parsers pueden ser generados
automáticamente mediante herramientas
como Lex y Yacc
– Lex (Lesk, 1975)
– Yacc (Johnson, 1975)
• Hay versiones más modernas Gnu Bison y
Flex ("Fast lex").

Unidad 3: Estructuras Sintácticas 52


Implementación de un Análisis Sintáctico
• Existen 2 categorías de parsers
– Top down – produce el árbol de parseo a partir de la
raíz para abajo.
• El orden es de un leftmost derivation
• Se construye el árbol en preorder
– Bottom up - produce el árbol de parseo, comenzando
desde las hojas
• El orden es el de un rightmost derivation
• Los parsers útiles miran únicamente un token
adelante en la entrada (minimiza las pasadas
sobre el fuente)
Unidad 3: Estructuras Sintácticas 53
Implementación de un Análisis Sintáctico
• Gramática:
expr → term { + term }
term → factor { ∗ factor }
factor → ( expr ) | number
• El ejemplo completo está en el libro de Louden
Ejemplo parser
recursivo factor()
descendente expr() { if (token == ‘(‘)
{ term(); { match(token);
while (token == ‘+’) expr();
{ match(token); match(‘)’);
term(); }
} else number();
Unidad 3: Estructuras Sintácticas } } 54
Análisis semántico
Sección 7
Análisis Semántico
• La determinación del significado de las sentencias se puede realizar
de manera
• Estática: antes de ejecutar el programa
• Dinámica: durante la ejecución del programa

• A continuación mencionaremos algunas de las técnicas de análisis


semántico.
En la práctica, la semántica puede estar especificada mediante
atributos extra de la gramática (gramática con atributos), o mediante
especificaciones técnicas adicionales y complementarias
Unidad 3: Estructuras Sintácticas 56
Semántica Estática
• Se intenta determinar el significado de las
sentencias de manera estática.

Unidad 3: Estructuras Sintácticas 57


Semántica Estática
• Se intenta determinar el significado de las
sentencias de manera estática.
• Se utilizan gramáticas con atributos para ésta
tarea.
• Una gramática con atributos es una gramática
que tiene atributos extra para indicar
información semántica en sus árboles de
parseo.

Unidad 3: Estructuras Sintácticas 58


Semántica Dinámica
• Se intenta determinar el significado de las
sentencias de manera dinámica.

Unidad 3: Estructuras Sintácticas 59


Semántica Dinámica
• Se intenta determinar el significado de las
sentencias de manera dinámica.
• No hay una notación o formalismo aceptado
ampliamente para describir la semántica. Los
más usados:
– Semántica Operacional
– Semántica Axiomática
– Semántica Denotacional

Unidad 3: Estructuras Sintácticas 60


Semántica Operacional
• Describe el significado de un programa
mediante la ejecución de sus sentencias en una
máquina (simulada o real).
• El cambio en el estado de la máquina
(memoria, registros, etc.) define el significado
de la sentencia
• Muy costoso e ineficiente en la mayoría de los
casos.

Unidad 3: Estructuras Sintácticas 61


Semántica Denotacional
• Basado en la teoría de funciones recursivas. Es
el método de descripción más abstracto.
• El proceso consiste en:
– Definir un objeto matemático por cada entidad del
lenguaje
– Definir una función que mapee instancias de las
entidades del lenguaje en instancias de los
correspondientes objetos matemáticos

Unidad 3: Estructuras Sintácticas 62


Semántica Axiomática
• Basado en lógica formal (cálculo de predicados)
• Propósito original: verificación formal de
programas
• Se definen axiomas o reglas de inferencia por
cada sentencia del lenguaje. A esto se le
conoce como aserciones.
• Se establecen aserciones como pre o post
condiciones que determinan el significado de la
sentencia

Unidad 3: Estructuras Sintácticas 63


Semántica dirigida por la sintaxis

• El árbol de parseo y el árbol de sintaxis


abstracta deben tener una estructura que
reflejen la computación a ser realizada.

Unidad 3: Estructuras Sintácticas 64


Ejemplo 1 Árbol de Parseo Árbol Sintáctico

Unidad 3: Estructuras Sintácticas 65


Ejemplo 2 Árbol de Parseo
Árbol Sintáctico

Unidad 3: Estructuras Sintácticas 66


Conclusiones
Sección 8
Conclusiones
• Un lenguaje de programación puede verse como un conjunto de sentencias, compuestas
a su vez por lexemas y tokens
• Se utiliza las GLC o BNF como formalismo para definir la gramática de un lenguaje de
programación
• La definición formal de una gramática es esencial para las etapas de traducción de
código hacia el código binario ejecutable
• El análisis léxico determina si todos los lexemas pertenecen al alfabeto del lenguaje y
asocia cada lexema con su token equivalente
• El análisis sintáctico determina si todos los tokens respetan las reglas de la gramática,
para ello se utiliza un parser, que emula el proceso de derivación y/o de construcción de
un árbol de análisis sintáctico.
El parser puede ser top-down o bottom-up.
• El análisis semántico determina el significado de una sentencia.

Unidad 3: Estructuras Sintácticas 68


Bibliografía y referencias
Sección 9
Bibliografía y referencias adicionales
El contenido de estas notas de lectura está basado en los libros de textos oficiales de la materia:
• Lenguajes de Programación, principios y prácticas. Kenneth C. Louden.
Ed. Thompson, 2da Edición. Capítulo 4
• Concepts of Programming Languages. Robert W. Sebesta.
Ed. Addison Wesley, 5ta Edición. Capítulos 3 y 4.

Y fue adaptado por los profesores:


• Derlis Zárate (dzarate@pol.una.py)
• Juan Gerardo González (jggonzalez@pol.una.py)
• Milciades Ramón Fernández González (mfernandez@pol.una.py)
• Saúl Zalimben (szalimben@pol.una.py)

Unidad 3: Estructuras Sintácticas 70


¿Consultas? ¿Dudas?
Puedes escribir tus consultas o dudas en
el Foro de la Unidad 3, que estaremos
respondiendo entre todos.

Unidad 3: Estructuras Sintácticas 71


Unidad 3: Estructuras Sintácticas
Fin de la presentación

También podría gustarte