Fase sintáctica

La segunda fase del compilador, encargada de analizar la estructura del código fuente a nivel de sus reglas gramaticales. Mientras que el análisis léxico se ocupa de dividir el código en tokens, el análisis sintáctico verifica si esos tokens están organizados de acuerdo con la gramática del lenguaje. La sintaxis se refiere a las reglas que determinan cómo deben organizarse las palabras (tokens) para que formen sentencias o expresiones válidas.

El analizador sintáctico toma la secuencia de tokens generada en la fase léxica y construye una estructura jerárquica (generalmente un árbol de sintaxis abstracta o AST, por sus siglas en inglés) que representa la organización del programa según las reglas del lenguaje.En la figura 9 se muestra un diagrama del analizador sintáctico.

Figura 9. Diagrama análisis sintáctico.
Fuente:https://ricardogeek.com/analisis-sintactico-de-un-compilador/

Se muestra en la figura 9 un esquema de un compilador,pero en en el cual podemos observar la entrada de componentes léxicos al analizador sintáctico para su procesamiento.

¿Qué es una gramática?

Una gramática define las reglas que describen cómo se forman las expresiones en un lenguaje de programación. Se representa utilizando una notación llamada gramática libre de contexto (CFG, por sus siglas en inglés), que tiene una serie de producciones que definen cómo se pueden combinar los símbolos (tokens) para formar otras construcciones del lenguaje.

Por ejemplo, para un lenguaje simple que permite declarar y dibujar círculos, la gramática podría ser algo como:

Figura 10 Ejemplo de gramática.

Elementos de una gramática (figura 10):

  • Símbolos terminales: Son los tokens que no se pueden dividir más, como identificadores, números, operadores, etc.
  • Símbolos no terminales: Son representaciones de estructuras dentro del lenguaje, como declaración, expresión, programa, etc.
  • Producciones: Reglas que describen cómo un símbolo no terminal puede expandirse a otros símbolos terminales o no terminales.
  • Símbolo inicial: Es el símbolo no terminal desde el cual se empieza a derivar la cadena.

¿Cómo funciona un analizador sintáctico?

Imaginemos que tenemos un lenguaje simple para declarar figuras geométricas y dibujarlas. Las producciones podrían ser (figura 11):

Figura 11 Lenguaje figuras geométricas.

La gramática para este lenguaje de ejemplo de la figura 11 sería:

  • Un programa consiste en una declaración seguida de una lista de figuras.
  • Una declaración de figura es la palabra clave circle, seguida de un par de paréntesis que contienen una lista de argumentos (un par de identificadores y un número).
  • La lista de argumentos está formada por identificadores (como x y y) y un número (como 10).
Este lenguaje permite una declaración de un círculo como sigue:

circle(x, y, 10);
Posteriormente el analizador sintáctico procede a generar los arboles de derivación para comprobar que el código fuente concuerde con la gramática definida.

¿Qué es un Árbol Sintáctico?

Un árbol sintáctico (o árbol de derivación) es una representación gráfica de la estructura jerárquica de un programa según su gramática. Cada nodo del árbol representa una producción de la gramática, y las hojas del árbol corresponden a los tokens que forman el código fuente. El árbol muestra cómo el compilador deriva el código desde la producción inicial (la raíz del árbol) hasta los tokens finales (las hojas).

En otras palabras, el árbol sintáctico permite visualizar cómo se agrupan y organizan las partes de un programa de acuerdo con las reglas del lenguaje, ayudando a entender la estructura gramatical del código.

Basándonos en nuestra gramática y código fuente nuestro árbol de derivación quedaría así:
Figura 12 Árbol sintáctico para el código circle(x, y, 10).



Explicación figura 12:

Basándonos en la gramática y el código, el árbol sintáctico se construye de la siguiente manera:

  1. Raíz (programa): El árbol comienza con la producción inicial programa.
  2. De arriba hacia abajo:
    • El programa se descompone en una declaración y una lista de figuras.
    • La declaración corresponde a circle(...), que se descompone en la palabra clave circle, un par de paréntesis y una lista de argumentos.
    • La lista de argumentos está formada por dos identificadores (x, y) y un número (10).
  3. Hojas (tokens): Los tokens son los elementos más simples del código, como circle, x, y, 10, ;, y ).
Con lo cual tenemos y verificamos que nuestro código fuente concuerda con la gramática del lenguaje.

Manejo de errores léxicos

Si un compilador tuviera que procesar sólo programas correctos, su diseño e implantación se simplificaría mucho. Pero los programadores a menudo escriben programas incorrectos, y un buen compilador debería ayudar al programador a identificar y localizar errores. Es más, considerar desde el principio el manejo de errores puede simplificar la estructura de un compilador y mejorar su respuesta a los errores.

Los errores en la programación pueden ser de los siguientes tipos:

  • Léxicos, producidos al escribir mal un identificador, una palabra clave o un operador.
  • Sintácticos, por una expresión aritmética o paréntesis no equilibrados.
  • Semánticos, como un operador aplicado a un operando incompatible.
  • Lógicos, puede ser una llamada infinitamente recursiva.


Dejamos contenido extra para que puedan estudiar y comprender mejor el tema:


https://www.youtube.com/watch?v=F63j5rHkXls



Referencias

Cueva Lovelle, J. M. & Universidad de Oviedo. (1994). Análisis sintactico en procesadores de lenguaje. http://di002.edv.uniovi.es/. http://di002.edv.uniovi.es/~cueva/publicaciones/monografias/Cuaderno-61-Matematicas-Sintactico.pdf





Comentarios

Entradas más populares de este blog