Você está na página 1de 16

Analse Lxica de Compiladores

Jos Rogrio de Oliveira da Silva

Cincia da Computao ASPER Associao Paraibana de Ensino Renovado Joo Pessoa, 21 de dezembro de 2011.

Resumo Esse trabalho apresenta uma compreenso sobre analse lxica de compiladores, como funciona um analisador lxico. Trasendo, de uma maneira mais clara, uma metodologia simples para melhor entendimento para estudantes de compiladores. Palavras chave: Anlise lxica, analisador lxico.

Anlise Lxica Anlise lxica o processo de analisar a entrada de linhas de caracteres (tal como o cdigo-fonte de um programa de computador) e produzir uma seqncia de smbolos chamado "smbolos lxicos" (lexical tokens), ou somente "smbolos" (tokens), que podem ser manipulados mais facilmente por um parser (leitor de sada). O componente do compilador responsvel pela execuo desse processo conhecido como Analisador lxico.

A anlise lxica a forma de verificar determinado alfabeto. Quando analisamos uma palavra, podemos definir atravs da anlise lxica se existe ou no algum caracter que no faz parte do nosso alfabeto, ou um alfabeto inventado por ns. a primeira etapa do processo de compilao e seu objetivo dividir o cdigo fonte em smbolos, preparado-o para a Anlise Sinttica. Neste processo pode-se destacar trs atividades como fundamentais:

Extrao e classificao dos tokens; Eliminao de delimitadores e comentrios; Recuperao de Erros.

O analisador lxico funciona de duas maneiras:

Primeiro estado da anlise: A primeira etapa l a entrada de caracteres, um de cada vez, mudando o estado em que os caracteres se encontram. Quando o analisador encontra um caracter que ele no identifica como correto, ele o chama de "estado morto" ento, ele volta ltima anlise que foi aceita e assim tem o tipo e comprimento do lxico vlido. Um lxico, entretanto, uma nica lista de caracteres conhecidas de ser

um tipo correto. Para construir um smbolo, o analisador lxico necessita de um segundo estado.

Segundo estado da anlise: Nesta etapa so repassados os caracteres do lxico para produzir um valor. O tipo do lxico combinado com seu valor o que adequadamente constitui um smbolo, que pode ser dado a um parser. (Alguns smbolos tais como parnteses no tm valores, e ento a funo da anlise no pode retornar nada). A anlise lxica escreve um parser muito mais fcil. Em vez de ter que

acumular, renomeia seus caracteres individualmente. O parser no mais se preocupa com smbolos e passa a preocupar-se s com questes de sinttica. Isto leva a eficincia de programao, e no eficincia de execuo.
2

Entretanto, desde que o analisador lxico o subsistema que deve examinar cada caracter nico de entrada, podem ser passos intensivos e o desempenhos se torna crtico, pode estar usando um compilador. As desvantagens da Anlise Lxica so o tratamento de dados em branco, formato fixo de entrada e a inexistncia de palavras reservadas, em determinadas linguagens. Funcionamento do Analisador Lxico O analisador lxico a primeira fase de um compilador. Sua tarefa principal a de ler os caracteres de entrada e produzir uma seqncia de tokens que o analisador sinttico utiliza. Essa interao, sumarizada esquematicamente na Figura 1, comumente implementada fazendo-se com que o analisador lxico seja uma sub-rotina ou uma co-rotina do analisador sinttico. Ao receber do analisador sinttico um comando obter o prximo token, o analisador lxico l os caracteres de entrada at que possa identificar o prximo token.

Programa Fonte

Analisador Lxico

Analisador Sinttico

Tabela de Smbolos Figura 1: Interao do analisador lxico com o analisador sinttico.

Como o analisador lxico a parte do compilador que l o texto-fonte, tambm pode realizar algumas tarefas secundrias ao nvel da interface com o usurio. Uma delas a de remover do programa-fonte os comentrios e os espaos em branco, os ltimos sob a forma de espaos, tabulaes e caracteres de avano de linha. Uma outra a de correlacionar as mensagens de erro do compilador com o programa-fonte. Por exemplo, o analisador lxico pode controlar o
3

nmero de caracteres examinados, de tal forma que um nmero de linha possa ser relacionado a uma mensagem de erro. Em alguns compiladores, o analisador lxico fica com a responsabilidade de fazer uma cpia do programafonte com as mensagens de erro associadas ao mesmo. Se a linguagem-fonte suporta algumas funes sob a forma de macros pr-processadas, as mesmas tambm podem ser implementadas na medida em que a anlise lxica v se desenvolvendo. Algumas vezes, os analisadores lxicos so divididos em duas fases em cascata, a primeira chamada de varredura (scanning) e a segunda de anlise lxica. O scanner responsvel por realizar tarefas simples, enquanto o analisador lxico propriamente dito realiza as tarefas mais complexas. Por exemplo, um compilador Fortran poderia usar um scanner para eliminar os espaos da entrada. Temas da Anlise Lxica Existem vrias razes para se dividir a fase de anlise da compilao em anlise lxica e anlise sinttica. 1. Um projeto mais simples talvez seja a considerao mais importante. A separao das anlises lxica e sinttica freqentemente nos permite simplificar uma ou outra dessas fases. Por exemplo, um analisador sinttico que incorpore as convenes para comentrios e espaos em branco significativamente mais complexo do que um que assuma que os mesmos j tenham sido removidos pelo analisador lxico. Se estivermos projetando uma nova linguagem, separar as convenes lxicas das sintticas pode levar a um projeto global de linguagem mais claro. 2. A eficincia do compilador melhorada. Um analisador lxico separado nos permite construir um processador especializado e potencialmente mais eficiente para a tarefa. Uma grande quantidade de tempo gasta lendo-se o programa-fonte e particionando-o em tokens. Tcnicas de buferizao especializadas para a leitura de caracteres e o processamento de tokens podem acelerar significativamente o desempenho de um compilador. 3. A portabilidade do compilador realada. As peculiaridades do alfabeto de entrada e outras anomalias especficas de dispositivos podem ser

restringidas ao analisador lxico. A representao de smbolos especiais ou no-padro, tais como ( ^ ) em Pascal, pode ser isolada no analisador lxico. Tokens, Padres, Lexemas Quando se fala sobre a anlise lxica, usamos os termos token, padro e lexema com significados especficos. Exemplos de seus usos so mostrados na Figura 2. Em geral, existe um conjunto de cadeias de entrada para as quais o mesmo token produzido como sada. Esse conjunto de cadeias descrito por uma regra chamada de um padro associado ao token de entrada. O padro dito reconhecer cada cadeia do conjunto. Um lexema um conjunto de caracteres no programa-fonte que reconhecido pelo padro de algum token. Por exemplo, no enunciado Pascal.

Const pi = 3.1416;

A subcadeia pi um lexema para o token como smbolos terminais na gramtica para a linguagem-fonte, usando nomes em negrito para representlos. Os lexemas reconhecidos pelo padro do token representam cadeias de caracteres no programa-fonte, e podem receber um tratamento conjunto, como instncias de uma mesma unidade lxica (por exemplo, instncias de identificadores, nmeros etc.). Na maioria das linguagens de programao, as seguintes construes so tratadas como tokens: palavras-chave, operadores, identificadores, constantes, literais, cadeias e smbolos de pontuao, como parnteses, vrgulas e ponto-e-vrgulas. No exemplo acima, quando a seqncia de caracteres pi aparece no programa-fonte, um token

representando um identificador repassado ao analisador sinttico. O repasse de um token freqentemente implementado transmitindo-se um inteiro associado ao token. justamente esse inteiro que designado por id na Figura 2. Um padro uma regra que descreve o conjunto de lexemas que podem representar um token particular nos programas-fonte. O padro para o token const na Figura 2 exatamente a cadeia singela const, que soletra a palavrachave. O padro para o token relacional o conjunto de todos os seis operadores relacionais de Pascal.
5

Certas convenes de linguagem aumentam a dificuldade da anlise lxica. Linguagens como Fortran requerem certas construes em posies fixas na linha de entrada. Dessa forma, o alinhamento de um lexema pode ser importante na determinao da correo de um programa-fonte. A tendncia no projeto moderno de linguagens de programao est na direo de entradas em formato livre, permitindo que as construes sejam colocadas em qualquer local da linha de entrada, e, por conseguinte, esse aspecto da anlise lxica vem se tornando menos importante. O tratamento dos espaos varia grandemente de linguagem para linguagem. Em algumas linguagens, os espaos no so significativos, exceto quando dentro de literais do tipo cadeia de caracteres. Podem ser adicionados vontade a fim de melhorar a legibilidade de um programa. As convenes relacionadas aos espaos podem complicar grandemente a tarefa de identificao dos tokens. Um exemplo popular que ilustra a dificuldade potencial em se reconhecer tokens o enunciado DO de Fortran. No comando DO 5 I = 1.25 No podemos afirmar que DO seja parte do identificador DO5I, e no um identificador em si, at que tenhamos examinado o ponto decimal. Por outro lado, no enunciado DO 5 I = 1,25 Temos sete tokens: a palavra-chave DO, o rtulo de enunciado 5, o identificador I, o operador =, a constante 1, a vrgula e a constante 25. Aqui no podemos estar certos, at que tenhamos examinado a vrgula, de que DO seja uma palavra-chave. Para aliviar esta incerteza, Fortran 77 permite que uma vrgula opcional seja colocada entre o rtulo e o ndice do enunciado DO ( no exemplo, a varivel I). O uso dessa vrgula encorajado porque a mesma ajuda a tornar o enunciado DO mais claro e legvel. Em muitas linguagens, certas cadeias so reservadas, isto , seus significados so predefinidos e no podem ser modificados pelo usurio. Se uma palavra-chave no for reservada, o analisador lxico precisar distinguir uma palavra-chave de um identificador

definido pelo usurio. Em PL/I, as palavras-chave no so reservadas; conseqentemente, as regras para essa distino so um tanto complicadas, como o seguinte enunciado PL/I ilustra:

SE ENTAO ENTAO ENTAO = SENAO; SENAO SENAO = ENTAO;

TOKEN Const Se Relacional Id Num Literal

LEXEMAS EXEMPLO const se <, <=, =, <>, >, >= PI, contador, D2 3.1416, 0, 6.02E23 contedo da memria

DESCRIO INFORMAL DO PADRO const se < ou <= ou = ou <> ou >= ou > letra seguida por letra e/ou dgito qualquer constante numrica quaisquer caractere entre aspas

Figura 2: Exemplo de tokens.

Atributos para os Tokens Quando um lexema for reconhecido por mais de um padro, o analisador lxico precisar providenciar informaes adicionais para as fases

subsequentes do compilador a respeito do lexema particular que foi reconhecido. Por exemplo, o padro num reconhece as duas cadeias O e 1, mas essencial para o gerador de cdigo ser informado sobre que cadeia foi efetivamente reconhecida, ou seja, no basta reconhecer num, tem que informar que ele vale 0 ou vale 1. O analisador lxico coleta informaes a respeito dos tokens em seus atributos associados. Os tokens influenciam decises na anlise gramatical; os atributos influenciam a traduo dos tokens. Do ponto de vista prtico, o token possui usualmente somente um nico atributo - um apontador para a entrada da tabela de smbolos na qual as informaes sobre os mesmos so mantidas; o apontador se torna o atributo do token. Para fins de diagnstico, podemos estar interessados tanto no lexema de um identificador quanto no nmero da linha na qual o mesmo foi
7

primeiramente examinado. Esses dois itens de informao podem, ambos, ser armazenados na entrada da tabela de smbolos para o identificador. Exemplo: Os tokens e os valores de atributos associados ao enunciado Fortran E = M * C ** 2 So escritos abaixo como uma seqncia de pares: <id, apontador para a entrada da tabela de smbolos para E >

<operador_de_atribuio,>

<id, apontador para a entrada da tabela de smbolos para M>

<operador_de_multiplicao,>

<id, apontador a para a entrada da tabela de smbolos para C>

<operador_de_exponenciao,>

<num, valor inteiro 2> Note-se que em certos pares no existe a necessidade de um valor de atributo; o primeiro componente suficiente para identificar o lexema. Nesse pequeno exemplo, ao token num foi associado um atributo de valor inteiro. O compilador pode armazenar a cadeia de caracteres que forma o nmero numa tabela de smbolos e deixar o atributo do token num ser o apontador para a entrada da tabela.

Erros Lxicos Poucos erros so distinguveis somente no nvel lxico, uma vez que um analisador lxico possui uma viso muito local do programa-fonte. Se cadeia fi for encontrada pela primeira vez num programa C, no contexto
8

Fi ( a == f (x) ) ... Um analisador lxico no poder dizer se Fi a palavra-chave se incorretamente grafada ou um identificador de funo no declarada. Como Fi um identificador vlido, o analisador lxico precisa retornar o token identificador e deixar alguma fase posterior do compilador tratar o eventual erro. Mas, suponhamos que acontea uma situao na qual o analisador lxico seja incapaz de prosseguir, porque nenhum dos padres reconhea um prefixo na entrada remanescente. Talvez a estratgia mais simples de recuperao seja a da modalidade pnico. Removemos sucessivos caracteres da entrada remanescente at que o analisador lxico possa encontrar um token bem-formado. Essa tcnica de recuperao pode ocasionalmente confundir o analisador sinttico, mas num ambiente de computao interativo pode ser razoavelmente adequada. Outras possveis aes de recuperao de erros so: 1. remover um caractere estranho 2. inserir um caractere ausente. 3. substituir um caractere incorreto por um correto 4. transpor dois caracteres adjacentes. Transformaes de erros como essas podem ser experimentadas numa tentativa de se consertar a entrada. A mais simples de tais estratgias a de verificar se um prefixo da entrada remanescente pode ser transformado num lexema vlido atravs de uma nica transformao. Essa estratgia assume que a maioria dos erros lxicos seja resultante de um nico erro de transformao, uma suposio usualmente confirmada na prtica, embora nem sempre. Uma forma de se encontrar erros num programa computar o nmero mnimo de transformaes de erros requeridas para tornar um programa errado num que seja sintaticamente bem-formado. Dizemos que um programa errado possui K erros se a menor seqncia de transformaes de erros que ir mape-lo em algum programa vlido possui comprimento K. A correo de erros de distncia mnima uma conveniente ferramenta terica de longo
9

alcance, mas que no geralmente usada por ser custosa demais de implementar. Entretanto, uns poucos compiladores experimentais tm usado o critrio da distncia mnima para realizar correes localizadas. Outra forma que pode ser adotada registrar como erro cada entrada que no se enquadra dentro dos padres definidos para a linguagem. Anlise Lxica no CSD Como foi dito anteriormente, a principal funo do analisador lxico ler os caracteres de entrada e produzir uma lista de token neste processo so removidos do programa fonte os comentrios e os espaos em branco que o analisador sinttico utilizar. Cada token representa um smbolo vlido na linguagem LPD. No CSD os token so representados internamente por uma estrutura formada por dois campos: Lexema: contm a seqncia de caracteres letras, nmeros, etc. que formam o token; Smbolo: este um campo do tipo numrico que contm uma representao interna para o token. Para aumentar a eficincia do sistema, toda a manipulao da estrutura do token ser feita utilizandose este campo. O CSD possui a seguinte tabela de smbolo:

10

TOKENS
LEXEMA Programas Incio Fim Procedimento Funo Se Ento Seno Enquanto Faca := escreva Lea Var Inteiro Boleano Identificador Nmero . ; , ( ) > >= = < <= <> + * Div E Ou No : SMBOLOS Sprograma Sincio Sfim Sprocedimento Sfuncao Sse Sentao Ssenao Senquanto Sfaca Satribuio Sescreva Slea Svar Sinteiro Sboleano Sidentificador Snmero Sponto sponto_virgula Svrgula sabre_parntese sfecha_parntese Smaior Smaiorig Sig Smenor Smenorig Sdif Smais Smenos Smult Sdiv Se Sou Snao Sdoispontos

Por exemplo, na anlise lxica da sentena abaixo

11

se contador > 10 { exemplo de comentrio } entao escreva (contador) senao escreva (x); gerada a seguinte lista de tokens LEXEMA
Se Contador > 10 Ento Escreva ( Contador ) Seno Escreva ( X ) ;

SMBOLOS
sse scontador smaior snmero sentao sescreva sabre_parntese scontador sfecha_parntese ssenao sescreva sabre_parntese sidentificador sfecha_parntese sponto_virgula

Os comentrios na linguagem CSD so feitos atravs do uso dos caracteres { para abrir um comentrio e } para fechar o comentrio , este caracteres assim como a seqncia de caracteres entre eles, no so considerados tokens pelo Analisador Lxico. Estrutura da Lista de Tokens A lista de Tokens uma estrutura de fila First in First out , formada por uma lista encadeada onde cada n possui o formato apresentado na figura abaixo.

LEXEMA

SMBOLOS

N na lista de tokens.

12

Os Algoritmos do Analisador Lxico no CSD Uma vez defina a estrutura de dados do analisador lxico, possvel descrever seu algoritmo bsico. No nvel mais alto de abstrao, o funcionamento do analisador lxico pode ser definido pelo algoritmo:

Algoritmo Analisador Lxico (Nvel 0) Inicio Abre arquivo fonte Enquanto no acabou o arquivo fonte Faa { Trata Comentrio e Consome espaos Pega Token Coloca Token na Lista de Tokens } Fecha arquivo fonte Fim Na tentativa de aproximar o algoritmo acima de um cdigo executvel, so feitos refinamentos sucessivos do mesmo. Durante este processo, surgem novos procedimentos, que so refinados na medida do necessrio.

Algoritmo Analisador Lxico (Nvel 1) Def. token: TipoToken Inicio Abre arquivo fonte Ler(caracter) Enquanto no acabou o arquivo fonte Faa {Enquanto ((caracter = {)ou (caracter = espao)) e (no acabou o arquivo fonte) Faa { Se caracter = { Ento {Enquanto (caracter } ) e (no acabou o arquivo fonte) Faa Ler(caracter) Ler(caracter)} Enquanto (caracter = espao) e (no acabou o arquivo fonte) Faa Ler(caracter)
13

} se caracter <> fim de arquivo ento {Pega Token Insere Lista} } Fecha arquivo fonte Fim. Algoritmo Pega Token Inicio Se caracter digito Ento Trata Digito Seno Se caracter letra Ento Trata Identificador e Palavra Reservada Seno Se caracter = : Ento Trata Atribuio Seno Se caracter {+,-,*} Ento Trata Operador Aritmtico Seno Se caracter {<,>,=} EntoTrataOperadorRelacional Seno Se caracter {; ,,, (, ), .} Ento Trata Pontuao Seno ERRO Fim. Algoritmo Trata Dgito Def num : Palavra Inicio num caracter Ler(caracter) Enquanto caracter dgito Faa { num num + caracter Ler(caracter) } token.smbolo snmero token.lexema num Fim. Algoritmo Trata Identificador e Palavra Reservada Def id: Palavra Inicio id caracter Ler(caracter) Enquanto caracter letra ou dgito ou _ Faa {id id + caracter
14

Ler(caracter) } token.lexema id caso id = programa : token.smbolo sprograma id = se : token.smbolo sse id = entao : token.smbolo sentao id = senao : token.smbolo ssenao id = enquanto : token.smbolo senquanto id = fim : token.smbolo sfim id = escreva : token.smbolo sescreva id = leia :token.smbolo sleia id = var : token.smbolo svar id = inteiro : token.smbolo sinteiro id = booleano : token.smbolo sbooleano id = verdadeiro : token.smbolo sverdadeiro id = falso : token.smbolo sfalso id = procedimento : token.smbolo sprocedimento id = funcao : token.smbolo sfuncao id = div : token.smbolo sdiv id = e : token.smbolo se id = ou : token.smbolo sou id = nao : token.smbolo snao seno : token.smbolo sidentificador Fim. Referncia Bibliogrfica
Ricardo Azambuja Silveira, slide: Linguagens Formais e compiladores, disponvel em http://migre.me/7eLVP , acessado 19 de dezembro de 2011. Ricardo Luiz de Freitas, Compiladores. Apostila Tcnica e Cientfica. Aleardo Manacero Junior, Analisador Lxico, disponvel em

http://migre.me/7eMFD, acessado em 15 de dezembro de 2011. Carlos Eduardo Gesser, monografia: Gerador de Analisadores Lxico e Sinttico, UFSC Florianpolis SC, fevereiro de 2003, disponvel em http://migre.me/7eMZE, acessado em 16 de dezembro de 2011.

15

16