Post on 20-Oct-2015
2. LENGUAJES REGULARES Y EXPRESIONES REGULARES Tal como se había expresado anteriormente, un lenguaje es un conjunto finito o
infinito de cadenas, construidos a partir de los símbolos de un alfabeto. Para
mayor comprensión de tal definición, en este acápite se aborda una clasificación
de los mismos, en lenguajes regulares y lenguajes no regulares, comprobables
mediante el lema del bombeo, temas que se describen en detalle a continuación.
2.1 CLASIFICACIÓN DE LOS LENGUAJES
Figura No 1. Tipos de Lenguajes
2.2 LENGUAJES REGULARES
TIPOS DE LENGUAJES
Lenguajes regulares
Lenguajes no regulares
Expresiones regulares
Gramática Independiente del
contexto
Se especifica mediante
Se especifica mediante
Es un lenguaje que se forma a partir de los lenguajes básicos como { } y {a}
donde a y debe cumplir tres operaciones básicas: Unión, concatenación y
cerradura de Kleene.
2.2.1. Definición Formal
{ } es un lenguaje regular.
Si a pertenece al alfabeto ( ) entonces {a} es un lenguaje regular.
Si L1 y L2 son lenguajes entonces L1 L2, L1 U L2, L1*, L2* son lenguajes
regulares.
2.2.2. Lema de Bombeo
Los lenguajes regulares poseen una propiedad muy importante que permite
demostrar que ciertos lenguajes no son regulares. Este lema es una herramienta
útil para ello. Tal vez no sea fundamental, pero al menos es un inicio.
El lema de bombeo es una herramienta utilizada para demostrar que ciertos
lenguajes aparentemente regulares no lo son, por medio de una estrategia
conocida como reducción al absurdo. Dicha estrategia consiste en partir de una
suposición aparentemente cierta, demostrar que es falsa por medio de pasos, los
cuales poco a poco contradicen la veracidad de dicha suposición.
Lema de bombeo1: para todo lenguaje regular L (sobre un alfabeto dado Σ) existe
una constante n Є N, llamada constante de bombeo para L, tal que toda cadena w
Є L, con |w|>n, satisface la siguiente propiedad:
1 D.K. Rodrigo. Teoría de la Computación: Lenguajes, Autómatas y Gramáticas. Colombia: Unilibros, 2004.
pp. 63-66.
P1: w se puede descomponer como w=xyz, con |xy| <n, y ≠ , y para todo k>0 se
tiene xykz Є L
Las restricciones bajo las cuales trabaja el lema de bombeo son las siguientes:
Para todo lenguaje regular infinito L, existe una constante n, dependiente de ese
lenguaje, de forma que si w es una cadena de L con |w| ≥ n, podemos partir w en
tres cadenas, x, y, z, de forma que:
• w = xyz,
• y ≠ (o dicho de otro modo, que |y| ≥ 1),
• |xy| <= n
• Para cualquier k ≥ 0, la cadena xyk
z pertenece a L.
2.2.2.1. Demostración de que un lenguaje no es regular
Sea el lenguaje L = {a2n
bn
| n ≥ 0}. Demostrar que L no es regular.
El primer paso es suponer que el lenguaje es regular. Si lo es, y como es infinito,
para él se cumplirá el lema de bombeo. Sea por tanto n∈N la constante del lema
de bombeo para L (constante que se desconoce).
Se elije una palabra que pertenezca a L y de longitud mayor o igual a n:
w = a2n
bn
, tenemos que w ∈ L y |w| = 3n y por tanto |w| ≥ n, sea cual sea n.
El segundo paso es buscar las formas de partir la palabra elegida w en tres xyz
que cumplan las restricciones del lema de bombeo:
- w = xyz
- y ≠
- |xy| <= n (siendo n la constante del lema)
Como se eligió la palabra w, cualquier x,y,z que cumplan las condiciones
(restricciones) del lema serán de la siguiente forma:
- x = ai
- y = aj
- (con j ≥ 1 puesto que y ≠ , con i+j <=n puesto que |xy| <= n)
- z = a2n-i-j
bn
Se sabe que la “x” y la “y” estarán formadas sólo por aes porque la palabra w
que se ha elegido, y de la cual se esta partiendo, tiene 2n aes al principio y la
longitud de “xy” es menor o igual que n. También se conocen las restricciones que
cumplen sus índices (i, j) porque nos la impone el lema de bombeo. Se puede ver
además que obviamente w = xyz, porque:
xyz = ai
aj
a2n-i-j
bn
= a2n
bn
= w.
El tercer paso es encontrar ahora una constante k ≥ 0 con la que ninguna de las
posibles particiones de w que se ha encontrado en el punto anterior sea
bombeable.
Si elegimos k = 2 y bombeamos las x, y, z encontradas en el punto anterior para
esa constante, tendremos que:
xy2
z = ai
a2j
a2n-i-j
bn
= a2n+j
bn
(para cualquier i y j, o sea para cualquiera de las
particiones “legales” de la w elegida según el lema de bombeo).
Pero como j ≥ 1 tenemos que xy2
z = a2n+j
bn
, es una palabra que no pertenece al
lenguaje porque tiene más del doble de aes que de bs (al menos una a más).
Hemos llegado por tanto a una contradicción (una palabra que no es bombeable
de ninguna forma para al menos una constante k en un lenguaje supuestamente
regular) que viene de suponer precisamente que el lenguaje L es regular, luego L
no es regular.
Ejemplo: Usar el lema de bombeo para demostrar que el lenguaje L = {0i1i: i > 0}
no es regular.
Solución. Supeniendo que L es regular, y además n es un a constante bombeo.
Sea w = 0n1n Є L. Entonces w se puede descomponer como w = uvx, con |v| > 1 y
|uv| < n. Por lo tanto, u y v constan únicamente de a es:
u = 0r, para algún r > 0,
v = 1s, para algún s > 1.
Entonces,
x = 0n–(r+s)1n = 0n–r–s 1n
Por el lema de bombeo, uvix Є L para todo i > 0. En particular, si i = 0, ux Є L.
Pero ux=0r1n–r–s1n=0n–s1n. Como n–s ≠ n, la cadena ux ∉ L lo cual es una
contradicción. Se concluye entonces que L no puede ser regular.
Tomando i = 2 también se llega a una contradicción: por un lado, uv2x Є L, pero
uv2x = arasaSan–r–sbn = ar+2s+n–r–sbn= an+sbn
Como s > 1, an+sbn no está en L.
El argumento anterior también sirve para demostrar que el lenguaje L = {aibi : i > 1}
no es regular.
2.2.3. Propiedades de las cerraduras
Las propiedades de las cerraduras tiene gran importancia en la conformación de
otros lenguajes regulares, ya que a través de estas propiedades se pueden
mantener las características de regularidad de los lenguajes, por esta razón es
que se concluye que todos los lenguajes regulares son cerrados bajos estas
operaciones.
Teorema. Si L1 y L2 son lenguajes regulares, entonces también son lenguajes
regulares:
# Operación Descripción
(1) L1UL2 Unión
(2) L1L2 Concatenación
(3) L1* o L1* Cerradura de Kleene
(4) L1+ o L2
+ L1 = Σ* – L1
Cerradura positiva
(5) Complemento
(6) L1⋂L2 Intersección
(7) L1– L2 Diferencia
(8) L1⊲ L2 Diferencia Simétrica
Tabla No 1. Propiedades de las Cerraduras
Las demostraciones de estas propiedades se dejan como trabajo complementario
del lector. Consideramos que estas demostraciones no son relevantes para los
objetivos de este libro.
Un lenguaje regular puede ser finito o infinito. De acuerdo a las propiedades de las cerraduras la unión de lenguajes regulares finitos también es regular, sin embargo la unión de lenguajes regulares infinitos no necesariamente regular.
Por ejemplo,
1
1/
i
iinn banbaL
NO es un lenguaje regular, lo cual se puede demostrar por el lema de Bombeo.
También se puede decir que los lenguajes contenidos dentro de un lenguaje
regular no necesariamente son regulares, también se puede concluir que un
lenguaje regular puede contener sublenguajes no-regulares, así:
Si 1/ nba nn
L
Es un sublenguaje del lenguaje regular a*b* pero L nos regular.
Las propiedades de cerradura permiten concluir, razonando por contradicción, que
ciertos lenguajes no son regulares. Esto se ilustra en los siguientes ejemplos en
los que se usa el hecho de que los lenguajes L = {aibi: i > 0} y L = { aibi: i > 1} no
son regulares.
Ejemplo:
L = {aibj: i, j > 0, i≠j} no es regular.
Si lo fuera, a*b* – L también lo sería, pero
a*b* — L = {aibi: i > 0}
2.2.4. Homomorfismo
En un ámbito general, el homomorfismo, a veces llamado también morfismo, se
define como una función que es compatible con toda la estructura relevante. Una
noción más general de morfismo se estudia abstractamente en la teoría de las
categorías, la cual trata de forma abstracta con las estructuras matemáticas y sus
relaciones. Por ejemplo, si un objeto consiste en un conjunto X con un orden
menor y el otro objeto consiste en un conjunto Y con orden mayor, entonces debe
valer para la función que, si u < v →f(u) < f(v).
O, si en estos conjuntos hay definidas operaciones binarias + y *,
respectivamente, entonces debe valer que: f(u + v) = f(u) * f(v). Ejemplos de
morfismo son los homomorfismos de grupos, los homomorfismos de anillo, los
operadores lineales y las funciones continuas, entre otras.
En el contexto de los lenguajes regulares, el homomorfismo se define como una
función que trabaja sobre cadenas, esto quiere decir que a cada símbolo que
pertenece a una cadena se le asocia otra cadena por medio de la concatenación.
Ejemplo:
Sea h: {0, 1}* → {a, b}
* definido como h (0) = ab, y h(1) = .
Entonces h (0011) = abab y h (L (10* 1)) = L ((ab)*).
En las temáticas anteriores se ha definido el proceso para identificar si un lenguaje
es o no regular, una vez comprendido este proceso se puede determinar que una
de las formas de especificar un lenguaje regular, es mediante expresiones
regulares, tema que se abordará en detalle a continuación.
2.3 EXPRESIONES REGULARES
Las Expresiones Regulares simplifican la especificación de un lenguaje regular y
sirven para efectuar representaciones de los patrones.
Los operadores que se utilizan en las expresiones regulares son los siguientes:
Operador Descripción
. Concatenación
| Unión
* Cerradura de Klenne
+ Cerradura Positiva
? Cerradura 0 o 1 caso
(,) Agrupar
Tabla No 2. Operadores usados en las Expresiones Regulares
# Operador Descripción
1. ( , ) Paréntesis
2. *, + ,? Cerraduras
3. . Concatenación
4. | Unión (se lee “o” y representa la unión en los lenguajes regulares).
Tabla No 3. Orden Jerárquico de Evaluación de los Operadores
2.3.1. Definición formal de Expresión Regular 1. es una expresión regular.
2. si a pertenece a , entonces a es una expresión regular.
3. Si r y s son expresiones regulares, entonces su lenguaje regular es
respectivamente L(r) y L(s).
a. r es una expresión regular y se representa L (r) = {r}
b. (r | s) es una expresión regular y se representa,
L(r) U L(s) = {r} U {s} = {r, s}.
c. r . s es una expresión regular y se representa
L(r) L(s) = {r}{s} = {rs}.
d. r* es una expresión regular y se representa
L*(r) = {r}* = { , r , r , rrr, rrrr…}.
2.3.2. Propiedades de las expresiones regulares
Sean r, s y t expresiones regulares, a partir de las cuales se definen las siguientes
propiedades:
1 r. = .r = r
2. r | = | r
3. r | r = r
4 (r . s) . t = r. (s . t)
5 (r | s) | t =r | (s | t)
6. r . (s | t) = r. s | r . t
7. (r | s)t = r. t | s . t
8. (r | s)* = (r* | s*)* = (r*s*)* = (r*s*)* =(r*s)*r* = r*(sr*)*
9. r(sr)* = (rs)*r
10. (r*s)*= |(r|s)*s
11. (rs*)*= |r(r|s)*
12. s(r| )*(r| )|s = sr*
13. r+ = r . r* = r*r
14. r* = | r+ = r+|
15. (r*)n = r*
16. (r*)+=r*
17. (r*)* = r*
18. (r+)* = r*
19. (r+)+ = r+
20. r? = | r
Todas las propiedades del lenguaje se aplican en las expresiones regulares.
Ejemplo:
= {a, b} Alfabeto
a. b* Expresión regular
Primer paso: verificar que cada elemento esté en el alfabeto, de ser así es una
expresión regular, de lo contrario NO.
Segundo paso: Verificar que la expresión contenga las operaciones básicas
(unión, concatenación y cerraduras).
Habiendo aplicado el primer y segundo paso se puede identificar si es o no una
expresión regular.
Tercer paso: Utilizando la definición formal de expresión regular se expresan las
expresiones regulares en sus respectivos lenguajes regulares, tal como se aprecia
a continuación.
L(a).L*(b) cada uno representa un lenguaje, entonces,
L(a).L*(b)={a}.{b}*, luego se desarrolla la cerradura de Kleene de
{b}*={ ,b,bb,bbb,....} concatenado da como resultado
{a}.{b}*= {a, ab, abb, abbb, abbbb,.....}.
Por tanto, este lenguaje regular corresponde a la expresión regular a. b*.
Ejemplo:
= {a, b, c} Alfabeto
b+a | abc? Expresión regular
Habiendo aplicado los dos primeros pasos se puede concluir que efectivamente es
una expresión regular. A continuación se realiza el tercer paso concerniente a la
aplicación de la definición formal de expresión regular.
b+a | abc? = L+(b).L(a) U L(a) L(b) L?(c) = L(b)L*(b).L(a) U L(a) L(b) (L()U L(c))
cada uno representa su lenguaje unitario.
= {b}{ ,b, bb, bbb, bbbb,…} {a} U {a} {b} {,c}
= {ba,bba,bbba,bbbba,…}U{ab}{,c} concatenando 2a parte
= {ba,bba,bbba,bbbba,…}U{ab, abc} uniendo resultaría
= {ba, bba, bbba, bbbba,…, ab, abc }
Se concluye por tanto que este lenguaje regular corresponde a la expresión
Regular b+a | abc?
Ejemplo:
= {a, b, c} Alfabeto
a*|b* Expresión regular
Habiendo aplicado los dos primeros pasos se puede concluir que efectivamente es
una expresión regular.
a*|b* = L*(a) U L*(b)
= (L(a))* U (L(b))*
= {a}* U {b}*
= { ,a,aa,aaa,aaaa,…}U{ ,b,bb,bbb,bbbb,…}
={ ,a,aa,aaa,aaaa,…,b,bb,bbb,bbbb,…}
Este lenguaje regular corresponde a la expresión regular.
2.3.3. Simplificación de expresiones regulares
Para poder simplificar las expresiones es necesario manejar las propiedades de
los lenguajes descritos y demostrados anteriormente, un ejemplo seria:
[b+b*| (b| )?] [(b*b*)+b?]=b*
[b b*b*| (b| | )] [((b*)2)+b?]=b*
[b(b*)2| (b| )] [(b*)+(b| )]=b*
[bb*|(b| )][b* b| b*)] =b*
[b+|b| ][ b+|b*] =b*
[(b+| )|b][b+|b*] =b*
[b*|b][b+|b*] =b*
[b*][b*] =b*
[b*]2=b*
b*= b*
2.3.4. Expresiones regulares y Patrones
Teniendo claro que un patrón es una regla que describe el conjunto de cadenas de
entrada que corresponden a un componente léxico.
Ejemplo: Una variable comienza en letras seguidas de letras y/ó dígitos.
De igual manera un ejemplo sencillo para comprender el concepto de patrón es el
siguiente
Por extensión tenemos: a,e,i,o,u
Por comprensión tenemos: las vocales
La descripción por compresión es lo que corresponde a un patrón.
Otro ejemplo puede ser {0,1,2,3,4,…,9} estos números forma los enteros positivos.
A continuación se definirán expresiones regulares en las cuales el patrón
corresponde de manera particular y exacta a esa expresión.
Nota 1: un patrón es único, pero se puede escribir de diferentes formas.
Nota 2: el patrón debe ser general para todas las cadenas del lenguaje.
Ejemplo:
Dada la siguiente expresión regular, identifique el patrón.
(a|b)* =L*(a|b)
= ({a}U{b})*
= {a,b}*
={ ,a,b,aa,bb,ab,ba,aaa,abb,aab,aba,baa,bbb,bab,bba...}
Se observa que se pueden formar todas las cadenas con a y b con cualquier
longitud. Es decir, de longitud 2 las posibles cadenas que se pueden formar son
aa,bb,ab,ba y de longitud 3 las cadenas que se pueden formar son
abb,aab,aba,baa,bbb,bab,bba y así sucesivamente. Todas las combinaciones con
las diferentes longitudes están dados en este lenguaje regular.
Como resultado se obtiene el siguiente patrón, correspondiente a la expresión
regular enunciada: Todas las posibles cadenas que se pueden formar con a y
b.
Ejemplo:
Dada la siguiente expresión regular, identifique el patrón.
a(a|b)+=a(a|b)(a|b)*
=L(a)L(a|b) L+(a|b) = {a}({a}U{b}) ({a}U{b})*
= {a}{a,b}{a,b}* ={a}{a,b}{ ,a,b,aa,bb,ab,ba,........}
={a}{a,aa,ab,aaa,abb,aab,aba,.....b,ba,bb,baa,bbb,bab,bba.....} ={aa,aaa,aab,aaaa,aabb,aaab,aaba,...ab,aba,abb,abaa,abbb,abab,abba...} ={aa,ab,aaa,abb,aab,aba,aaaa,aaab,aaba,aabb,abaa,…}
Como resultado se obtiene el siguiente patrón, correspondiente a la expresión
regular enunciada: Todas las posibles cadenas que se pueden formar con a y
b con prefijo a y con longitud mayor o igual a 2.
Ejemplo:
Dada la siguiente expresión regular, identifique el patrón.
(a|b|c)*=L*(a|b|c) = ({a}U{b} U{c})*
= {a,b,c}* ={ ,a,b,c,aa,ab,ac,ba,bb,bc,ca,cb,cc.aaa,aab,aac,aba,abb,abc,aca,acb,acc,…}
Es importante tener en cuenta que no es necesario desarrollar el lenguaje del
ejercicio propuesto para poder entender su comportamiento. Este patrón se puede
deducir a partir del patrón de la expresión regular (a|b)*, es decir, cuando existen
varios componentes léxicos operados con | y todos afectados por una cerradura
de Kleene siempre el resultados será las posibles combinaciones entre los
diferentes componentes léxico.
Como resultado se obtiene el siguiente patrón, correspondiente a la expresión
regular enunciada: Todas las posibles cadenas que se pueden formar con a, b
y c.
Ejemplo:
Dada la siguiente expresión regular, identifique el patrón.
(a|ab)*
= L*(a|ab) = ({a} U {ab})*
= (a, ab)*
= { ,a, ab, aa, aab, aba, abab, aaa, aaab, aaba, aabab, }
Como resultado se obtiene el siguiente patrón, correspondiente a la expresión
regular enunciada: Todas las posibles cadenas que comienzan con a y no
tiene b seguidas.
Ejemplo:
Dada la siguiente expresión regular, identifique el patrón.
(a|b)*a(a|b)
= L*(a|b)L(a)L(a|b) = ({a}U{b})*{a}({a}U{b})
= ({a,b})*{a} ({a,b}) = { ,a,b,aa,ab,ba,bb,....}{a}{a,b}
= {a,aa,ba,aaa,aba,baa,bba,....}{a,b}
= {aa,ab,aaa,aab,baa,bab,aaaa,aaab,abaa,abab…..}
Como resultado se obtiene el siguiente patrón, correspondiente a la expresión
regular enunciada: todas las posibles cadenas que se forman con “a” y “b”
que tenga como penúltimo el símbolo “a”.
En los casos generales del diseño de un compilador siempre se le entrega al
diseñador las reglas que representan a los componentes léxicos, es por eso que la
vía patrón- expresión es la dirección real que representa el diseño y especificación
de esos patrones.
Para desarrollar este tipo de ejercicios no existe un método definido. Todo
consiste en familiarizarse con las expresiones de tal manera que al leer un patrón
se pueda construir intuitivamente la expresión. Para esto, ayuda conocer en qué
consiste cada una de las operaciones básicas (concatenación, unión, cerradura de
Klenne, cerradura positiva y cerradura de 1 o 0 casos) y comprender claramente
su funcionamiento, además de los alcances de combinar estas operaciones.
Ejemplo:
Todas las posibles combinaciones de a, b y c que comiencen con c.
Solución:
Como tiene que comenzar por c, lo obvio es que una c vaya al inicio concatenada
con cualquier cadena entre a, b, y c y esa es otra expresión en si misma, que tiene
un número infinito de combinaciones. La mejor manera de armarlo es con una
cerradura, si fuera +, siempre la c estaría acompañada por lo menos de un
carácter haciendo que la longitud de las cadenas formadas sea mínimo dos, así, la
cerradura adecuada sería * porque ella toma un estado de vacío. Las
combinaciones que se pueden formar entre a, b y c viene dado como (a | b | c)* ya
que siempre que existan elementos entre | y se le aplica una cerradura esto
permite realizar todas las combinaciones.
c(a | b | c)*
Nota: es muy importante que el patrón que se proponga sea muy específico y
comprenda completamente todos los requisitos de la expresión regular.
Ejemplo:
Todas las cadenas que se puedan formar con a y b que tengan una longitud
mayor o igual a 4.
Solución:
Todas las posibles combinaciones de a y b se construye con la expresión regular
(a|b)*; pero con esta expresión no se controla la longitud de las cadenas, para
controlar la longitud de caracteres se debe controlar así: (a|b)4 esta expresión
asegura exactamente 4 símbolos y si se concatena con (a|b) * se tendrían
longitudes mayores e iguales a 4, porque con (a|b) * se tendrían todas las posibles
cadenas que se pueden formar con a y b, de tal manera que la expresión regular
queda de la siguiente forma:
(a|b)4(a|b)
*
Note que esta expresión también se puede escribir:
(a|b) (a|b)3
= (a|b)3(a|b) = (a|b)*(a|b)
4
El orden en que se coloque la cerradura no influye porque no estamos controlando
ni el comienzo ni el final de las cadenas.
El concepto de expresión regular tiene su aplicación práctica en las definiciones
regulares, por ello se abordará este tema a continuación.
2.4 DEFINICIONES REGULARES
Para el abordaje formal de las “Definiciones Regulares”, en primera instancia se
describe la definición regular como concepto fundamental en el proceso del
análisis léxico y se complementa esto con la construcción de definiciones
regulares a partir de un patrón.
2.4.1. La definición regular como concepto fundamental en el proceso del
análisis léxico
La definición regular permite construir expresiones regulares a partir de patrones,
los cuales poseen muchos componentes y por ende alfabetos con gran cantidad
de símbolos, es decir las definiciones regulares permiten simplificar la cantidad de
expresiones regulares utilizadas para resolver reglas que son aplicadas dentro del
contexto de los lenguajes de programación y sobre todas aquellas estructuras que
tiene una secuencia susceptibles de ser solucionadas con el concepto de
expresiones regulares.
Definición formal
Sea Σ un alfabeto, entonces una definición regular es una secuencia de
definiciones de la forma:
d1 → r1 donde di y ri son símbolos de Σ U {d1, d2, ....} d2 → r2 : : dn → rn
dn: Son las definiciones regulares las cuales son nombres dados por el diseñador,
que los asigna de acuerdo a las características o la función que tiene dentro del
diseño. Estas deficiones pueden estar formadas por otras definiciones
previamente definidas.
ri: son expresiones regulares que provienen de un alfabeto. → : la flecha se lee como “define ó produce”. dn → rn : dn se define como rn ó dn produce rn
La estructura que debe contener una definición regular completa es la siguiente:
1. Identificación de los alfabetos.
Σ1 = {0,1,2,3,5,6,7,8,9} Σ2 = {+,-} Σ3 = {.,,}
2. Determinación de las definiciones básicas. Es decir construcción de las
definiciones regulares a partir de las expresiones regulares básicas
tomadas de los alfabetos.
dig → [0-9] signo → +|-
sep → .|,
3. Determinación de definiciones compuestas (que se forman de otras
definiciones).
Numero_entero → signo dig+
Numero_decimal → signo dig* sep sig+
4. Definición resultante (esta definición contiene la solución del problema)
Número →numero_entero | numero_decimal.
Esta definición genera dos opciones, es decir las dos posibilidades de
números enteros y decimales
2.4.2. Construcción de definiciones regulares a partir de un patrón
Ejemplo:
“Una variable debe empezar con una letra y los caracteres siguientes deben ser
letras y/o dígitos”.
Solución:
Lo primero es definir los alfabetos que nos servirán para desarrollar la definición
regular, es importante que se tenga en cuenta que los alfabetos deben estar
definidos por su tipo, es decir, un alfabeto para las letras, otro para los números y
otro para los signos.
Σ1 = {a, b, c,..., z, A, B, C,..., Z} Σ2 = {0, 1, 2,..., 9}
Se necesita en este patrón las letras y los dígitos
Letra [ a | b | c |…| z | A | B | C |...| Z]
Se puede simplificar de la siguiente forma:
[a-z, A-Z] es una forma de representar
Se necesita definir los dígitos
digito 0 | 1 | 2 | …. | 9 | ó dígito [ 0-9 ]
Ahora la definición regular var comienza con una letra y como el enunciado del
ejercicio especifica que debe ir seguido por letras y/o dígitos, esto se puede
representar con una operación de concatenación de la definición básica letra con
las posibles combinaciones que se pueden dar entre letra y dígitos, la definición
quedaría de esta manera:
var Letra (Letra | digíto)*
Ejemplo:
Los números pueden ser casificados como enteros, decimales y punto flotante.
Construya una definición regular para determinar el número que corresponde.
Solución:
Σ1 = {0,1,2,....,9} Σ2 = {+,-} Σ3 = {.} Σ4 = {E,e} digíto [0 - 9] sig (+|-) Exp(E|e)
Ent sig? Digíto+
Dec Sig? digito*.digito+
Flotante Sig ? (Ent | Dec)(Exp) Ent
Ejemplo:
“Un identificador en un lenguaje de programación que empieza con letra
mayúscula y continua con mayúscula o minúscula, tiene como mínimo 5
caracteres y no puede terminar en las subcadenas CIA ó CIO (MAYUSCULAS).”
Solución:
Σ1 = {a, b, c,..., z, A, B, C,..., Z} may → [A-Z] min → [a-z] let → [may, min] sinC → [ A,B, D-Z, min] sinI → [A-H, J-Z, min] sinOA → [B-N, P-Z, min] iden → may let+(sinC let2 | let sinI let | let2 sinOA)