Está en la página 1de 19

Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

EJERCICIOS SECCION 3.3


3.3.1 Consulte los manuales de referencia del lenguaje para determinar (i) los conjuntos de
caracteres que forman el alfabeto de entrada (excluyendo aquellos que sólo puedan aparecer
en cadenas de caracteres o comentarios), (ii) la forma léxica de las constantes numéricas, y ( iii)
la forma léxica de los identificadores, para cada uno de los siguientes lenguajes:
(a) C (b) C + + (c) C # (d) Fortran (e) Java (f) Lisp (g) SQL.

a. Lenguaje C

i) Conjuntos de Caracteres
En la elaboración de programas en C se pueden utilizar para formar los elementos básicos
(constantes, variables, operadores, expresiones) las letras mayúsculas de la A a la Z, las
minúsculas de la a a la z , los dígitos del 0 al 9 y ciertos caracteres especiales:

! * + \ " <
# ( = | { >
% ) ~ ; } /
^ - _ [ : '
? & . ] (blanco)

ii) Forma Léxica constantes numéricas


Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

iii)

b. Lenguaje C++
i)

Caracteres especiales y signos de puntuación:


+ - * / = % & # ! ? ^ “ ‘ ~
\ | < > ( ) [ ] { } : ; . ,
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

ii)
Constantes enteras

Ejemplo 1:

1912 3 8 6578 0

Una constante entera octal está formada por cualquier combinación de dígitos tomados del 0
al 7. El primer dígito obligatoriamente tiene que ser 0 (esto es para distinguir la constante
como un número octal).

Ejemplo 2:

0 03 0654 032

Una constante entera hexadecimal debe comenzar por 0x o 0X, a continuación puede aparecer
cualquier combinación del 0 al 9 o de la a a la f (tanto mayúsculas como minúsculas).

Ejemplo 3:

0x 0x3 0x7f 0xacd


Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

Constantes de coma flotante

2.4 por 10 elevado a -3 es equivalente a 2.4E-3 ó 2.4e-3

8 por 10 elevado a +3 es equivalente a 8000

8 por 10 elevado a +3 es equivalente a 8E+3

8 por 10 elevado a +3 es equivalente a 8E3

8 por 10 elevado a +3 es equivalente a 8.0e3

iii)
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

c. Lenguaje C#
i) Los caracteres en C# no tienen un tamaño de 8 bits como en otros muchos lenguajes de
programación, sino que usan un tamaño de 16 bits llamado Unicode al cual se le llama char. No
existen conversiones automáticas de tipo entero a char.

C#, al igual que C++, define un tipo de cadena de caracteres. Dentro de la cadena de caracteres
se pueden usar secuencias de escape. Una cadena de caracteres puede iniciarse con el símbolo
@ seguido por una cadena entre comillas ("), en tal caso, las secuencias de escape no tienen
efecto, y además la cadena puede ocupar dos o más líneas.

ii)
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

iii) En C# reserva 76 identificadores para uso propio, se les conoce como palabras clave y cada
una de ellas posee un significado particular.

d. Lenguaje Fortran
i) El conjunto de caracteres admisible para FORTRAN es el siguiente :
• Las letras A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
• Los dıgitos 0 1 2 3 4 5 6 7 8 9..
• Los caracteres especiales.

Los caracteres alfabéticos en minúsculas, el signo de


admiración(!), el subrayado( ) y las comillas (“) son extensiones al
standard ANSI FORTRAN 77.
Se pueden intercalar espacios para mejorar la legibilidad del
código fuente.
El compilador no hace distinción entre mayúsculas y minúsculas
(excepto en constantes de tipo carácter).
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

ii)

iii) Los identificadores deben empezar con una letra y pueden tener hasta 31 letras, dígitos o
caracteres de subrayado _.
• Por ejemplo, identificadores válidos son:
• Masa, MASA, Velocidad_de_la_luz, Sueldo_del_ultimo_mes,X007.
• Y no válidos: R2-D2, 34JUlio, pepe$.
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

e) Lenguaje JAVA
i) En Java los caracteres no están restringidos a los ASCII sino son Unicode. Un carácter está siempre
rodeado de comillas simples como 'A', '9', 'ñ', etc. El tipo de dato char sirve para guardar estos caracteres.

Un tipo especial de carácter es la secuencia de escape, similares a las del lenguaje C/C++, que se
utilizan para representar caracteres de control o caracteres que no se imprimen. Una secuencia
de escape está formada por la barra invertida (\) y un carácter. En la siguiente tabla se dan las
secuencias de escape más utilizadas.

Carácter Secuencia de escape

retorno de
\r
carro

tabulador
\t
horizontal

nueva línea \n

barra invertida \\

ii) Su estructura está compuesta por:

static final Tipo IDENTIFICADOR = valor;


// En el ámbito de una clase, o es miembro de la clase.
final Tipo IDENTIFICADOR = valor;
// En el ámbito de una clase, o es miembro de la clase.
final Tipo IDENTIFICADOR = valor;
// En el cuerpo de un método, o de ámbito local.

iii) Los identificadores se utilizan para los nombres de las clases, de los métodos y de las variables.
Un identificador puede ser cualquier secuencia descriptiva de letras mayúsculas o minúsculas,
números, el carácter de subrayado, o el símbolo del dólar. Un identificador no debe empezar nunca
con un número, para evitar la confusión con un literal numérico. Conviene recordar otra vez que
Java distingue entre mayúsculas y minúsculas; así, el identificador VALOR no es lo mismo que el
identificador valor.Ejemplo:
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

f) Lenguaje Lisp
i) En Lisp las cadenas de caracteres son átomos, y pueden contener cualquier carácter. En forma
escrita, los átomos cadena de caracteres utilizan la representación habitual de caracteres
encerrados entre comillas dobles.

ii)

iii) Símbolos (Identificadores): Estos átomos comienzan con un caracter seguido de cualquier
otro caracter excepto espacios, comas, puntos o paréntesis. Ejemplo: casa, ca&, casa1, C, etc.
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

g) Lenguaje SQL
i) Para un usuario o un grupo:
Los caracteres válidos son: 'A'-'Z'; 'a'-'z'; '0'-'9'; '#'; '@'; '$'; '_'; '!'; ' '('; ')'; '{'; '}'; '-'; '.'y '^'.
Los caracteres siguientes deben delimitarse entre comillas si se especifican en el procesador de
línea de mandatos: '!'; ' '('; ')'; '{'; '}'; '-'; '.'y '^'.
El nombre no puede empezar por los caracteres 'SYS', 'IBM' ni 'SQL'.
El nombre no puede ser: 'ADMINS', 'GUESTS', 'LOCAL', 'PUBLIC' ni 'USERS'.
Un ID de autorización delimitado no debe contener letras en minúsculas.

ii)

constant_name tipo de datos CONSTANT: = valor;

• constant_name es el nombre de la constante, es decir, similar a un nombre de variable.


• La palabra CONSTANTE es una palabra reservada y asegura que el valor no cambia.
• VALOR - Es un valor que se debe asignar a una constante cuando se declara. No se puede
asignar un valor más tarde.

iii)
• identificadores de SQL
Existen dos tipos de identificadores de SQL: ordinarios y delimitados.
o Un identificador ordinario es una letra mayúscula seguida por cero o más
caracteres, cada uno de los cuales es una letra en mayúsculas, un dígito o el
carácter de subrayado. Tenga en cuenta que pueden utilizarse letras en
minúsculas al especificar un identificador ordinario, pero éstas se convertirán en
mayúsculas al procesarse. Un identificador ordinario no debe ser una palabra
reservada.
Ejemplos
WKLYSAL WKLY_SAL
o Un identificador delimitado es una secuencia de uno o varios caracteres entre
comillas dobles. Los espacios en blanco interlineados en la secuencia son
significativos. Los espacios en blanco rezagados en la secuencia no son
significativos, a pesar de que se almacenan con el identificador. Dos comillas
consecutivas se utilizan para representar unas comillas dentro del identificador
delimitado. Se puede utilizar un identificador delimitado cuando la secuencia de
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

caracteres no se considere un identificador ordinario. De esta manera un


identificador puede incluir letras en minúsculas.
Ejemplos
"WKLY_SAL" "WKLY SAL" "UNION" "wkly_sal"
La conversión de caracteres de los identificadores creados en una página de códigos de doble
byte pero utilizados por una aplicación o una base de datos con página de códigos de múltiples
bytes puede necesitar una consideración especial: tras la conversión, dichos identificadores
pueden superar el límite de longitud de un identificador.
• Identificadores del lenguaje principal
Un identificador del lenguaje principal es un nombre declarado en el programa de lenguaje
principal. Las normas para formar un identificador de lenguaje principal son las normas del
lenguaje principal. Un identificador de sistema principal no debería tener más de 255 bytes de
longitud y no debería empezar por SQL o DB2 (en mayúsculas o en minúsculas).

3.3.2 Describa los lenguajes detonados por las siguientes expresiones regulares:

1. a(a|b)*a
2. ((ε|a)b*)*
3. (a|b)*a(a|b)(a|b)
4. a*ba*ba*ba*
5. !! (aa|bb)*((ab|ba)(aa|bb)*(ab|ba)(aa|bb)*)*

1. Inducción

L( a ) ( L( a|b ) ) * L( a )
Entonces:
L( a ) = { a }

L( a|b ) = { a,b } entonces ( L( a|b ) ) * = { ε, a, aa, …, b, bb, bbb, ….}


Operaciones:

( L( a|b ) ) * L( a ) = { ε, a, aa, …, b, bb, bbb, ….} { a } = { a, aa, aaa, …., ba , bba, bbba, …}
L( a ) ( L( a|b ) ) * L( a ) = L{ a } { a, aa, aaa, …., ba , bba, bbba, …} = { aa, aaa , aaaa, … , aba,
abba, abbba, …}

Cadena de a y b que comienzan y terminan con a.


Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

2. Inducción

( L( ε |a ) L( b) * ) *
Entonces:
L( b ) = { b } → ( L( b )*) = { ε, b ,bb ,bbb, …}

L( ε |a ) = { ε,a }
Operaciones:
L( ε |a ) L( b)* = { ε,a } { ε, b ,bb ,bbb, …} ={ b, bb, bbb, …., a ,ab, abb, abbb }

( L( ε |a ) L( b) * ) * = { ε ,bb , bbb, bbbb, …, aa, abab, abbabb, abbbabbb}

Cadena de a y b

3. Inducción

L( a|b )* L( a) L( a|b ) L( a|b )


Entonces:
L( a|b ) = { a,b } → L( a|b )* = { ε, a ,aa ,aaa, …, b, bb, bbb, …}
L( a ) = { a }

Operaciones:

L( a|b )* L( a) = { ε, a ,aa ,aaa, …, b, bb, bbb, …} { a } = { a, aa, aaa, …, ba, bba, bbba, …}
L( a|b )* L( a) L( a|b ) = { a, aa, aaa, …, ba, bba, bbba, …} { a,b } = {aa, aaa,aaaa, …,
baa,bbaa,bbbaa,…,ab,aab,aaab,…,bab,bbab,bbbab,…}
L( a|b )* L( a) L( a|b ) L( a|b ) = {aa, aaa,aaaa, …, baa,bbaa,bbbaa, …, ab,aab,aaab, …,
bab,bbab,bbbab,…}{ a,b } = { aaa, aaaa, …, baaa, bbaaa, bbbaaa, …, aba, aaba, aaaba, …,
baba, bbab, bbbaba, …, aab,aaab,aaaab, …,baab,bbaab,bbbaab, …abb,aabb,aaabb,
…,babb,bbabb,bbbabb,…}

Cadena de a y b terminada en a o b
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

4. Inducción a*ba*ba*ba*

L( a )* L( b) L( a )* L( b) L( a )* L( b) L( a )*
Entonces:
L( a ) = { a} → L( a )* = { ε, a ,aa ,aaa, …}
L( b ) = { b }
Operaciones:
L( a) *L( b ) = { ε, a ,aa ,aaa, …} { b } = { b, ab, aab,aaab,…}

L( a )* L( b) L( a )* = { b, ab, aab,aaab,…} { ε, a ,aa ,aaa, …}


= { b, ba, baa,...,ab, aabaa, aaabaaa,..}
L( a )* L( b) L( a )* L( b) = { b, ba, baa,...,ab, aabaa, aaabaaa,..} { b }
={ bb, bab, baab, …, abb, aabaab, aaabaaab,…}
L( a )* L( b) L( a )* L( b) L( a )* = { bb, bab, baab, …, abb, aabaab, aaabaaab,…} { ε, a ,aa
,aaa, …}
={ bb, baba , baabaa,… abb, aabba, aaabaabaa, aaabaaabaaa,…}

L( a )* L( b) L( a )* L( b) L( a )* L( b) L( a )*
={ bbb, bababa, baaabaabaa, …, abbb, aaabbaba, aaabaabaabaa, aaaabaaabaaabaaa,…}

Cadena de a y b que contiene tres b.

5. Inducción (aa|bb)*((ab|ba)(aa|bb)*(ab|ba)(aa|bb)*)*

L( aa|bb )*( L( ab|ba ) L( aa|bb )* L( ab|ba) L( aa|bb )* )*


Entonces:
L( aa|bb )= { aa, bb } → L( aa|bb )*= { ε,aa,aaaa,aaaaaa,…,bb,bbbbb,bbbbbb,…}
L( ab|ba ) = { ab, ba }
Operaciones:
L( aa|bb )*( L( ab|ba ) L( aa|bb )* L( ab|ba) L( aa|bb )* )*

={aa,aaaa,aaaaaa,…., bb,bbbb,…,aabb,aaaabbbb,….,bbaa,bbbbaaaa,…,abab, ababab,…}

Cadena de a y b que tiene un número par de a y b.


Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

3.3.3 En una cadena de longitud n, ¿cuántos de los siguientes hay?


a) Prefijos.
b ) Sufijos.
c) Prefijos propios.
d ) Subcadenas.
e) Subsecuencias.

a) Prefijo de n: una cadena que se obtiene eliminando cero o más símbolos desde
derecha de la cadena n.

b) Sufijo: de n: una cadena que se forma suprimiendo cero o más símbolos desde la
izquierda de una cadena n por ejemplo era es un sufijo de bandera.

c) Prefijos propios: cualquier cadena no vacía x que sea respectivamente, un prefijo,


sufijo o subcadena de n tal que n = x

d) Subcadenas de n: una cadena que se obtiene suprimiendo un prefijo y un sufijo de


n, por ejemplo: ande es una subcadena de bandera

e) Una subsecuencia es una secuencia que puede derivarse de otra secuencia


eliminando algunos o ningún elemento sin cambiar el orden de los elementos
restantes ejemplo: (i-0,n) C(n, i)

3.3.4 La mayoría de los lenguajes son sensible a mayúsculas y minúsculas por lo que la palabra
clave solo pueden escribirse de una forma y las expresiones regulares que describen su lexema
son muy simples. No obstante, algunos lenguajes como SQL son insensibles a mayúsculas y
minúsculas, por lo que una palabra clave puede escribirse en minúsculas o en mayúsculas, o en
cualquier mescla de ambas. Por lo que una palabra clave puede escribirse en minúsculas o en
mayúsculas, o en cualquier mescla de ambas. Por ende, la palabra clave SELECT de SQL
también puede escribirse como select, Select, o sELEct o sELEcT. Muestre como escribir una
expresión regular para una palabra Clave en un lenguaje insensible a mayúsculas y minúsculas.
Ilustre la idea escribiendo la expresión “select”.

((S)(s)(E)(e)(L)(l)(E)(e)(C)(c)(T)(t))
S[eleCt]* = SeleCt
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

s[ElecT]* = sElecT

3.3.5 Escriba definiciones regulares para los siguientes lenguajes:


a) Todas las cadenas de letras en minúsculas que contengan las cinco vocales en orden.
cadena -> consonantes *a(consonantes |a)* e(consonantes |e)*i(consonantes |i)*o(consonantes
|o)*u(consonantes |u)*
consonantes -> [bcdfghjklmnpqrstvwxyz]
b) T odas las cadenas de letras en minúsculas, en las que las letras se encuentren en orden
lexicográfico ascendente.
(a* b* ... z*)*
c) Comentarios, que consistan de una cadena rodeada por / * y * / , sin un * / entre ellos, a
menos que se encierre entre dobles comillas (").
\/\*([^*"]*|".*"|\*+[^/])*\*\/
d) Todas las cadenas de dígitos sin dígitos repetidos. Sugerencia: Pruebe este problema
primero con unos cuantos dígitos, como {0, 1, 2}.
[0|1,5] [6|7,9]
e) Todas las cadenas de dígitos que tengan por lo menos un dígito repetido.
2(3|4*) (5|6*)7

f) Todas las cadenas de as y bs con un número par de as y un número impar de bs.


cadena -> (FE*G|(aa)*b)(E|FE*G)
E -> b(aa)*b
F -> a(aa)*b
G -> b(aa)*ab|a
F -> ba(aa)*b
g) El conjunto de movimientos de Ajedrez, en la notación informal, como p -k 4 o kbp xqn.
a,h = Torre
b,g = caballo
c,f = arfil
d = rey
e = Dama
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

Posición 7= piones

a b c d e f g h
8 8
7 7
6 6
5 5
4 4
3 3
2 2
1 1
a b c d e f g h

1.e4 e5 2.f4 exf4 3.Bc4 Qh4+ 4.Kf1 b5 5.Bxb5 Nf6 6.Nf3 Qh6 7.d3 Nh5 8.Nh4 Qg5 9.Nf5 c6 10.g4
Nf6 11.Rg1 cxb5 12.h4 Qg6 13.h5 Qg5 14.Qf3 Ng8 15.Bxf4 Qf6 16.Nc3 Bc5 17.Nd5 Qxb2 18.Bd6
Bxg1 19.e5 Qxa1+ 20.Ke2 Na6 21.Nxg7+ Kd8 22.Qf6+ Nxf6 23.Be7# 1-0
!! h) Todas las cadenas de as y que que no contengan la subcadena abb.
(a*b) (b|a*)

i) Todas las cadenas de as y fe que no contengan la subsecuencia abb.


b* | b*a+ | b*a+ba*
3.3.6 Escriba clases de caracteres para los siguientes conjuntos de caracteres:
a) Las primeras diez letras (hasta “j”), ya sea en mayúsculas o en minúsculas.
[A-Ja-j]
b) Las con son antes en minúsculas.
(b|c|d|f|g|h|j|k|l|m|n|ñ|p|q|r|s|t|v|w|x|y|z)
c) Los “dígitos” en un número hexadecimal (elija mayúsculas o minúsculas para los “dígitos”
mayores a 9).
[0-9a-f]
d) Los caracteres que pueden aparecer al final de una oración legítima e n inglés (por ejemplo,
el signo de admiración).
(…|.|?|!|$|*)
Los siguientes ejercicios, hasta e incluyendo el ejercicio 3.3.10, tratan acerca de la notación
de expresiones regulares extendidas de Lex (el generador de analizadores léxicos que veremos
con detalle en la sección 3.5). La notación extendida se presenta en la figura 3.8.
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

3.3.7 Observe que estas expresiones regulares proporcionan a todos los siguientes símbolos
(caracteres de operadores) un significado especial:
\".~$[]+?{}|/
Su significado especial debe desactivarse si se necesitan para representarse a sí mismos en una
cadena de caracteres. Para ello, debemos colocar el carácter entre comillas, dentro de una
cadena de longitud uno o más; por ejemplo, la expresión regular "**" coincide con la cadena
**. También podemos obtener el significado literal de un carácter de operador si le
anteponemos una barra diagonal inversa. Por ende, la expresión regular \ * \ * también
coincide con la cadena **. Escriba una expresión regular que coincida con la cadena "\
\"\\
3.3.8 En Lex, una clase de carácter complementado representa a cualquier carácter, excepto los
que se listan en la clase de carácter. Denotamos a un carácter complementado mediante el uso
de ^ como el primer carácter; este símbolo no forma en sí parte de la clase que se está
complementando, a menos que se liste dentro de la misma clase. Así, [^A-Za-z] coincide con
cualquier carácter que no sea una letra mayúscula o minúscula, y [^\^] representa a cualquier
carácter excepto ^ (o nueva línea, ya que el carácter nueva línea no puede estar en ninguna
clase de caracteres). Muestre que, para cualquier expresión regular con clases de caracteres
complementados, hay una expresión regular equivalente sin clases de caracteres
complementados.
[^A-Za-z] = [0-9]
[^A-Z] = [a-z0-9]
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

[^\^]= ϵ
Ejercicio 3.3.9: La expresión regular 𝑟{𝑚, 𝑛}coincide con las ocurrencias entre m y n del patrón r. Por
ejemplo, 𝑎{𝑚, 𝑛}coincide con una cadena de una a cinco a’s. Muestre que para cada expresión regular que
contiene operadores de repetición de esta forma, hay una expresión regular equivalente sin operadores de
repetición.

Solución

Para cada expresión regular 𝑟{𝑚, 𝑛} siendo:

𝑚, 𝑛 números enteros

𝑟 una expresión regular

Hay una expresión regular equivalente, que es:

𝑟1 𝑟2 𝑟3 . .. 𝑟𝑚 | 𝑟1 𝑟𝑟2 𝑟3 . . . 𝑟𝑚 𝑟𝑚+1 | . . . | 𝑟1 𝑟𝑟2 𝑟3 . . . 𝑟𝑛−1 𝑟𝑛 , con 𝑟1 𝑟𝑟2 𝑟3 . . . 𝑟𝑚 . . . 𝑟𝑛 = 𝑟

Por ejemplo:

Tenemos la expresión regular en Lex letra:

Letra [a-z]

{𝑙𝑒𝑡𝑟𝑎}{2,4} {𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}|{𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}|{𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}{𝑙𝑒𝑡𝑟𝑎}

Ejercicio 3.3.10: El operador ˄ coincide con el extremo izquierdo de una línea, y $ coincide con el extremo
derecho de una línea. El operador ˄ también se utiliza para introducir las clases de caracteres
complementados, pero el con texto siempre deja en claro cuál es el significado deseado. Por ejemplo, ˄ [˄
a e i o u] *$ coincide con cualquier línea completa que no contiene una vocal en minúscula.

a) ¿Cómo podemos saber cuál es el significado deseado de ˄?


• Fijándonos en cómo está definida la expresión regular en Lex, ya que si ˄ está junto a los
símbolos del alfabeto significa que es la negación de esos tales símbolos, es decir
cualquier símbolo del alfabeto excepto los mencionados en la expresión regular. Y
también hay que fijarnos si lo utilizamos como el comienzo de una línea. Es decir hay que
fijarnos si esta en la clase de los caracteres

Por ejemplo:

[˄a-z] es complemento.

˄[a-z] es comienzo de línea.

b) ¿Podemos sustituir siempre una expresión regular, usando los operadores ˄ y $, por una
expresión equivalente que no utilice ninguno de estos operadores?
• Aunque se demostró dos ejercicios atrás, que podemos remplazar una expresión regular
que utiliza ˄ como complemento por otra expresión regular equivalente, no existe una
expresión regular para remplazar ˄ como comienzo de una línea, por lo que no podríamos
sustituir siempre una expresión regular.

Ejercicio 3.3.11: El comando del intérprete (shell) de UNIX sh utiliza los operadores de la figura 3.9 en
expresiones de nombres de archivo para describir conjuntos de nombres de archivos. Por ejemplo, la
Integrantes: Julian Rosero, Christian Diaz, Michael Borja Lenguajes y Compiladores

expresión de nombre de archivo ∗. 𝑜 coincide con todos los nombres de archivo que terminen en . 𝑜;
𝑜𝑟𝑑𝑒𝑛1 . ? coincide con todos los nombres de archivo de la forma 𝑜𝑟𝑑𝑒𝑛. 𝑐,

1
2
3
4
5

en donde c es cualquier carácter. Muestre cómo pueden sustituirse las expresiones de nombres de archivo
de sh por expresiones regulares equivalentes, usando sólo los operadores básicos de unión, concatenación
y cerradura.

Solución

Ejemplo de nombres en unix:

• *.c hola.c ejecutable.c cs1561.c 231651.c , es decir cualquier cadena


terminada en c
• Martin.x Martin.x , es decir tal y como está escrito

Ahora pasemos esto, a expresiones regulares en Lex que ya conocemos para:

1. ‘s’ 𝑠 siendo s la cadena exactamente


2. \c c siendo c un carácter
3. * [a − zA − Z0 − 9] +, puede haber 1 o más dígitos o letras para la cadena
4. ¿ [a − zA − Z], solo puede existir una letra o carácter
5. [s] [mArtingArrIx], cualquier carácter que se encuentra en la cadena en los corchetes

Ejercicio 3.3.12: SQL permite una forma rudimentaria de patrones, en los cuales dos caracteres tienen un
significado especial: el guion bajo (_) representa a cualquier carácter y el signo de por ciento (%)
representa a cualquier cadena de 0 o más caracteres. A demás, el programador puede definir cualquier
carácter, por decir e, para que sea el carácter de escape, de manera que si colocamos a e antes de e antes
de _, % o cualquier e, obtenemos el carácter que va después de su significado literal. Muestre cómo
expresar cualquier patrón de SQL como una expresión regular, dado que sabemos cuál es el carácter de
escape.

Tenemos

Patrones SQL Coincide con Expresión Regular Lex


- (Guión bajo) Cualquier carácter [a-zA-Z]
% Cualquier cadena de 0 o más [a-zA-Z]+
caracteres
e Carácter de escape, para capturar lo e$
que va despues

También podría gustarte