Você está na página 1de 10

Captulo 1

Introduo ao Flex
Objectivos:
Familiarizao com a ferramenta FLEX;
Introduo ao reconhecimento de padres e expresses regulares;
Aprendizagem dos conceitos atravs da realizao de alguns exerccios;
Apresentar o ambiente de trabalho proposto (seco 1.6);
Relembrar alguns comandos bsicos de Linux importantes para a utilizao
do FLEX (seco 1.7).

1.1

Analisadores lxicos

Um analisador lxico (scanner ) um programa que permite ler os caracteres de


um ficheiro de texto (e.g., programafonte) e produzir uma sequncia de componentes lxicos (tokens) que sero utilizados pelo analisador sintctico (parser ) e/ou
identificar erros lxicos na entrada. Alm de sua funo bsica, o analisador lxico
em geral est encarregue de fazer algumas tarefas secundrias, designadamente, a
eliminao de comentrios, espaos em branco e tabulaes.
Um token representa um conjunto de cadeias de entrada possvel e por sua vez,
um lexema uma determinada cadeia de entrada associada a um token. Considere
os exemplos apresentados na tabela 1.1.
O FLEX uma ferramenta que permite gerar analisadores lxicos. Estes analisadores so capazes de reconhecer padres lxicos em texto (e.g., nmeros, identificadores e palavraschave de uma determinada linguagem de programao). O
analisador construdo com base num conjunto de regras. Uma regra constituda
por um par, padroaco, o padro (expresso regular) descreve o elemento a reconhecer e aco (ou conjunto de aces) define o procedimento que ser realizado
no caso de identificao positiva do padro.

1.2. MODO DE UTILIZAO DO FLEX

1. Introduo ao Flex

Tabela 1.1: Tokens e lexemas


Tokens
Lexemas
FOR
for
IF
if
WHILE
while
NMERO
1089, 142857, 0.2, 3.14159
IDENTIFICADOR
i, j, contador, nomeAluno
OP_SOMA
+
OP_MAIOR_IGUAL >=
ABRE_PAR
(

1.2

Modo de utilizao do FLEX

O ciclo de vida de um programa FLEX obedece estrutura apresentada na figura


1.1.
Erros de
FLEX

ficheiro
fonte flex
.flex

FLEX

Erros de
compilao

ficheiro
fonte C
.c

Compilador
(gcc)

Ficheiro
texto n
Ficheiro
texto 2
Ficheiro
texto 1

programa
executvel

Resultado
n

Resultado
2
Resultado
1

Figura 1.1: Ciclo de vida de um programa FLEX


Com base num ficheiro fonte escrito de acordo com a sintaxe do FLEX, o programa FLEX gerar um analisador lxico descrito na linguagem C. Em caso de
existirem erros de codificao, o FLEX gerar uma listagem de erros. O ficheiro
fonte em C ter de ser compilado para a plataforma em utilizao utilizando um
compilador da linguagem C adequado (neste caso o GCC). O resultado final da
compilao ser um programa executvel capaz de identificar os padres definidos
pelo programado e levar o conjunto de aces previsto. Como entrada para o analisador gerado podem ser fornecidos ficheiros de texto ou alternativamente fornecer
os dados directamente pelo standard de entrada.
No exemplo seguinte so apresentados os passos necessrios compilao e utilizao de um programa FLEX. Considerese a existncia de um ficheiro ficheiro.flex
com o programa FLEX j escrito.

1. Introduo ao Flex

1.3. FORMATO DE UM FICHEIRO FLEX

flex ficheiro.flex
gcc lex.yy.c -lfl
./a.out
O comando flex gera, por omisso, um ficheiro com o nome lex.yy.c que
dever ser compilado, por exemplo com o gcc. Na utilizao do gcc necessrio
indicar a utilizao da biblioteca FLEX adicionando o parmetro -lfl. Por sua
vez, o compilador de C gera, por omisso, um ficheiro com o nome a.out. Por
ltimo, para a execuo deste programa basta a evocao do seu nome na linha
de comandos. Neste caso, a introduo dos dados ter de ser realizada via consola
(terminando obrigatoriamente com Ctrl+D).
flex Exemplo.flex -oExemplo.c
gcc Exemplo.c -o Programa -lfl
./Programa < Dados.txt
Neste exemplo, o comando flex gera a partir do ficheiro Exemplo.flex, o
ficheiro com o nome Exemplo.c que dever ser compilado. Nesta utilizao apresentada do gcc, indicado o nome do executvel a ser gerado, neste caso, Programa.
Na execuo do Programa, a introduo dos dados realizada a partir do ficheiro
Dados.txt.

1.3

Formato de um ficheiro FLEX

Um programa em FLEX constitudo por trs seces, a saber, declaraes, regras


e rotinas auxiliares. A separao entre as seces feita inserindo uma linha com
o smbolo %%.
Considerese o seguinte exemplo que ser discutido nas seces seguintes.
1

%{
int numChars=0;

2
3

%}

4
5

%%

6
7

{
numChars++;
p r i n t f ( "%s " , y y t e x t ) ;

8
9

10
11
12

\n

{
numChars++;
p r i n t f ( "\n" ) ;

13
14
15

1.3. FORMATO DE UM FICHEIRO FLEX

1. Introduo ao Flex

16
17

%%

18
19
20
21
22

main ( )
{
yylex ( ) ;
p r i n t f ( "Nmero de c a r a c t e r e s %d\n" , numChars ) ;

23
24

1.3.1

Declaraes

Esta seco compreende duas partes:


Instrues C nesta parte, delimitada pelos smbolos %{ e %}, so
colocadas as instrues da linguagem C que posteriormente sero includas
no incio do ficheiro C a gerar pelo FLEX. Os exemplos mais comuns so a
incluso de ficheiros de cabealhos ( headers, .h), declaraes de variveis e
constantes.
1
2
3
4

/ D e f i n i o da v a r i v e l numChars /
%{
int numChars=0;
%}

Expresses regulares nesta parte, podem ser declaradas macros para as


expresses regulares mais comuns como por exemplo algarismo ou letra do
alfabeto.
/ D e f i n i o de macros /
ALGARISMO [0 9] / Algarismo /
ALFA [ azAZ ] / L e t r a do a l f a b e t o /

1
2
3

A utilizao de macros para expresses regulares ser explicada com detalhe


mais adiante.

1.3.2

Regras (definio de padres e aces)

Nesta seco so definidas as expresses regulares (padres) e as respectivas aces


que se pretendem realizar no caso da identificao positiva (pattern matching) do
referido padro.
No caso de um qualquer carcter excepto mudana de linha (representado por
.) incrementada a varivel num_chars e impresso o referido carcter no standard
de sada. A mudana de linha (representado por \n) tambm contabilizada como
um carcter e escrita no standard de sada.

1. Introduo ao Flex

1.3. FORMATO DE UM FICHEIRO FLEX

As expresses regulares tm de ser obrigatoriamente escritas na primeira


coluna do ficheiro.
1

{
numChars++;
p r i n t f ( "%s " , y y t e x t ) ;

2
3

4
5
6

\n

{
numChars++;
p r i n t f ( "\n" ) ;

7
8

Na seco 1.8 so apresentados alguns dos padres mais relevantes utilizados


pelo FLEX.
o analisador lxico gerado funciona de acordo com as seguintes regras:
Apenas uma regra aplicada entrada de dados;
A aco executada corresponde expresso que consome o maior nmero de
caracteres;
Caso existam duas ou mais expresses que consumam igual nmero de caracteres, tem precedncia a regra que aparece em primeiro no ficheiro.
Quando um padro reconhecido, a sequncia de caracteres consumida (token)
na identificao do padro guardada na varivel yytext (do tipo char *). Para
alm disso, o comprimento da referida sequncia guardado na varivel yyleng1
(do tipo int).

1.3.3

Rotinas em C de suporte

Nesta seco pode ser escrito o cdigo C que se pretende que seja adicionado ao
programa a gerar pelo FLEX. Tipicamente este cdigo inclui o corpo do programa,
designadamente, a funo main() da linguagem C.
1
2
3
4
5

main ( )
{
yylex ( ) ;
p r i n t f ( "Nmero de c a r a c t e r e s %d\n" , numChars ) ;
}
A funo yylex() evoca o analisador lxico gerado pelo flex que processar as
expresses regulares anteriormente descritas (ver seco 1.3.2).
1
O valor desta varivel poderia ser obtido atravs da instruo da linguagem C
strlen(yytext)

1.4. EXEMPLO MAIS ELABORADO

1.4

1. Introduo ao Flex

Exemplo mais elaborado

Considere o seguinte exemplo, no qual contabilizado a quantidade de nmeros


e de linhas existentes no ficheiro. Neste exemplo recorrese utilizao de uma
macro para a definio de algarismo.
1
2
3

%{
int qtdNumeros =0, nLinhas =0;
%}

4
5

ALGARISMO

[0 9]

6
7

%%

8
9
10

/ Se a aco f o r d e s c r i t a numa s l i n h a
as c h a v e t a s podem s e r o m i t i d a s /

11
12
13
14

\n
{ALGARISMO}+
.

nLinhas++;
{ p r i n t f ( "d%s \n" , y y t e x t ) ; qtdNumeros++}

15
16
17
18
19
20
21
22

%%
main ( )
{
yylex ( ) ;
p r i n t f ( "# l i n h a s=%d\n" , nLinhas ) ;
p r i n t f ( "# numeros=%d\n" , qtdNumeros ) ;
}
Todos os caracteres no processados pelas duas primeiras expresses regulares
so consumidos pela ltima qual no corresponde nenhuma aco particular.

1.5

Propostas de exerccios

a) Escrever um programa que permite contar o nmero de ocorrncias de uma


cadeia de caracteres;
b) Escrever um programa que permite substituir uma cadeia de caracteres por
outra;
c) Escrever um programa que dado um ficheiro de texto, mostra:
nmero de algarismos;
nmero de letras do alfabeto;

1. Introduo ao Flex

1.6. AMBIENTE DE TRABALHO

nmero de linha de texto;


nmero de espaos ou tabulaes (\t);
nmero de caracteres no identificados nos pontos anteriores;
d) Escrever um programa que permite identificar nmeros naturais;

Entrada
123 abc 12.45 s 245 xyz
xyz 2 abc 45 cc

Sada
123 12 45 245
2 45

e) Escrever um programa que permite identificar nmeros inteiros (com ou sem


sinal);
f) Escrever um programa que permite identificar nmeros com parte decimal
(com ou sem sinal);

1.6

Ambiente de trabalho

O acesso a uma mquina LINUX pode ser realizado utilizando o programa putty
que est instalado em c:putty em modo SSH (ver figura 1.2). As mquinas a
utilizar devero ser ssh, ssh1 e ssh2.

Figura 1.2: Acesso SSH via putty


7

1.7. RESUMO DE COMANDOS UNIX TEIS

1. Introduo ao Flex

A edio dos ficheiros fonte pode ser realizada a partir de qualquer editor de
texto bsico (e.g., no ambiente Windows existe o Programmers Notepad) desde
que os ficheiros sejam gravados em formato Unix.

1.7

Resumo de comandos UNIX teis

Na tabela 1.2 so apresentados os comandos que permitem fazer mudana de directrio e mostrar qual o directrio actual.

Comando
cd
cd ..
cd <DIR>
pwd

Tabela 1.2: Mudar e mostrar directrio


Descrio
Mudar para o directrio home
Mudar para o directrio pai
Mudar para o directrio DIR
Mostra o path do directrio actual

Na tabela 1.3 so apresentados os comandos que permitem listar o contedo de um


determinado directrio.

Tabela 1.3: Listagem do contedo de um directrio


Comando
Descrio
ls
Mostra contedo do directrio actual
ls -a
idem incluindo ficheiros escondidos
ls -la
idem incluindo ficheiros escondidos sob a forma de
lista
ls <DIR> -l Mostra contedo do directrio DIR sob a forma de lista
Na tabela 1.4 so apresentados os comandos que permitem alterar as permisses
de acesso a ficheiros e/ou directrios. As permisses podem ser de trs tipos:
Leitura (r) permite visualizar o contedo quando de se trate de ficheiros,
no caso de directrios, permite fazer um ls;
Escrita (w) permite alterar o contedo quando de se trate de ficheiros e no
caso de directrios permite criar ficheiros/directrios no referido directrio;
Execuo (x) permite executar um programa, quando de se trate de ficheiros, no caso de directrios, permite aceder aos seus contedos;
As permisses de acesso a um ficheiro ou directrio esto subdivididas por trs
grupos de utilizadores:

1. Introduo ao Flex

1.8. PADRES UTILIZADOS NO FLEX

Tabela 1.4: Alterao de permisses de acesso de ficheiros/directrios


Comando
Descrio
chmod u+rwx,go-rw <FICH> Concede as permisses rwx para o utilizador;
retira as permisses rw para utilizadores do
mesmo grupo e outros; as outras permisses
no so alteradas
chmod u+rwx,go+rx <DIR>
Concede as permisses rwx para o utilizador;
concede as permisses rx para utilizadores
do mesmo grupo e outros; as outras permisses no so alteradas
chmod 751 <DIR>
Concede somente as permisses: rwx (7 =
4 + 2 + 1) para o utilizador, rx (5 = 4 + 1)
para utilizadores do mesmo grupo e x (1)
para outros utilizadores
o prprio (owner );
o grupo (group);
restantes (other ).
Considere o seguinte extracto resultado da execuo do comando ls -la no
qual o primeiro campo faz a codificao das permisses leitura, escrita e execuo
(rwx) para cada grupo. Estas permisses podem ser convertidas para um valor
numrico somando 4 para r, 2 para w e 1 para x.
-rwxr----drwx--x---

1 user
4 user

profs
profs

25 Jan 27 2002 fich


4096 Jan 17 16:31 dir/

Neste exemplo, o ficheiro fich tem permisses de leitura, escrita e execuo


para o prprio, leitura para o grupo e nenhuma para os restantes utilizadores. Por
sua vez, o directrio dir (o primeiro carcter um d no caso de directrios) tem
permisses de leitura, escrita e execuo para o prprio, execuo para o grupo e
nenhuma para os restantes utilizadores.

1.8

Padres utilizados no FLEX

Na tabela 1.5 so apresentados alguns dos padres mais relevantes utilizados pelo
FLEX.

1.8. PADRES UTILIZADOS NO FLEX

1. Introduo ao Flex

Tabela 1.5: Padres utilizados no FLEX


Padro
x
.
\n
[xyz]
xyz
[a-zA-Z]
[-+*/]

[abj-oZ]
[A-Z\n]
r*
r+
r?
r{2,5}
r{2,}
r{4}
{macro}
(r)
xyz*
(xyz)*
r|s
r
r$
xyz$
<<EOF>>

Descrio
O carcter x
Qualquer carcter excepto mudana de linha
Mudana de linha
Um dos caracteres x, y ou z
A cadeia de caracteres xyz
Um dos caracteres no intervalo de a a z ou de A a Z
Qualquer um dos operadores -, +, * ou /, send que o
smbolo - tem de aparecer em primeiro lugar dada a possibilidade de ambiguidade com a definio de intervalo
Um dos caracteres a, b ou de j a o ou Z
Qualquer carcter excepto no intervalo de A a Z ou mudana de linha
O carcter r zero ou mais vezes
O carcter r uma ou mais vezes
O carcter r zero ou uma vez
O carcter r repetido de duas a cinco vezes
O carcter r repetido pelo menos duas vezes
O carcter r repetido exactamente quatro vezes
Substituio/Expanso da macro definida anteriormente
O carcter r, sendo que os parntesis permitem estipular precedncias
A sequncia xy seguida de zero ou mais zs
A sequncia xyz repetida zero ou mais vezes
O carcter r ou s (alternativa)
O carcter r apenas se no incio da linha
O carcter r apenas se no final da linha (no consome o \n)
Uma linha que contm apenas a cadeia de caracteres xyz
Fim de ficheiro

10

Você também pode gostar