En matemáticas, lógica y ciencias de la computación, un lenguaje
formal es un lenguaje cuyos símbolos son primitivos y las reglas para unir esos símbolos están formalmente especificadas. 12 Al conjunto de los símbolos primitivos se le llama el alfabeto (o vocabulario) del lenguaje, y al conjunto de las reglas se le llama la gramática formal (o sintaxis). A una cadena de símbolos formada de acuerdo a la gramática se le llama una fórmula bien formada (o palabra) del lenguaje. Estrictamente hablando, un lenguaje formal es idéntico al conjunto de todas sus fórmulas bien formadas.
Expresiones regulares
Una expresión regular es una cadena de caracteres que es utilizada
para describir o encontrar patrones dentro de otros strings, en base al uso de delimitadores y ciertas reglas de sintaxis. La mayoría de los programadores no se dan el tiempo de aprender a aplicar las expresiones regulares, lo cual es una lástima ya que son de gran utilidad. Cuando aprendas a aplicar las expresiones regulares, te darás cuenta de lo poderosas que son, la gran cantidad de problemas que pueden resolver, y lo mucho que aumentará tu productividad al programar. Si es la primera vez que te acercas al concepto de expresiones regulares –también conocidas como “regex” en el argot de la programación– te animará saber que muy probablemente ya las has usado aún sin saberlo, al menos en su vertiente más básica. Por ejemplo, el comando dir *.txt para obtener un listado de todos los archivos con extensión txt es una forma muy sencilla de expresión regular, donde el patrón * coincide con cualquier cadena de caracteres. Autómatas Finitos (AFN y AFD) Un autómata finito es un modelo matemático de una máquina que acepta cadenas de un lenguaje definido sobre un alfabeto A. Consiste en un conjunto finito de estados y un conjunto de transiciones entre esos estados, que dependen de los símbolos de la cadena de entrada. El autómata finito acepta una cadena x si la secuencia de transiciones correspondientes a los símbolos de x conduce desde el estado inicial a un estado final. Si para todo estado del autómata existe como máximo una transición definida para cada símbolo del alfabeto, se dice que el autómata es determinístico (AFD). Si a partir de algún estado y para el mismo símbolo de entrada, se definen dos o más transiciones se dice que el autómata es no determinístico (AFND). Formalmente un autómata finito se define como una 5-upla M = donde E: conjunto finito de estados A: alfabeto o conjunto finito de símbolos de entrada δ: función de transición de estados, que se define como - δ: E x A → E si el autómata es determinístico - δ: E x A → P(E) si el autómata es no determinístico (P(E) es el conjunto potencia de E, es decir el conjunto de todos los subconjuntos de E) e0: estado inicial; e0 ∈ E F: conjunto de estados finales o estados de aceptación; F ⊆ E Generalmente se asocia con cada autómata un grafo dirigido, llamado diagrama de transición de estados. Cada nodo del grafo corresponde a un estado. El estado inicial se indica mediante una flecha que no tiene nodo origen. Los estados finales se representan con un círculo doble. Si existe una transición del estado ei al estado ej para un símbolo de entrada a, existe entonces un arco rotulado a desde el nodo ei al nodo ej; es decir que δ(ei , a) = ej , se representa en el diagrama. Expresiones regulares y autómatas Las expresiones regulares están estrechamente relacionadas con los autómatas finitos no deterministas y pueden considerarse una alternativa, que el usuario puede comprender fácilmente, a la notación de los AFN para describir componentes de software. Por tanto, las expresiones regulares sirven como lenguaje de entrada de muchos sistemas que procesan cadenas. Algunos ejemplos son los siguientes:
Comandos de búsqueda tales como el comando grep de UNIX o
comandos equivalentes para localizar cadenas en los exploradores web o en los sistemas de formateo de texto. Generadores de analizadores léxicos, como Lex o Flex. Recuerde que un analizador léxico es el componente de un compilador que divide el programa fuente en unidades lógicas o sintácticas formadas por uno o más caracteres que tienen un significado.
Transformación AFND/AFD
Transformación de autómata finito no determinista a autómata finito
determinista. Todo AFND estricto, o sea un AFND que no es AFND-V, puede ser transformado a AFD utilizando un algoritmo que transforma los estados del AFND en nuevos estados que son subconjuntos de los estados originales y aplica a los mismos la clausura para confirmar la conexidad entre cada uno de los componentes y así eliminar el indeterminismo. Este algoritmo, aunque siempre obtiene un AFD equivalente no puede decirse que sea la versión mínima del mismo, para ello deben aplicarse otras transformaciones.
Algoritmo
Sea un autómata finito estrictamente no determinista (AFND) definido
por la 5-tupla A=<Q, T, g, F, q0>, donde Q es el conjunto de estados, T el alfabeto de símbolos terminales, la relación de transiciones ó (léase: del estado qi mediante el terminal x se va a qj), F son los estados finales o de llegada dentro de Q, q0 es el estado inicial o de partida
1. A se transforma en AAFD=<QA,T, gA,FA,q0A>', tal que:
1. VA=P(V)-{{}}, con P(V) que es el conjunto potencia de los vértices de A. 2. FA={x | }. 3. gA={<r,x,q> | }. 4. q0A={q0}. 2. Luego se eliminan de AAFD todos los estados y sus correspondientes transiciones inalcanzables desde el estado inicial q0A.