CAPITULO 2 COMP

Anuncio
2.1
El proceso de análisis léxico
Un compilador se compone internamente de varias etapas, o fases, que realizan
distintas operaciones lógicas. Es útil pensar en estas fases como en piezas separadas
dentro del compilador, y pueden en realidad escribirse como operaciones codificadas
separadamente aunque en la práctica a menudo se integren juntas.
El análisis léxico constituye la primera fase, aquí se lee el programa fuente de
izquierda a derecha y se agrupa en '''componentes léxicos''' (Token (programación)),
que son secuencias de caracteres que tienen un significado. Además, todos los
espacios en blanco, líneas en blanco, comentarios y demás información innecesaria se
elimina del programa fuente. También se comprueba que los símbolos del lenguaje
(palabra clave, operador, ...) se han escrito correctamente.
Como la tarea que realiza el analizador léxico es un caso especial de coincidencia de
patrones, se necesitan los métodos de especificación y reconocimiento de patrones, y
éstos métodos son principalmente las expresión regular y los autómata finito. Sin
embargo, un analizador léxico también es la parte del compilador que maneja la
entrada del código fuente, y puesto que esta entrada a menudo involucra un
importante gasto de tiempo, en analizador léxico debe funcionar de manera tan
eficiente como sea posible.
2.2
Expresiones regulares
Una expresión regular, a menudo llamada también '''patrón''', es una expresión que
describe un conjunto de cadenas sin enumerar sus elementos. Por ejemplo, el grupo
formado por las cadenas ''Handel'', ''Händel'' y ''Haendel'' se describe mediante el
patrón "H(a|ä|ae)ndel". La mayoría de las formalizaciones proporcionan los siguientes
constructores: una '''expresión regular''' es una forma de representar a los lenguaje
regular (finitos o infinitos) y se construye utilizando carácter|caracteres del alfabeto
sobre el cual se define el lenguaje. Específicamente, las expresiones regulares se
construyen utilizando los operadores unión concatenación y clausura de Kleene.
Alternación
Una barra vertical separa las alternativas. Por ejemplo, "marrón|castaño" casa con
''marrón'' o ''castaño''.
Cuantificación
Un cuantificador tras un carácter especifica la frecuencia con la que éste puede ocurrir.
Los cuantificadores más comunes son +, ? y *: +
El signo más indica que el carácter al que sigue debe aparecer al menos una vez. Por
ejemplo, "ho+la" describe el conjunto infinito ''hola'', ''hoola'', ''hooola'', ''hoooola'',
etcétera.
? El signo de interrogación indica que el carácter al que sigue puede aparecer como
mucho una vez. Por ejemplo, "ob?scuro" casa con ''oscuro'' y ''obscuro''.
agrupación
Los paréntesis pueden usarse para definir el ámbito y precedencia de los demás
operadores. Por ejemplo, "(p|m)adre" es lo mismo que "padre|madre", y
"(des)?amor" casa con amor y con desamor.
Los constructores pueden
-6-
combinarse libremente dentro de la misma expresión, por lo que "H(ae?|ä)ndel"
equivale a "H(a|ae|ä)ndel".
La sintaxis precisa de las expresiones regulares cambia según las herramientas y
aplicaciones consideradas, y se describe con más detalle a continuación.
Su utilidad más obvia es la de describir un conjunto de cadenas, lo que resulta de
utilidad en editores de texto y aplicaciones para buscar y manipular textos.
Muchos lenguajes de programación admiten el uso de expresiones regulares con
este fin. Por ejemplo, Perl tiene un potente motor de expresiones regulares
directamente incluido en su sintaxis. Las herramientas proporcionadas por las
distribuciones de Unix (incluyendo el editor sed y el filtro grep) fueron las
primeras en popularizar el concepto de expresión regular.
Numerosos editores de texto y otras utilidades (especialmente en el sistema operativo
UNIX/linux), como por ejemplo sed y awk, utilizan expresiones regulares para, por
ejemplo, buscar palabras en el texto y reemplazarlas con alguna otra cadena de
caracteres.
En el área de la programación las expresiones regulares son un método por medio del
cual se pueden realizar búsquedas dentro de cadenas de caracteres. Sin importar si la
búsqueda requerida es de dos caracteres en una cadena de 10 o si es necesario
encontrar todas las apariciones de un patrón definido de caracteres en un archivo de
millones de caracteres, las expresiones regulares proporcionan una solución para el
problema. Adicionalmente, un uso derivado de la búsqueda de patrones es la
validación de un formato específico en una cadena de caracteres dada, como por
ejemplo fechas o identificadores.
Para poder utilizar las expresiones regulares al programar es necesario tener acceso a
un motor de búsqueda con la capacidad de utilizarlas. Es posible clasificar los motores
disponibles en dos tipos: Motores para el programador y Motores para el usuario final.
Motores para el usuario final: Son programas que permiten realizar búsquedas
sobre el contenido de un archivo o sobre un texto extraído y colocado en el programa.
Están diseñados para permitir al usuario realizar búsquedas avanzadas usando este
mecanismo, sin embargo es necesario aprender a redactar expresiones regulares
adecuadas para poder utilizarlos eficientemente. Éstos son algunos de los programas
disponibles:
grep: Programa de los sistemas operativos Unix/Linux
PowerGrep: versión de grep para los sistemas operativos Windows
RegexBuddy: Ayuda a crear las expresiones regulares en forma interactiva y luego
le permite al usuario usarlas y guardarlas.
EditPad Pro: Permite realizar búsquedas con expresiones regulares sobre archivos y
las muestra por medio de código de colores para facilitar su lectura y comprensión.
Motores para el programador: Permiten automatizar el proceso de búsqueda de
modo que sea posible utilizarlo muchas veces para un propósito específico. Estas son
algunas de las herramientas de programación disponibles que ofrecen motores de
búsqueda con soporte a expresiones regulares:
Java: Existen varias librerías hechas para java que permiten el uso de RegEx, y
Sun planea dar soporte a estas desde el SDK
JavaScript: A partir de la versión 1.2 (ie4+, ns4+) JavaScript tiene soporte
integrado para expresiones regulares, lo que significa que las validaciones que se
-7-
realizan normalmente en una página web podrían simplificarse grandemente si el
programador supiera utilizar esta herramienta.
Perl: Es el lenguaje que hizo crecer a las expresiones regulares en el ámbito de la
programación hasta llegar a lo que son hoy en día.
PCRE: Librería de ExReg para C, C++ y otros lenguajes que puedan utilizar librerías
dll (Visual Basic 6 por ejemplo).
PHP: Tiene dos tipos diferentes de expresiones regulares disponibles para el
programador.
Python: Lenguaje de "scripting" popular con soporte a Expresiones Regulares.
.Net Framework: Provee un conjunto de clases mediante las cuales es posible
utilizar expresiones regulares para hacer búsquedas, reemplazar cadenas y validar
patrones.
Nota: De las herramientas mencionadas con anterioridad se utilizan el EditPad Pro y el
.Net Framework para dar ejemplos, aunque es posible utilizar las expresiones
regulares con cualquier combinación de las herramientas mencionadas. Aunque en
general las Expresiones Regulares utilizan un lenguaje común en todas las
herramientas, las explicaciones prácticas acerca de la utilización de las herramientas y
los ejemplos de código deben ser interpretados de forma diferente. También es
necesario hacer notar que existen algunos detalles de sintaxis de las expresiones
regulares que son propietarios del .Net Framework que se utilizan en forma diferente
en las demás herramientas de programación. Cuando estos casos se den se hará notar
en forma explícita para que el lector pueda buscar información respecto a estos
detalles en fuentes adicionales. En el futuro se incluirán adicionalmente ejemplos de
otras herramientas y lenguajes de programación.
Expresiones Regulares como motor de búsqueda
Las expresiones regulares permiten encontrar porciones específicas de texto dentro de
una cadena más grande de caracteres. Así, si es necesario encontrar el texto "lote" en
la expresión "el ocelote salto al lote contiguo" cualquier motor de búsqueda sería capaz
de efectuar esta labor. Sin embargo, la mayoría de los motores de búsqueda
encontrarían también el fragmento "lote" de la palabra "ocelote", lo cual podría no ser
el resultado esperado. Algunos motores de búsqueda permiten adicionalmente
especificar que se desea encontrar solamente palabras completas, solucionando este
problema. Las expresiones regulares permiten especificar todas estas opciones
adicionales y muchas otras sin necesidad de configurar opciones adicionales, sino
utilizando el mismo texto de búsqueda como un lenguaje que permite enviarle al motor
de búsqueda exactamente lo que deseamos encontrar en todos los casos, sin
necesidad de activar opciones adicionales al realizar la búsqueda.
Expresiones Regulares como lenguaje
Para especificar opciones dentro del texto a buscar se utiliza un lenguaje o convención
mediante el cual se le transmite al motor de búsqueda el resultado que se desea
obtener. Este lenguaje le da un significado especial a una serie de caracteres. Por lo
tanto cuando el motor de búsqueda de Expresiones Regulares encuentre estos
caracteres no los buscará en el texto en forma literal, sino que buscará lo que los
caracteres significan. A estos caracteres se les llama algunas veces "meta-caracteres".
A continuación se listan los principales meta-caracteres y su función y como los
interpreta el motor de Expresiones Regulares.
-8-
2.3
Autómatas finitos
Un autómata finito o máquina de estado finito es un modelo matemático de un sistema
que recibe una cadena constituida por símbolos de un alfabeto y determina si esa
cadena pertenece al lenguaje que el autómata reconoce.
Formalmente, un autómata finito (AF) puede ser descrito como una 5-tupla (S,Σ,T,s,A)
donde:
S un conjunto de estados;
Σ es un alfabeto;
T es la función de transición:
;
es el estado inicial;
es un conjunto de estados de aceptación o finales.
Ejemplo 1
S = {S1, S2},
Σ = {0,1},
T = {(S1,0,{S2});(S1,1,{S1});(S2,0,{S1});(S2,1,{S2})}
s = S1
A = {S1}.
Además de notar un AF a través de su definición formal es posible representarlo a
través de otras notaciones que resultan más cómodas. Entre estas notaciones, las más
usuales son:
Las Tablas de Transiciones: la tabla de transición para el AF del ejemplo 1 es
0 1
S S S
1
2
1
S S S
2
1
2
Los Diagramas de Transiciones: el diagrama de transición para el AF del ejemplo 1
es
Figura 2.1
-9-
Las Expresiones regulares. Se demuestra que dado un autómata de estados finitos,
existe una expresión regular que lo representa.
Ø υ 1* υ (1* ο 0 ο 1* ο 0)*.
En el comienzo del proceso de reconocimiento de una cadena, el AF se encuentra en el
estado inicial y a medida que procesa cada símbolo de la cadena va cambiando de
estado de acuerdo a lo determinado por la función de transición. Cuando se ha
procesado el último de los símbolos de la cadena de entrada, el autómata se detiene.
Si el estado en el que se detuvo es un estado de aceptación o final, entonces la cadena
pertenece al lenguaje reconocido por el autómata, caso contrario, la cadena no
pertenece a dicho lenguaje.
2.4
Desde las expresiones regulares hasta los DFA ( autómatas finitos determinstas)
Un AFD o autómata finito determinista es aquel autómata finito cuyo estado de llegada
está unívocamente determinado por el estado inicial y el carácter leído por el
autómata.
Formalmente, un autómata finito determinista (AFD) es similar a un Autómata de
estados finitos, representado con una 5-tupla (S,Σ,T,s,A) donde:
Σ es un alfabeto;
S un conjunto de estados;
T es la función de transición:
;
es el estado inicial;
es un conjunto de estados de aceptación o finales.
Al contrario de la definición de autómata finito, este es un caso particular donde no se
permiten transiciones vacías, el dominio de la función T es S (con lo cual no se
permiten transiciones desde un estado de un mismo símbolo a varios estados).
A partir de este autómata finito es posible hallar la expresión regular resolviendo un
sistema de ecuaciones.
S1 = 1 S 1 + 0 S 2 + ε
S2 = 1 S 2 + 0 S 1
Siendo ε la palabra nula. Resolviendo el sistema y haciendo uso de las
reducciones apropiadas se obtiene la siguiente expresión regular:
1*(01*01*)*.
Inversamente, dada la expresión regular es posible generar un autómata que
reconozca el lenguaje en cuestión utilizando el algoritmo de Thompson,
desarrollado por Ken Thompson, uno de los principales creadores de UNIX,
junto con Dennis Ritchie.
Un tipo de autómatas finitos deterministas interesantes son los tries.
Autómatas finitos no deterministas
Un AFND o autómata finito no determinista es aquel que presenta cero, una o
más transiciones por el mismo carácter del alfabeto.
Un autómata finito no determinista también puede o no tener más de un
nodo inicial.
- 10 -
Los AFND también se representan formalmente como tuplas de 5 elementos
(S,Σ,T,s,A). La única diferencia respecto al AFD es T.
AFD:
AFND:
(partes de S)
Debido a que la función de transición lleva a un conjunto de estados, el
automáta puede estar en varios estados a la vez (o en ninguno si se trata del
conjunto vacío de estados).
Autómatas finitos no deterministas con transiciones vacías
Un AFND-ε o autómata finito no determinista con transiciones ε permite
cambiar de estado sin procesar ningún símbolo de entrada. Cuando el
autómata llega a un estado, se encuentra en ese estado y en los estados a
los que apunte este mediante una transición ε.
Un automata es un AFND:
(partes de S)
AFND-ε:
(partes de S)
Cuando el símbolo de entrada es la palabra vacía (ε), existe una transición ε
entre los estados.
AFD, AFND y AFND-ε
Para todo AFND-ε existe un AFND equivalente y para todo AFND existe un
AFD equivalente.
Existen algoritmos para transformar un autómata en otro. Los AFD son los
más sencillos de construir, por tanto, puede ser útil diseñar un autómata
complejo como AFND-ε o AFND para luego transformarlo en AFD para su
implementación.
2.5
Implementación de un analizador léxico TINY (“Diminuto”)
Con las herramientas y los conceptos expuestos en los párrafos anteriores, parecen ser
los suficientes para implementar un analizador léxico pequeño. Los pasos a seguir
serian enumerados de la siguiente manera:
� Determinar
los tokens
un patrón para cada uno
� Implementar los patrones
� Manual
� Herramientas
� Definir
La función de un analizador léxico es examinar el código fuente y reconocer las
palabras o tokens que formen parte del lenguaje así como determinar si hay elementos
que no pertenecen al lenguaje. Como resultado del análisis léxico se devolverá la lista
de tokens que forman el código fuente.
Lo primero que debemos hacer es definir los tipos de palabras que compondrán el
lenguaje así como las reglas para formar palabras. En el lenguaje que estoy creando
he identificado los siguientes tipos de palabras:
- 11 -









Identificadores
Cadenas
Valores o constantes numéricas
Valores o constantes lógicas
Palabras reservadas
Símbolos especiales como “,”, “(” y “)”
Operadores
Saltos de línea
Fin de fichero
Dicho lenguaje pretende ser bastante sencillo y fácil de utilizar. Por ello se utilizan
palabras en castellano en vez de en ingles como la mayoría de lenguajes de
programación.
Ahora pasaremos a definir las reglas de formación de cada uno de esos tipos de
palabras. Hay tipos de palabras que se definen por enumeración como son los
operadores, los símbolos especiales, las palabras reservadas, etc. Para definir otros
tipos de tokens utilizaremos autómatas finitos deterministas como ya se explico en el
artículo Autómata finito determinista para reconocer constantes numéricas.
Definiciones


Operadores:
o + , -, *, /, =, !=, <, >, >=, <=, Y, O
Palabras reservadas:
Variable:
Constante:
Logica:
Cadena:
Numerica:
Si:
Entonces:
Fin:
Mientras:

para declarar variables
para declarar constantes
tipo de dato
tipo de dato
tipo de dato
Forma parte de la estructura condicional
Forma parte de la estructura Condicional
Forma parte de la estructura Condicional e Iterativa
Forma parte de la estructura Iterativa
 Símbolos especiales: (, ) y ,
Constantes lógicas:
Verdadero, Falso

Constante cadena:
Secuencia de caracteres delimitados por las comillas (“) Si la cadena
contiene el carácter “ o \ debe ir precedido del carácter de escape \
- 12 -
Figura 2.2

A.F.D. Reconocedor de cadenas.
Constante numérica:
Una constante numérica debe estar formada por al menos un dígito,
puede ir precedida o no por el signo y puede tener o no decimales. Si
contiene el punto decimal debe tener al menos un dígito en la parte de
los decimales.
Figura 2.3

A.F.D. Reconocedor de constantes numéricas.
Identificadores:
Una letra seguida una secuencia de 0 o más letras o dígitos o el signo _
- 13 -
Figura 2.4
A.F.D. Reconocedor de identificadores.
Trás definir todos los posibles tokens procederemos a la implementación del analizador
léxico que los reconocerá. El analizador antes de poder reconocer los tokens debe
fraccionar el código fuente en las palabras que lo componen, teniendo en cuenta para
ello los separadores (salto de línea y espacio en blanco). Además se debe tener en
cuenta que los espacios en blanco dentro de una cadena no deben ser tenidos en
cuenta. Una vez separadas todas las palabras existentes en el código fuente se deben
intentar reconocer cada una de ellas. Para ello nos serviremos de autómatas finitos
deterministas, que desarrollaremos según lo expuesto antes, para los componentes
léxicos más complejos. Para aquellas palabras cuyo reconocimiento es trivial, como los
operadores o las palabras reservadas, simplemente compararemos con dichas
elementos. Como se muestra en el siguiente fragmento de código que es utilizado para
reconocer si una palabra es una constante lógica o no.
1.
2.
3.
Private Shared Function EsConstanteLogica(ByVal palabra As String) As Boolean
Return palabra.ToUpper = "VERDADERO" Or palabra.ToUpper = "FALSO"
End Function
El analizador recibe como parámetros la ruta de un fichero que contiene el script, una
cadena con el script o un array de cadenas conteniendo cada una línea del script. Como
salida genera una colección de palabras o componentes léxicos. Para cada uno de ellos se
proporciona la siguiente información:




Palabra en si tal y como aparece en el script
Tipo de componente léxico
Componente sintáctico con que se corresponde y que será utilizado posteriormente por el
analizador sintáctico
Linea y columna del script en la que aparece la palabra. Utilizado para mostrar los errores
resaltándolos en el código del script y notificar en que punto se ha producido el posible
error.
El analizador reconoce los siguientes componentes léxicos:









Identificador
CTE_Cadena
CTE_Numerica
CTE_Logica
Palabra_Reservada
Simbolo_Especial ",", "(" y ")"
Operador
Salto_Linea
Fin_Fichero
- 14 -

Erronea
La siguiente entrada del analizador léxico:
n1 "hola" "hño l!'a" "\\as" "ac\\as\"11\"22\"dd fas" c2
fin
variable 3 * a verdadero Y
fas"dfas "as"asf"
"a\aas" 1234.34
c3 c3 "AAAA BB
CC"
"fasdfs\"
numerica 3 / 456 <> != 3 O
fadvariable c3
si
falso
cadena
( , 3 ) produce la siguiente salida:
Salida del analizador léxico.
- 15 -
2.6
Uso de Lex para generar automáticamente un analizador léxico
El lex es un generador de programas diseñado para el proceso léxico de cadenas de
caracteres de input. El programa acepta una especificación, orientada a resolver un
problema de alto nivel para comparar literales de caracteres, y produce un programa C
que reconoce expresiones regulares. Estas expresiones las especifica el usuario en las
especificaciones fuente que se le dan al lex. El código lex reconoce estas expresiones
en una cadena de input y divide este input en cadenas de caracteres que coinciden con
las expresiones. En los bordes entre los literales, se ejecutan las secciones de
programas proporcionados por el usuario. El fichero fuente lex asocia las expresiones
regulares y los fragmentos de programas. Puesto que cada expresión aparece en el
input del programa escrito por el lex, se ejecuta el fragmento correspondiente.
El usuario proporciona el código adicional necesario para completar estas funciones,
incluyendo código escrito por otros generadores. El programa que reconoce las
expresiones se genera en forma de fragmentos de programa C del usuario, El lex no es
un lenguaje completo sino un generador que representa una cualidad de un nuevo
lenguaje que se añade al leguaje de programación C.
El lex convierte las expresiones y acciones del usuario (llamadas fuente en este
capítulo) en un programa C llamado yylex. El programa yylex reconoce expresiones en
un flujo (llamado input en este capítulo) y lleva a cabo las acciones especificadas para
cada expresión a medida que se va detectando.
Considere un programa para borrar del input todos los espacios en blanco y todos los
tabuladores de los extremos de las líneas. Las líneas siguientes:
%%
[b\ t]+ $ ;
es todo lo que se requiere. El programa contiene un delimitado %% para marcar el
principio de las órdenes, y una orden. Esta orden contiene una expresión que coincide
con una o más apariciones de los caracteres espacio en blanco o tabulador (escrito \ t
para que se vea con mayor claridad, de acuerdo con la convención del lenguaje C)
justo antes del final de una línea. Los corchetes indican la clase del carácter compuesto
de espacios en blanco y tabuladores; el + indica uno o más del item anterior; y el
signo de dólar ($) indica el final de la línea. No se especifica ninguna acción, por lo
tanto el programa generado por el lex ignorará estos caracteres. Todo lo demás se
copiará. Para cambiar cualquier cadena de caracteres en blanco o tabuladores que
queden en un solo espacio en blanco, añada otra orden:
%%
[b\ t]+$ ;
[b\ t] + printf (“ ”);
La automatización generada por este fuente explora ambas órdenes a la vez, observa
la terminación de la cadena de espacios o tabuladores haya o no un carácter newline, y
después ejecuta la acción de la orden deseada. La primera orden coincide con todas las
cadenas de caracteres de espacios en blanco o tabuladores hasta el final de las líneas,
y la segunda orden coincide con todos los literales restantes de espacios o tabuladores.
El lex se puede usar sólo para transformaciones sencillas, o por análisis o estadísticas
buscando en un nivel léxico. El lex también se puede usar con un generador
reconocedor para llevar a cabo la fase de análisis léxico; es especialmente fácil hacer
que el lex y el yacc funcionen juntos. Los programas lex reconocen sólo expresiones
regulares; yacc escribe reconocedores que aceptan una amplia clase de gramáticas de
texto libre, pero que requieren un analizador de nivel bajo para reconocer tokens de
input. Por lo tanto, a menudo es conveniente una combinación del lex y del yacc.
Cuando se usa como un preprocesador para un generador, el lex se usa para dividir el
input, y el generador de reconocimiento asigna una estructura a las piezas resultantes.
- 16 -
Los programas adicionales, escritos por otros generadores o a mano, se pueden añadir
fácilmente a programas que han sido escritos por el lex. Los usuarios del yacc se darán
cuenta de que el nombre yylex es el que el yacc da a su analizador léxico, de forma que el
uso de este nombre por el lex simplifica el interface.
El lex genera un autómata finito partiendo de expresiones regulares del fuente. El
autómata es interpretado, en vez de compilado, para ahorrar espacio.
El resultado es todavía un analizador rápido. En particular, el tiempo que utiliza un
programa lex para reconocer y dividir una cadena de input es proporcional a la
longitud del input. El número de órdenes lex o la complejidad de las órdenes no es
importante para determinar la velocidad, a no ser que las órdenes que incluyan
contexto posterior requieran una cantidad importante de exploración. Lo que aumenta
con el número y complejidad de las órdenes es el tamaño del autómata finito, y por lo
tanto el tamaño del programa generado por el lex. En el programa escrito por el lex,
los fragmentos del usuario (representando acciones que se van a llevar a cabo a
medida que se encuentra cada expresión) se colectan como casos de un intercambio.
El intérprete del autómata dirige el flujo de control. Se proporciona la oportunidad al
usuario para insertar declaraciones o sentencias adicionales en la rutina que contiene
las acciones, o para añadir subrutinas fuera de esta rutina de acción. El lex no está
limitado a fuente que se puede interpretar sobre la base de un posible carácter. Por
ejemplo, si hay dos órdenes una que busca ab y la otra que busca abcdefg, y la cadena
de caracteres del input es abcdefh, el lex reconocerá ab y dejará el puntero del input
justo delante de cd. Tal precaución es más costosa que el proceso de lenguajes más
sencillos.
Formato fuente del lex
El formato general de la fuente lex es:
{definiciones}
%%
{órdenes}
%%
{subrutinas del usuario}
donde las definiciones y las subrutinas del usuarios se omiten a menudo. El segundo
%% es opcional, pero el primero se requiere para marcar el principio de las órdenes.
El programa lex mínimo absoluto es por lo tanto %% (sin definiciones, ni órdenes) lo
cual se traduce en un programa que copia el input en el output sin variar.
En el formato del programa lex que se mostró anteriormente, las órdenes representan
las decisiones de control del usuario. Estas forman una tabla en la cual la columna
izquierda contiene expresiones regulares y la columna derecha contiene decisiones,
fragmentos de programas que se ejecutarán cuando se reconozcan las expresiones.
Por lo tanto la siguiente orden individual puede aparecer:
integer printf(“ localizada palabra reservada INT ”) ;
Esto busca el literal “integer” en el input e imprime el mensaje:
localizada palabra reservada INT siempre que aparezca en el texto de input. En este
ejemplo la función de librería printf() se usa para imprimir la cadena de caracteres o
literal. El final de la expresión regular lex se indica por medio del primer carácter
espacio en blanco o tabulador. Si la acción es simplemente una sola expresión C, se
puede especificar en el lado derecho de la línea; si es compuesta u ocupa más de una
línea, deberá incluirse entre llaves. Como ejemplo un poco más útil, suponga que se
desea cambiar un número de palabras de la ortografía Británica a la Americana. Las
órdenes lex tales como:
- 17 -
colour printf(“color”);
mechanise printf(“mechanize”);
petrol printf(“gas”);
será una forma de empezar. Estas órdenes no son suficientes puesto que la palabra
petroleum se convertirá en gaseum; una forma de proceder con tales problemas se
describe en una sección posterior.
- 18 -
Descargar