Un compilador se organiza en dos etapas: análisis (front-end) y síntesis (back-end). Estas se subdividen en fases: análisis léxico, análisis sintáctico, análisis semántico, generación de código intermedio, optimización de código y generación de código objeto (Aho, Lam, Sethi y Ullman, "Libro del Dragón").
El análisis léxico (scanner) agrupa los caracteres de la entrada en componentes léxicos o tokens mediante expresiones regulares y autómatas finitos; herramientas clásicas: Lex/Flex. El análisis sintáctico (parser) verifica que la secuencia de tokens cumpla una gramática libre de contexto y construye el árbol de análisis, ya sea de forma descendente (LL, top-down) o ascendente (LR/SLR/LALR, bottom-up); herramientas: Yacc/Bison.
Las gramáticas libres de contexto se describen con la notación BNF (Backus-Naur Form), metasintaxis que se hizo famosa al definir formalmente ALGOL 60. Sus metasímbolos son ::= (se define como), | (alternativa) y <...> para encerrar los no terminales. Una gramática es ambigua cuando alguna cadena admite más de un árbol de derivación (o más de una derivación por la izquierda).
Los modelos de máquina se ordenan según la jerarquía de Chomsky (Tipos 0 a 3):
Las expresiones regulares combinan unión, concatenación y estrella de Kleene, con precedencia de mayor a menor: estrella (*), concatenación y unión. El lema del bombeo es una condición necesaria de los lenguajes regulares y sirve para demostrar que un lenguaje NO es regular.
En una tabla de transición, cada fila es un estado y cada columna un símbolo del alfabeto; el estado inicial se marca con → y los de aceptación con *. La cadena se acepta si, partiendo de q0 y consumiendo toda la entrada, el autómata termina en un estado de F.
Sobre decidibilidad, el problema de la parada es indecidible (Turing, 1936). Conceptualmente, la clase P reúne los problemas resolubles en tiempo polinómico; NP, los verificables en tiempo polinómico; y los NP-completos son los más difíciles de NP.
1. ¿Cuál es la primera fase de la etapa de análisis de un compilador, encargada de agrupar los caracteres de la entrada en tokens (componentes elementales del programa fuente)?
El análisis léxico (scanner) es la primera fase del front-end y agrupa los caracteres en tokens; el análisis sintáctico y semántico operan después, sobre esos tokens. (Aho, Lam, Sethi, Ullman, Compiladores: principios, técnicas y herramientas, 2a ed., cap. 1.)
2. En la fase de análisis léxico de un compilador, ¿qué formalismo se emplea típicamente para especificar los patrones que definen cada tipo de token?
El análisis léxico usa expresiones regulares (implementadas mediante autómatas finitos) para reconocer patrones de tokens; las gramáticas libres de contexto se usan en la fase sintáctica. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 3.)
3. ¿Qué fase de un compilador verifica que la secuencia de tokens producida por el analizador léxico cumpla las reglas de una gramática libre de contexto y construye el árbol de análisis (parse tree)?
El análisis sintáctico (parser) recibe los tokens y construye el árbol de análisis conforme a una gramática libre de contexto; el léxico solo produce tokens y el semántico revisa significado, no estructura. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 4.)
4. Un programa escrito en un lenguaje fuertemente tipado intenta sumar directamente un valor entero con una cadena de texto, sin ninguna conversión explícita, y el compilador reporta un error de incompatibilidad de tipos. ¿En qué fase del compilador se detecta este error?
La verificación de tipos es tarea del análisis semántico, que revisa el significado de construcciones ya validadas sintácticamente; el léxico y el sintáctico solo revisan tokens y estructura gramatical. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 1.)
5. Un analizador sintáctico construye el árbol de derivación partiendo del símbolo inicial de la gramática y expandiéndolo hacia los tokens de la entrada, como hacen los analizadores de tipo LL. Este método de análisis se clasifica como:
Los analizadores LL parten del símbolo inicial y expanden hacia abajo, por lo que se llaman descendentes; los analizadores LR/SLR/LALR parten de los tokens y reducen hacia el símbolo inicial (ascendentes). (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 4.)
6. ¿Cuál de las siguientes es una herramienta clásica utilizada para generar analizadores léxicos a partir de expresiones regulares?
Lex y su variante Flex generan analizadores léxicos a partir de expresiones regulares; Yacc/Bison y ANTLR generan analizadores sintácticos, y LLVM es una infraestructura para generación y optimización de código. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 3.)
7. Una gramática libre de contexto es ambigua: existe al menos una cadena que admite dos árboles de derivación distintos. ¿Qué consecuencia práctica tiene esta ambigüedad para el diseño de un analizador sintáctico determinista, como uno de tipo LL o LR?
La ambigüedad impide que un analizador determinista elija una única derivación, generando conflictos de análisis; esto no afecta al analizador léxico ni cambia el tipo de la gramática en la jerarquía de Chomsky. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 4.)
8. ¿Cuál de las siguientes fases forma parte de la etapa de síntesis (back-end) de un compilador, y no de la etapa de análisis (front-end)?
La generación de código objeto pertenece a la etapa de síntesis (back-end), que traduce la representación intermedia a código máquina; el análisis léxico, sintáctico y semántico forman la etapa de análisis (front-end). (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 1.)
9. ¿Cuál de las siguientes actividades NO es una fase reconocida de un compilador dentro del modelo clásico de análisis y síntesis?
La recolección de basura es una actividad del entorno de ejecución (runtime), no una fase del compilador; el análisis léxico, semántico y la generación de código intermedio sí son fases reconocidas del modelo clásico. (Aho, Lam, Sethi, Ullman, Compiladores, 2a ed., cap. 1.)
10. ¿Cómo se define formalmente un autómata finito determinista (AFD)?
Un AFD se define como la 5-tupla (Q, Σ, δ, q0, F): estados, alfabeto, función de transición, estado inicial y estados de aceptación; la 7-tupla con Γ y Z0 corresponde a un autómata de pila. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory, Languages, and Computation, 3a ed., cap. 2.)
11. Un AFD reconoce las cadenas binarias con un número par de unos. Tiene dos estados: q0 (inicial y de aceptación, número par de unos leídos) y q1 (número impar de unos leídos). Su tabla de transición es: δ(q0,0)=q0, δ(q0,1)=q1, δ(q1,0)=q1, δ(q1,1)=q0. ¿Cuál de las siguientes cadenas es aceptada por este autómata?
La cadena 1001 contiene exactamente dos unos (número par), por lo que el autómata termina en q0 y acepta; las otras tres cadenas contienen tres unos (número impar) y terminan en q1, sin ser aceptadas. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2 (tabla de transición de un AFD).)
12. ¿Cuál es la diferencia formal entre la función de transición de un AFD y la de un AFN?
La diferencia formal está en el codominio de δ: el AFD mapea a un único estado (Q) y el AFN a un subconjunto de estados (P(Q)), incluyendo transiciones ε; el alfabeto y el tamaño de F no distinguen a ambos modelos. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2.)
13. Un AFD tiene estados {q0, q1, q2}, alfabeto {0, 1}, estado inicial q0 y único estado de aceptación q2. Su tabla de transición es: δ(q0,0)=q1, δ(q0,1)=q0, δ(q1,0)=q2, δ(q1,1)=q0, δ(q2,0)=q2, δ(q2,1)=q2. ¿Cuál de las siguientes cadenas es aceptada por este autómata?
Con la cadena 100 el autómata recorre q0→q0→q1→q2, terminando en el estado de aceptación q2 (reconoce cadenas que contienen la subcadena 00); las otras tres cadenas terminan en q0 o q1, sin ser aceptadas. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2 (simulación sobre tabla de transición).)
14. Se tiene un AFN con 4 estados. Al aplicarle el algoritmo de construcción de subconjuntos (subset construction) para obtener un AFD equivalente, ¿cuál es el número MÁXIMO de estados que puede tener el AFD resultante?
El teorema de la construcción de subconjuntos garantiza que un AFN de n estados produce un AFD de a lo sumo 2^n estados; con n=4 el máximo es 2^4=16, no una simple duplicación (8) ni el mismo número de estados (4). (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2 (teorema de subconjuntos).)
15. Según el teorema de Kleene, ¿cuáles de los siguientes formalismos son equivalentes entre sí en poder expresivo?
El teorema de Kleene establece la equivalencia entre autómatas finitos, expresiones regulares y gramáticas regulares (Tipo 3); el autómata de pila corresponde a las gramáticas libres de contexto (Tipo 2), un nivel distinto de la jerarquía. (Kleene (1956); Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 3.)
16. En una tabla de transición de un autómata finito escrita en forma de texto, ¿qué convención se usa habitualmente para señalar el estado inicial?
Por convención, el estado inicial se marca con una flecha (->) y los estados de aceptación con un asterisco (*); el círculo doble es una convención de los diagramas de estados, no de las tablas. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2.)
17. Un AFN tiene, desde el estado q0 y con el símbolo 'a', transiciones simultáneas hacia q1 y hacia q2. ¿Qué algoritmo permite convertir este AFN en un AFD equivalente que reconozca exactamente el mismo lenguaje?
La construcción de subconjuntos convierte cualquier AFN en un AFD equivalente tratando cada subconjunto de estados alcanzables como un estado del AFD; el lema del bombeo sirve para probar que un lenguaje no es regular, y la eliminación de recursividad izquierda y la factorización por la izquierda son técnicas para preparar gramáticas para el análisis LL, no para convertir autómatas. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2.)
18. En la tabla de transición de un autómata finito, ¿qué representan, respectivamente, cada fila y cada columna?
En la representación estándar de la función δ como tabla, cada fila representa un estado del conjunto Q y cada columna un símbolo del alfabeto Σ, con la celda indicando el estado siguiente. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 2.)
19. Según la jerarquía de Chomsky, ¿qué modelo de máquina reconoce exactamente los lenguajes de Tipo 3 (regulares)?
En la jerarquía de Chomsky, los lenguajes regulares (Tipo 3) son reconocidos exactamente por autómatas finitos; el autómata de pila corresponde al Tipo 2, el linealmente acotado al Tipo 1 y la máquina de Turing al Tipo 0. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. sobre la jerarquía de Chomsky.)
20. ¿Qué modelo de máquina de la jerarquía de Chomsky reconoce exactamente los lenguajes libres de contexto (Tipo 2)?
Los lenguajes libres de contexto (Tipo 2) son reconocidos exactamente por autómatas de pila (no deterministas); el autómata finito corresponde al Tipo 3 y el linealmente acotado al Tipo 1. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 6.)
21. ¿Qué modelo de máquina corresponde, dentro de la jerarquía de Chomsky, a los lenguajes sensibles al contexto (Tipo 1)?
Los lenguajes sensibles al contexto (Tipo 1) son reconocidos por el autómata linealmente acotado, una máquina de Turing cuya cinta está limitada al tamaño de la entrada; el autómata de pila y el finito corresponden a niveles menos potentes, y la máquina de Turing sin restricciones al Tipo 0. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. sobre la jerarquía de Chomsky.)
22. ¿A qué tipo de lenguajes de la jerarquía de Chomsky corresponden los reconocidos por una máquina de Turing sin restricciones (Tipo 0)?
El Tipo 0 de la jerarquía de Chomsky corresponde a los lenguajes recursivamente enumerables, reconocidos por una máquina de Turing sin restricciones; los otros tipos corresponden a modelos más restringidos. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. sobre la jerarquía de Chomsky.)
23. Considera la siguiente definición en notación BNF: <digito> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 ; <numero> ::= <digito> | <digito><numero>. ¿A qué tipo de la jerarquía de Chomsky corresponde el lenguaje generado por esta gramática (secuencias de uno o más dígitos)?
El lenguaje generado son las cadenas de uno o más dígitos ([0-9]+), que es regular (Tipo 3); aunque la producción <numero> ::= <digito><numero> incluya el no terminal <digito>, este deriva un solo terminal, por lo que la gramática equivale a una lineal por la derecha. (Naur (ed.), Report on the Algorithmic Language ALGOL 60; Hopcroft, Motwani, Ullman, jerarquía de Chomsky.)
24. Se quiere demostrar que el lenguaje L = { aⁿbⁿ : n ≥ 0 } NO es un lenguaje regular. ¿Qué herramienta formal es la adecuada para construir esta demostración?
El lema del bombeo es una condición necesaria de los lenguajes regulares y se usa para probar, por contradicción, que un lenguaje dado no es regular; la construcción de subconjuntos convierte AFN en AFD y el teorema de Kleene establece equivalencias entre formalismos regulares, sin servir para demostrar no regularidad. (Hopcroft, Motwani, Ullman, Introduction to Automata Theory..., cap. 4.)
25. En la notación BNF (Backus-Naur Form), empleada en la definición formal de ALGOL 60, ¿qué representa el metasímbolo '::='?
El metasímbolo '::=' introduce la regla de producción, indicando que el no terminal de la izquierda 'se define como' la expresión de la derecha; la alternancia se expresa con el metasímbolo '|', no con '::='. (Naur (ed.), Report on the Algorithmic Language ALGOL 60 (1960/1963).)
26. En la notación BNF (Backus-Naur Form) utilizada para describir gramáticas libres de contexto, el metasímbolo ::= que aparece en una producción significa...
En BNF, ::= indica que el no terminal de la izquierda se define por la expresión de la derecha; la alternativa se expresa con el símbolo |, no con ::=. (Naur (ed.), "Report on the Algorithmic Language ALGOL 60" (1960/1963).)
27. La notación BNF se popularizó en la teoría de lenguajes de programación porque se utilizó para especificar formalmente la sintaxis de...
El informe sobre ALGOL 60, editado por Peter Naur, popularizó la notación BNF para describir formalmente la gramática libre de contexto del lenguaje. (Naur (ed.), "Report on the Algorithmic Language ALGOL 60" (1960/1963).)
28. En una gramática escrita en BNF, un símbolo encerrado entre los metasímbolos < y > representa...
Los metasímbolos < y > encierran no terminales, es decir, símbolos que aún deben expandirse mediante producciones hasta llegar a terminales. (Naur (ed.), "Report on the Algorithmic Language ALGOL 60" (1960/1963).)
29. Un compilador utiliza la gramática E ::= E + E | E * E | id sin ninguna regla de precedencia. Al analizar la cadena 'id + id * id', el equipo de desarrollo detecta que...
La cadena puede derivarse agrupando primero la suma o primero la multiplicación, generando dos árboles distintos; este es el problema clásico de ambigüedad que se resuelve con reglas de precedencia. (Aho, Lam, Sethi, Ullman, "Compiladores: principios, técnicas y herramientas" (Libro del Dragón), 2a ed., cap. 4.)
30. Se dice que una gramática libre de contexto es ambigua cuando...
La definición estándar de ambigüedad exige la existencia de al menos una cadena con dos o más árboles de derivación distintos, no simplemente producciones con varios no terminales. (Aho, Lam, Sethi, Ullman, "Compiladores" (Libro del Dragón), 2a ed., cap. 4.)
31. Dentro de la jerarquía de Chomsky, las gramáticas que se escriben típicamente en notación BNF, con producciones de la forma A -> α donde A es un único no terminal y α una cadena cualquiera de terminales y no terminales, corresponden al...
Tener un único no terminal a la izquierda y una parte derecha sin restricciones define a las gramáticas libres de contexto (Tipo 2), reconocidas por autómatas de pila; el Tipo 3 (regular) impone además restricciones a la parte derecha. (Hopcroft, Motwani, Ullman, "Introduction to Automata Theory, Languages, and Computation", 3a ed.)
32. Un desarrollador construye un compilador y necesita verificar que la secuencia de tokens entregada por el analizador léxico cumpla las reglas de la gramática escrita en BNF, además de construir el árbol de análisis correspondiente. Esta tarea corresponde a la fase de...
El análisis sintáctico (parser) usa la gramática libre de contexto para validar la secuencia de tokens y construir el árbol de análisis; el análisis léxico solo agrupa caracteres en tokens. (Aho, Lam, Sethi, Ullman, "Compiladores" (Libro del Dragón), 2a ed., cap. 1 y 4.)
33. Un analizador sintáctico construye el árbol de derivación comenzando desde el símbolo inicial de la gramática y expandiendo las producciones hacia los símbolos terminales, en vez de partir de la cadena de entrada y reducirla hasta el símbolo inicial. Este analizador se clasifica como...
LL construye el árbol desde el símbolo inicial hacia las hojas (descendente); LALR, SLR y LR son variantes ascendentes que parten de la cadena y reducen hasta el símbolo inicial. (Aho, Lam, Sethi, Ullman, "Compiladores" (Libro del Dragón), 2a ed., cap. 4.)
34. Un equipo de desarrollo ya escribió la gramática de su lenguaje en notación similar a BNF y quiere generar automáticamente el analizador sintáctico correspondiente. La herramienta clásica para esta tarea es...
Yacc/Bison generan analizadores sintácticos a partir de gramáticas tipo BNF; Lex/Flex generan analizadores léxicos a partir de expresiones regulares, no de gramáticas. (Aho, Lam, Sethi, Ullman, "Compiladores" (Libro del Dragón), 2a ed., cap. 4.)
35. Un autómata finito determinista (AFD) se define formalmente como la 5-tupla (Q, Σ, δ, q0, F). En esta definición, F representa...
F es el conjunto de estados finales o de aceptación; Σ es el alfabeto, δ la función de transición y q0 el estado inicial, cada uno un componente distinto de la 5-tupla. (Hopcroft, Motwani, Ullman, "Introduction to Automata Theory...", cap. 2.)