Sei sulla pagina 1di 16

UEMG UNIVESIDADE DO ESTADO DE MINAS GERAIS ISEPI INSTITUTO SUPERIOR DE ENSINO E PESQUISA DE ITUIUTABA FEIT FUNDAO EDUCACIONAL DE ITUIUTABA

ENTENDIMENTO E CRIAO DE UM ANALISADOR LXICO

Flavio Rodrigues

ITUIUTABA - MG 2013

ENTENDIMENTO E CRIAO DE UM ANALISADOR LXICO

Flavio Rodrigues

Trabalho de aproveitamento do Curso de Engenharia de Computao da Fundao Educacional de Ituiutaba-FEIT e Universidade do Estado de Minas Gerais UEMG como pr-requisito para obteno parcial de crditos na disciplina de compiladores sob orientao da Prof. Dr. Mnica Rocha.

ITUIUTABA - MG 2013

Resumo
Este trabalho traz as fazes de desenvolvimento e gerao de um analisador lxico, sendo este o objeto de estudo. Para tal desenvolvimento, foi escolhido o Software Gerador de Analisadores Lxicos e Sintticos (GALS), sendo este uma ferramenta eficaz para gerao de analisadores lxicos e analisadores sintticos e com proposito didtico auxiliando na construo de Compiladores.

Introduo
Analisadores Lxicos e Sintticos so importantes partes de um compilador. Sua construo sem a utilizao de ferramentas de auxlio pode levar a erros no projeto, alm de ser um trabalho desnecessrio. Existem hoje diversas ferramentas comerciais semelhantes, porm a maioria delas gera apenas ou o Analisador Lxico ou o Sinttico, o que obriga o usurio a conhecer duas ferramentas distintas e leva a incompatibilidades no momento da utilizao em conjunto dos analisadores gerados. Muitas ferramentas geram analisadores segundo uma nica tcnica de anlise sinttica, o que limita seu valor didtico. Praticamente todas geram analisadores em apenas uma linguagem objeto, diminuindo sua flexibilidade. Outro fator agravante o fato de serem ferramentas de cdigo fechado, o que impede que se possa provar formalmente o analisador gerado, j que no se tem acesso a seu cdigo fonte. Tambm existem ferramentas livres (gratuitas e de cdigo aberto) para esta tarefa. A maioria apresenta as mesmas limitaes citadas acima. Mas, por se tratarem de software, livre tm a vantagem de poderem ter seu cdigo-fonte analisado, verificando-se assim se o que fazem realmente aquilo que se prope a fazer. O GALS tenta superar estes problemas e se tornar uma ferramenta prtica e verstil, com aplicabilidade tanto como ferramenta didtica como para uso profissional, promovendo assim o uso das tcnicas formais de anlise.

1. Teoria das Linguagens - Analisador Lxico


Um analisador lxico, ou scanner, um programa que implementa um autmato finito, reconhecendo (ou no) strings como smbolos vlidos de uma linguagem. A implementao de um analisador lxico requer uma descrio do autmato que reconhece as sentenas da gramtica ou expresso regular de interesse.
Ele l o texto do programa e o divide em tokens, que so os smbolos bsicos de uma linguagem de programao. Eles representam palavras reservadas, identificadores, literais numricos e de texto, operadores e pontuaes. Comentrios no texto do programa geralmente so ignorados pelo analisador.

1.1Funes de um Analisador Lxico


Um analisador lxico possui funes importantes e que caracterizam seu funcionamento e utilizao. A classificao e extrao dos tokens que compe o texto do programa fonte uma das principais funes de um analisador lxico Entre a classe de tokens mais encontradas em analisadores lxicos esto: identificadores, palavras reservadas, nmeros inteiros, cadeias de caracteres, caracteres especiais simples e compostos. Espaos em branco, smbolos separadores e comentrios so irrelevantes na gerao de cdigo podendo ser eliminados pelo analisador lxico.

1.2 Classificao das gramticas


As gramticas foram agrupadas em quatro classes ou tipos, para facilitar seu estudo. Esta classificao foi feita por Chomsky, de acordo com capacidade representativa das gramticas. Tipo 0 (Gramtica sem Restries): Esta classe engloba todas as gramticas

possveis. Tipo 1 (Gramticas Sensveis ao Contexto): Possui a seguinte restrio:

Para toda produo X ::= Y pertencente gramtica, |X| <= |Y| (o tamanho de X menor que o tamanho de Y)

Tipo 2 (Gramticas Livres de Contexto): Possui a restrio das gramticas tipo 1, e suas produes devem ser da forma A ::= Y, com A N, e Y (N T)*

Tipo 3 (Gramticas Regulares): Alm das restries das gramticas tipo2, as tipo 3 s podem ter produes das formas: A ::= aB, com A e B N, e a T, ou A ::= a, com A N, e a T. Vale a pena notar que em gramticas tipo 2 e 3, produes do tipo A ::= so

permitidas, mesmo que elas quebrem a regra das gramticas tipo 1 (o tamanho de e 0, que menor que o tamanho do lado esquerdo da produo). Isto possvel graas a um teorema que prova que para toda gramtica tipo 2 ou tipo 3 com este tipo de produo, pode-se escrever uma equivalente sem este tipo de produo.

1.3 Expresses Regulares


Expresses regulares podem ser expressas atravs da teoria de linguagens formais. Elas consistem de constantes e operadores que denotam conjuntos de cadeias de caracteres e operaes sobre esses conjuntos, respectivamente. Dado um alfabeto finito , as seguintes constantes so definidas:

(conjunto vazio) denotando o conjunto (cadeia de caracteres vazia) denotando o conjunto {} (literal) a em denotando o conjunto {a}

As seguintes operaes so definidas:

(concatenao) RS denotando o conjunto { | em R e em S }. Por exemplo, {"ab", "c"}{"d", "ef"} = {"abd", "abef", "cd", "cef"}.

(alternncia) R|S denotando o conjunto unio de R e S. Usa-se os smbolos , + ou para alternncia ao invs da barra vertical. Por exemplo, {"ab", "c"}{"dv", "ef"} = {"ab", "c", "dv", "ef"}

Exemplos

a|b* denota {, a, b, bb, bbb, ...} (a|b)* denota o conjunto de todas as cadeias de caracteres que contm os smbols a e b, incluindo a cadeia vazia: {, a, b, aa, ab, ba, bb, aaa, ...} ab*(c|) denota o conjunto de cadeias de caracteres comeando com a, ento com zero ou mais bs e opcionalmente com um c: {a, ac, ab, abc, abb, ...}

A definio formal de expresses regulares concisa e evita a utilizao dos quantificadores redundantes ? e +, que podem ser expressados respectivamente por (a|) e aa*. Por vezes o operador de complemento ~ adicionado; ~R denota o conjunto das cadeias de caracteres de * que no esto em R. Esse operador redundante, e pode ser expressado usando outros operadores, apesar da computao para tal representao ser complexa.

2. Gals Gerador de Analisador Lxico


GALS uma ferramenta para a gerao automtica de analisadores lxicos e sintticos. Foi desenvolvido em Java, verso 1.4, de 10 de maro de 2003. Utilizado em qualquer ambiente para o qual haja uma mquina virtual Java. possvel gerar-se analisadores lxicos e sintticos, atravs de especificaes lxicas, baseadas em expresses regulares, e especificaes sintticas, baseadas em gramticas livres de contexto. Pode-se fazer os analisadores lxico e sinttico independentes um do outro, bem como fazer de maneira integrada. Existem trs opes de linguagem para a gerao dos analisadores: Java, C++ e Delphi. O GALS tenta ser um ambiente amigvel, tanto para uso didtico como para o uso profissional. O objeto de estudo em questo foi desenvolvido no GALS, utilizando toda a teoria estudada em sala de aula.

2.2 Utilizao do ambiente


atravs do ambiente que o usurio entra com sua especificao para a gerao do analisador. Est a viso inicial que se tem:

Nesta interface so definidos aspectos lxicos e sintticos de uma forma conjunta. Porm, dependendo da escolha que se faa, para gerar apenas o analisador lxico ou o sinttico, o ambiente rearranjado de modo adequado.

Os seguintes menus esto disponveis para o usurio: Arquivo Permite operaes bsicas, como abrir, salvar e criar novos arquivos, alm de importar especificaes sintticas do GAS. Ferramentas Possibilita modificar opes, verificar erros, simular os analisadores e gerar o cdigo dos analisadores lxico e sinttico. Documentao Exibe as tabelas de anlise. Ajuda Ajuda para o usurio.

2.3 Desenvolvimento do analisador Lxico


A especificao dos aspectos lxicos composta de duas partes: especificao dos tokens que o analisador deve reconhecer, e a descrio opcional de definies lxicas, que so como macros que podem ser usadas na definio dos tokens. Abaixo segue uma tabela demonstrando as representaes de tokens e expresses regulares para cada um deles:

Tokens
Numero Letra ID ABRECOLCH FECHACOLCH VIRGULA ATRIB ABREPAR FECHAPAR NEGACAO ADICAO SUB MENOR MAIOR BIT_OU MULT DIV MOD BIT_E PONTOVIRGULA Num

Expresses Regulares
[0-9] [a-zA-Z] ({Numero}+({Letra}{Letra}{Letra}){Numero}+) ["["] ["]"] [","] ["="] ["("] [")"] ["!"] ["+"] ["-"] ["<"] [">"] [|] [*] [/] [%] [&] [;] [({Numero}+)]

A imagem abaixo define onde e como devem ser escritas as expresses regulares:

Tm-se aqui duas definies regulares: Numero e Letra. Estas definies no influem em nada no analisador gerado, apenas facilitam a vida do usurio no sentido de que ele no precisa ficar repetindo uma expresso regular complexa na posterior definio dos tokens.

2.4 Definies regulares


Todas as definies regulares so da forma:
<IDENTIFICADOR> : <EXPRESSO REGULAR> S permitida uma definio por linha. Identificadores repetidos so considerados erros, que so reportados ao usurio. Pode-se ainda inserir comentrios de linha, que se iniciam com // e se estendem at o fim da linha.

2.5 Tokens

A forma geral da definio de um token :


<TOKEN> : <EXPRESSO REGULAR> S permitida a definio de um token por linha. So aceitos comentrios, da mesma forma que nas definies regulares.

3. Simulao
Abaixo segue a imagem com a simulao proposta no software GALS:

Atravs da imagem pode notar a forma que cada um dos tokens so implementados. Ao simular observa-se que o analisador lxico implementado est funcionando corretamente, pois ele separa cada um dos tokens informando o seu lexema e a posio que este lexema assume no simulador.

Concluses
Este trabalho foi importante para o entendimento da forma que um analisador lxico trabalha as formas de implementao e principalmente a principal funcionalidade deste analisador. A tutorial apresentado no menu ajuda do GALS auxiliou juntamente com a matria aplicada em sala de aula uma implementao de um analisador lxico.

ANEXO A
Cdigos fonte SyntaticError public class SyntaticError extends AnalysisError { public SyntaticError(String msg, int position) { super(msg, position); } public SyntaticError(String msg) { super(msg); } } Cdigos fonte LexicalError public class LexicalError extends AnalysisError { public LexicalError(String msg, int position) { super(msg, position); } public LexicalError(String msg) { super(msg); } } Cdigos fonte SemanticError public class SemanticError extends AnalysisError { public SemanticError(String msg, int position) { super(msg, position); } public SemanticError(String msg) { super(msg); } }

Cdigos fonte Lexico public class Lexico implements Constants { private int position; private String input; public Lexico() { this(new java.io.StringReader("")); } public Lexico(java.io.Reader input) { setInput(input); } public void setInput(java.io.Reader input) { StringBuffer bfr = new StringBuffer(); try { int c = input.read(); while (c != -1) { bfr.append((char)c); c = input.read(); } this.input = bfr.toString(); } catch (java.io.IOException e) { e.printStackTrace(); } setPosition(0); } public void setPosition(int pos) { position = pos; } public Token nextToken() throws LexicalError { if ( ! hasInput() ) return null;

int start = position; int state = 0; int lastState = 0; int endState = -1; int end = -1; while (hasInput()) { lastState = state; state = nextState(nextChar(), state); if (state < 0) break; else { if (tokenForState(state) >= 0) { endState = state; end = position; } } } if (endState < 0 || (endState != state && tokenForState(lastState) == -2)) throw new LexicalError(SCANNER_ERROR[lastState], start); position = end; int token = tokenForState(endState); if (token == 0) return nextToken(); else { String lexeme = input.substring(start, end); return new Token(token, lexeme, start); } } private int nextState(char c, int state) { int next = SCANNER_TABLE[state][c]; return next; }

private int tokenForState(int state) { if (state < 0 || state >= TOKEN_STATE.length) return -1; return TOKEN_STATE[state]; } private boolean hasInput() { return position < input.length(); } private char nextChar() { if (hasInput()) return input.charAt(position++); else return (char) -1; } } Cdigo Fonte Token public class Token { private int id; private String lexeme; private int position; public Token(int id, String lexeme, int position) { this.id = id; this.lexeme = lexeme; this.position = position; } public final int getId() { return id; } public final String getLexeme() { return lexeme; }

public final int getPosition() { return position; } public String toString() { return id+" ( "+lexeme+" ) @ "+position; }; } Cdigo fonte Constantes public interface Constants extends ScannerConstants { int EPSILON = 0; int DOLLAR = 1; int t_Num = 2; int t_Letra = 3; int t_ID = 4; int t_ABRECOLCH = 5; int t_FECHACOLCH = 6; int t_VIRGULA = 7; int t_ATRIB = 8; int t_ABREPAR = 9; int t_FECHAPAR = 10; int t_NEGACAO = 11; int t_ADICAO = 12; int t_SUB = 13; int t_MENOR = 14; int t_MAIOR = 15; int t_BIT_OU = 16; int t_MULT = 17; int t_DIV = 18; int t_MOD = 19; int t_BIT_E = 20; int t_PONTOVIRGULA = 21; }

Potrebbero piacerti anche