capítulo 2 - analisador léxicoaleardo/cursos/compila/cap02.pdf · tabular se presta bem ao...

Download Capítulo 2 - Analisador Léxicoaleardo/cursos/compila/cap02.pdf · tabular se presta bem ao armazenamento das transições num computador, o que vai ser muito interessante durante

If you can't read please download the document

Upload: phamthuan

Post on 06-Feb-2018

218 views

Category:

Documents


0 download

TRANSCRIPT

  • Editado por Aleardo Manacero Jr.

    Captulo 2 - Analisador Lxico1. Expresses regulares 2. Autmatos de estado finito 3. AEF's e expresses regulares 4. Implementao do analisador lxico

    O compilador tem no seu analisador lxico o primeiro componente a entrar em contato com o cdigo fonte. Sua funo basica identificar os tokens presentes no cdigo fonte e passar essa informao para o parser. Isso significa que ele vai ocupar uma grandeparte do tempo de execuo do compilador, obrigando-nos a implement-lo de modo bastante eficiente para que o processo decompilao possa ocorrer de forma rpida. O procedimento de anlise lxica consiste em ler os caracteres de entrada e agrupa-los emconjuntos que tenham sentido para os demais componentes do compilador. Estes conjuntos so os tokens da linguagem e na realidadeso os identificadores e smbolos especiais de uma linguagem de computao. A seguir trataremos das expresses regulares e dosautmatos de estado finito, para depois estudarmos como os AEF's podem ser construdos automaticamente a partir de uma gramticaregular e como os analisadores lxicos podem ser representados atravs de um AEF.

    1. Expresses regularesExpresso regular uma forma compacta de denotar todos os possveis strings que compe uma determinada linguagem, usando paraisso a chamada notao estrela (*) de Kleene para representar a ocorrncia de zero ou mais instncias de um determinado smbolo ouconjunto de smbolos terminais.

    O que a notao * de Kleene faz apenas indicar que uma sequncia de um determinado caracter "c" expressa pelo smbolo "c*",representando uma sequncia de pelo menos zero ocorrncias do caracter "c". Assim, um nmero inteiro pode ser representado por"dd*", em que "d" representa um dos algarismos entre 0 e 9. Da mesma forma, um identificador em pascal ou modula-2 pode serrepresentado por "a(a|d)*", em que "a" representa uma letra entre a e z enquanto "d" um algarismo entre 0 e 9.

    Uma expresso regular pode ser expressa atravs de uma gramtica livre de contexto da seguinte forma:

    gramtica ER = ( {'|', '(', ')', '*', '+', '?', \sigma}, {ExpReg, Termo, Fator, Primario}, ExpReg, P ) Na qual P: 1. ExpReg -> ExpReg '|' Termo (alternao) 2. ExpReg -> Termo 3. Termo -> Termo Primario (concatenao) 4. Termo -> Primario 5. Primario -> Fator '*' (iterao) 6. Primario -> Fator 7. Fator -> '(' ExpReg ')' (agrupamento) 8. Fator -> \sigma

    Observaes: 1. '(', ')', '*', '|', '+' e '?' so chamados meta-smbolos. 2. O meta-smbolo '+' significa que o Fator associado a ele pode ser repetido uma ou mais vezes. Logo, "a+" = "aa*" 3. O meta-smbolo '?' significa que o Fator associado a ele pode ser repetido zero ou uma vez. Logo, "a?" = a |\lambda

    1.1 lgebra de expresses regulares

    Uma vez definida uma expresso regular, temos que saber como manipula-la de modo a torna-la o mais legvel possvel, isto , comouma expresso regular define todos os strings de uma linguagem, gostaramos de poder ler atravs dela quais so os strings admissveispara a dada linguagem sem muitos transtornos.

    Isto possvel atravs de manipulaes algbricas feitas a partir de propriedades do tipo associativa, comutativa, distributiva e deidentidade aplicadas s expresses regulares. Por exemplo, fica fcil de perceber que a propriedade comutativa pode ser aplicada sobreuma alternao pois r|s = s|r e no sobre uma concatenao pois rs != sr. A seguir temos uma lista das propriedades algbricas paraexpresses regulares.

    1. r|s = s|r (comutativa para alternao) 2. r|(s|t) = (r|s)|t (associativa para alternao) 3. r(st) = (rs)t (associativa para concatenao) 4. r|r = r (absoro para alternao) 5. r(s|t) = rs|rt (distributiva a esquerda) 6. (r|s)t = rt|st (distributiva a direita) 7. r \lambda = \lambda r = r (identidade para concatenao) 8. r*r* = r* (absoro de fechamento) 9. r* = \lambda | r | rr | ... (fechamento de Kleene) 10.(r*)* = r* 11.rr* = r*r = r+ 12.(r*|s*)* = (r*s*)* 13.(r*s*)* = (r|s)* 14.(rs)*r = r(sr)* 15.(r|s)* = (r*s)*r*

    1.2 Transformaes entre gramticas e expresses regulares

    Uma linguagem regular pode ser definida ou atravs de uma gramtica regular ou atravs de uma expresso regular. Ambas as formasso suficientes, isto , definindo-se uma delas a linguagem fica automaticamente definida tambm. As diferenas entre a gramtica e aexpresso que definem uma linguagem regular se devem ao formato em que definimos estas duas entidades.

    Enquanto uma gramtica usa o conjunto de produes para reescrever o smbolo inicial nos strings da linguagem, a expresso regularvai descrever os mesmos strings atravs de uma nica sentena na forma descrita em 2.1. Portanto a descrio de uma linguagematravs de uma expresso regular permite uma identificao mais clara dos strings que compem a dada linguagem, enquanto que agramtica mais til no momento de se formular as regras de formao da linguagem.

    Logo, interessante que tenhamos alguma estratgia para converter uma gramtica numa expresso regular e vice-versa, para quetenhamos como definir as regras e visualizar a linguagem nas formas adequadas para ambos os casos.

    A) Converso de expresso regular para gramtica: Dada a expresso regular \omega:

    1. Cria-se a "produo" S -> \omega 2. Aplica-se uma das regras a seguir at no existirem produes vazias nem meta-smbolos

    Regra Para as produes Criam-se as produes

    R1 A -> xy A -> xB e B -> y

    R2 A -> x*y A -> xB | y e B -> xB |y

    R3 A -> x | y A -> x e A -> y

    R4 A -> B e B -> x A -> x e B -> x

    R5 A -> \lambda e B -> xA B -> xA e B -> x

    R6 S -> \lambda (S o smboloinicial) G -> \lambdaG -> S

    Exemplo:

    a(a|d)* ==> S -> a(a|d)* (R1) S -> aA A -> (a|d)*

    A -> (a|d)* A -> (a|d)*\lambda

    (R2) A -> (a|d)B | \lambda B -> (a|d)B | \lambda

    (R3) A -> (a|d)B A -> \lambda A -> aB A -> dB

    (R3) B -> (a|d)B B -> \lambda B -> aB B -> dB

    Com isso temos: S -> aA A -> aB A -> dB A -> \lambdaB -> aB B -> dB B -> \lambdaEliminando-se as produes vazias e fazendo as simplificaes necessrias temos a gramtica final dada por: S -> aA S -> aA -> aA A -> dAA -> a A -> dB) Converso de gramtica para expresso regular: A converso neste sentido tambm simples, bastando fazer o procedimentoinverso ao anterior usando para tanto as regras dadas a seguir:

    R1 Produes da gramtica Expressoregular

    R1 A -> xB B -> y A -> xy

    R2 A -> xA | y A -> x*y

    R3 A -> x A -> y A -> x|y

    Exemplo: A partir da gramtica G abaixo teremos:

    S-> aA S -> a A -> aA A -> a ===> a(a|d)*(a|d)|a ===> a(a|d)* A -> dA A -> d

    2. Autmatos de estado finitoComo foi dito no captulo anterior, um autmato uma entidade capaz de reconhecer se uma string est ou no corretamente definidadentro de uma dada gramtica. Pela classificao de Chomsky vimos tambm que uma gramtica regular pode ser reconhecida peloque chamamos de autmato de estado finito (AEF), o qual descrito pelos cinco objetos discriminados a seguir: M = (\SIGMA, Q, \DELTA, q0, F) Em que

    \SIGMA o alfabeto compreendido pelo autmato, Q o conjunto de estados definidos para o autmato, \DELTA o seu conjunto de regras de transio, q0 o seu estado inicial e F o conjunto de estados finais para o autmato.

    Um autmato pode ter suas regras de transio representadas de forma grfica ou tabular. Na forma grfica temos tambm arepresentao visual dos estados do AEF, o que facilita o entendimento de como o autmato passa de um estado a outro. J a formatabular se presta bem ao armazenamento das transies num computador, o que vai ser muito interessante durante o projeto de umanalisador lxico. A figura a seguir ilustra a representao grfica de um AEF, enquanto que a tabela depois da figura representa astransies do mesmo autmato em sua forma tabular.

    Forma grfica para representao de um AEF.

    a b cA B B CB C B -C A - DD - - -

    Forma tabular para representao das transies num AEF.

    Um autmato reconhece ou aceita um string para uma dada linguagem se, ao final do string, parar num estado pertencente aoconjuntode estados finais F. Caso isso no ocorra diz-se que o autmato rejeita o string. Alm disso, diz-se que um autmato aceitauma linguagem se e somente se todos os strings definidos para aquela linguagem so aceitos pelo autmato, isto , para qualquer stringpertencente linguagem o autmato ir parar num de seus estados finais. Partindo da definio da aceitao de uma linguagempodemos comparar dois autmatos sobre suas condies de equivalncia, isomorfismo, etc. Assim, diz-se que dois autmatos soEQUIVALENTES quando eles aceitam a mesma linguagem. J quando, alm de aceitarem a mesma linguagem, eles tambm tiveremos mesmos estados, diz-se que eles so ISOMORFOS. Por outro lado, quando um autmato tem o menor nmero de estados entretodos os seus equivalentes dizemos que ele REDUZIDO.

    Um AEF ainda pode ser classificado segundo o tipo de regras de transio que o mesmo apresenta. Por este critrio ele pode serdeterminstico ou no-determinstico.

    Um AEF no-deterministico aquele em que pode ocorrer a transio vazia, que aquela em que o AEF pode passar de um estado aoutro sem que ocorra a entrada de um caracter do string. Alm disso, num AEF no-determinstico podem ocorrer indeterminaes naao do AEF, isto , determinados estados podem ter mais do que uma transio possvel para um dado caracter.

    O AEF determinstico aquele em que transies vazias no ocorrem e tambm em que no existam indeterminismos no momento detransitar de um estado a outro aps a leitura de um caracter, ou seja, todo aquele que no for no-determinstico.

    2.2.1 Transformao de uma gramtica regular num AEF

    Como um AEF um dispositivo capaz de reconhecer os strings de uma linguagem e uma gramtica um meio formal de definir umalinguagem, devemos ter mecanismos para a partir de uma gramtica especificar o AEF que reconhea tal linguagem. Isto feito deforma bastante simples, seguindo-se as regras a seguir:

    GRAMTICA AEF

    alfabeto \SIGMA alfabeto \SIGMA

    Para todo smbolo no-terminal emN cria-se um estado q pertencente a Q

    cria-se um estado final qf

    S q0

    Para toda produo A -> xB cria-se uma transio \delta(A,x) = B

    Para toda produo A -> x cria-se uma transio \delta(A,x) = qf

    3 AEF's e expresses regularesComo j vimos, gramticas e expresses regulares so apenas duas formas distintas de representar uma linguagem. Logo, tambmpodemos construir um AEF partindo-se de uma expresso regular. Uma forma bastante simples de se fazer isto atravs darepresentao grfica de um AEF, em que uma expresso regular ER seria colocada dentro de uma caixa-preta com um estado deentrada A e outro de sada B, como mostrado a seguir:

    A seguir acrescentaria-se um estado inicial S e outro final F, quando teramos as transies \delta(S,\lambda) = A e \delta(B,\lambda) =F. A partir da seguiramos com a transformao usando as cinco regras a seguir, at que no existam mais caixas-pretas.

    REGRAS:

    Exerccio:

    Encontre o AEF que reconhea a expresso \omega = a(a|d)*

    Como se pode observar, o nmero de transies vazias no AEF encontrado bastante elevado, o que nos faz pensar em reduzir onmero destas ocorrncias. Entretanto, bastante perigoso fazer isso sem um critrio muito bem definido, pois podemos acabaralterando a linguagem reconhecida por um AEF se retirarmos expresses vazias que fossem realmente necessrias. O exemplo a seguirilustra bem este problema.

    Exemplo (exerccio):

    1. Construa o AEF para a expresso \omega = (a*b)* usando as regras dadas anteriormente. 2. Aps isso repita a construo do AEF, porm trocando a regra R3 pela regra F3 dada a seguir. Verifique que neste segundo

    caso possvel a aceitao do string "a", que no aceita por \omega.

    3.1 - Obteno de um AEF determinstico a partir de um no-determinstico

    A reduo do nmero de transies vazias num AEF, bem como a eliminao de transies ambguas, pode ser feita de forma seguraquando se faz a reduo de um AEF no-determinstico para um determinstico. Este processo realizado em quatro etapas, "remoode ciclos vazios", "eliminao de transies vazias", "remoo de no-determinismos" e "reduo do autmato", que esto descritas aseguir.

    1. Remoo de ciclos vazios: O primeiro passo na obteno do AEF determinstico identificar ciclos nos quais, partindo-se de um dado estado pode-sechegar ao mesmo passando apenas por transies vazias. Como se percebe, tais ciclos implicam em que os estadosintermedirios no necessariamente precisam ser percorridos, desde que se garanta a manuteno das transies no-vaziasligadas aos estados do ciclo.

    Para eliminarmos estes ciclos sem que haja prejuzo de consistncia ao AEF basta que se crie um novo estado que ir assumir olugar de todos os estados que fazem parte do ciclo. As transies de entrada do novo estado so as transies de entrada de cadaum dos estados do ciclo, enquanto que as transies de sada so todas as transies de sada dos estados em substituio. Nesseprocesso, caso um dos estados do ciclo for final, ento o novo estado tambm ser final.

    Efetuar isto de forma grfica possvel, bastando tomar cuidado para, a cada passo, no deixar de lado nenhuma transio dosestados que compe o ciclo. Entretanto, quando estamos fazendo isso de forma automatizada fica difcil conseguir umalgoritmo que trabalhe de forma visual eficientemente. O que se faz usar a forma tabular de representao das transies doAEF, passando ento a ser necessrio um algoritmo de deteo de ciclos vazios na tabela em questo.

    Fica como exerccio a especificao dos algoritmos para a eliminao dos ciclos vazios no AEF no-determinstico, o quesignifica um algoritmo para a deteo do ciclo e outro para a unio dos estados pertencentes ao ciclo.

    2. Eliminao de transies vazias: Aps a eliminao dos ciclos vazios ainda teremos transies vazias que no pertenciam a nenhum ciclo. A eliminao de taistransies pode ser feita de forma semelhante eliminao dos ciclos vazios, isto , atravs da unio dos estados envolvidosnuma transio vazia, tanto de forma grfica quanto de forma algoritmica atravs da tabela de transies.

    No caso da eliminao de transies vazias, o que se faz copiar o estado destino da transio vazia sobre o estado origem damesma, sem remover o estado destino entretanto. No processo o que se faz copiar todas as transies que partem do estadodestino para o estado origem, pois so estas as transies que passam a ser possveis quando partindo do estado origem com atransio vazia para o estado destino, no qual teramos as novas transies de partida possveis. Aqui tambm, o novo estado(aquele do qual partia a transio vazia) passar a ser final caso o estado destino seja final.

    Na forma tabular, teramos algo como nas tabelas seguintes, nas quais estamos eliminando a transio vazia \delta(A, \lambda)= B.

    a b \lambda a b \lambdaS B A S B A A B A A,B F GB A,B F G B A,B F GF ===> F G F H,J G F H,JH F H FJ A J A Observem que o algoritmo pode ser otimizado se forarmos com que o processo se inicie a partir de um estado destino que notenha transies vazias entre as suas transies de partida, pois assim eliminamos a possibilidade de ter que eliminar transiesrecursivamente.

    3. Remoo de no-determinismos: Como se pode ver das tabelas apresentadas no passo 2 ainda teremos indeterminismos em algumas transies, como porexemplo \delta(A, a) = A ou \delta(A, a) = B. O ltimo passo para a obteno de um AEF determinstico a eliminao de taistransies, o que pode ser feito atravs da alterao dos estados do autmato. Muito embora isso tambm possa ser feito deforma grfica, apenas realizamos este passo pela forma tabular, uma vez que a complexidade da alterao dos estados tal queseria muito fcil cometer pequenos enganos no processo, o que levaria a uma linguagem diferente da original.

    O processo pela forma tabular o seguinte: 1. partindo-se do estado inicial, para cada transio com mltiplas opes cria-se um novo estado, cujo nome a unio dos

    nomes dos estados destinos da transio. 2. Cria-se uma nova linha na tabela, com o novo estado, em que as transies so dadas pela unio entre as transies de

    cada um dos estados agora aglutinados. 3. Repete-se o processo at que no existam mais estados a serem aglutinados.

    4. Reduo do autmato:

    Muito embora o autmato obtido no passo 3 j seja determinstico, o mesmo contm muitos estados que poderiam sereliminados por um processo de reduo no tamanho do autmato. Esta reduo se d pela identificao dos estadosequivalentes em classe, que so os estados para os quais se aceitariam as mesmas strings caso eles fossem os estados iniciaispara as strings.

    Uma vez identificados os estados de uma classe de equivalncia, os mesmos so substituidos por apenas uma instncia,alterando-se o seu nome e atualizando a tabela de transies para conter este novo nome. O processo se repete at que no sejamais possvel identificar novas classes de equivalncia, o que significa que o autmato dado pela tabela atual o autmatoreduzido para a linguagem em questo.

    O algoritmo a seguir deixa explcito o processo de minimizao dos estados de um autmato determinstico: 1. Dividir os estados em duas classes, uma contendo todos os estados que sejam finais e outra contendo os no-finais. 2. Em qualquer das classes, separar tambm os estados que bloqueiam num determinado caracter do alfabeto numa nova

    classe. 3. Estados dentro de uma mesma classe que levem at estados em diferentes classes para um mesmo caracter, tambm

    podem ser divididos em duas classes. 4. O processo continua at que mais nenhuma nova classe possa ser criada. Nesse momento, cada uma das classes pode

    ser considerada como sendo um estado nico.

    A aplicao desse processo no autmato a seguir mostra bem como isso pode ser feito:

    Ou seja, de incio separamos os estados finais dos no-finais. Depois, vemos que os estados B e BE bloqueiam para o caracter"a" e devem, portanto, serem separados do estado A. A seguir, vemos que o estado CF leva ao estado A, numa classe diferenteda classe a que pertence o estado CF, enquanto que os demais estados levam ao estado BE, que est numa classe diferente de A.Assim, podemos separar o estado CF numa classe diferente da que pertencem os outros estados finais. A seguir, no teramosmais classes para separar, quando ento poderamos juntar todos os estados de uma dada classe num estado nico, resultandono autmato indicado na ltima tabela da sequncia.

    3.2- Transformao de AEF's em gramticas regulares

    O processo aqui bastante simples, bastando fazer a aplicao das regras de transformao de forma reversa, isto , para toda transio

    \delta(A,x) = B acrescenta-se a produo A -> xB

    e para todo estado final "F" acrescenta-se a produo F -> \lambda

    Aps a criao de todas as produes deve-se fazer a eliminao das produes vazias atravs dos mecanismos apresentadosanteriormente. Portanto percebe-se que a transformao trivial, levando-nos a conseguir mais uma passagem entre as vrias formasde se representar a gramtica para um analisador lxico.

    3.3- Gramtica linear a esquerda

    Quando examinamos o processo de transformao de uma gramtica num AEF construmos todas as regras baseando-nos numagramtica linear a direita, isto , com produes do tipo A -> xB e A -> x. Entretanto, nem sempre temos uma gramtica deste tipo emmos. Uma forma de se obter tal gramtica usar expresses regulares como uma forma intermediria no processo de transformaode uma gramtica linear a esquerda em outra a direita. Como j temos as regras de transformao entre ER's e gramticas lineares adireita, resta-nos apenas determinar as regras de transformao entre gramtica linear a esquerda e expresses regulares.

    As regras de produo so as seguintes:

    Produes: Expressoregular:

    A -> Bx e B -> y A -> yx

    A -> Ax e A -> y A -> yx*

    A -> x e A -> y A -> x | y

    4. Implementao do analisador lxicoUm analisador lxico pode ser implementado ou atravs do AEF que o representa ou atravs de sua gramtica regular. Embora oresultado de ambas as tcnicas deva ser o mesmo, estas formas tem diferenas fundamentais quanto implementao. Se partirmos doAEF para a implementao do scanner, o trabalho de manipulao maior do que se partirmos de sua gramtica regular, que umprocesso que pode ser feito de forma automtica.

    A seguir descrevemos estas duas abordagens, apresentando tambm os problemas envolvidos na especificao do analisador lxico,tais como a implementao da tabela de smbolos, tamanho do alfabeto de entrada e tratamento da passagem de valores (tokens) aoanalisador sinttico, entre outros.

    4.1 Implementao via AEF

    A implementao do scanner atravs de um AEF bastante simples. Basicamente o que feito usar um par de comandos do tipoCASE (switch em C) para representar os estados e os caracteres sendo lidos pelo autmato.

    Assim, por exemplo, um primeiro CASE faz sua deciso a partir do estado atual do autmato (que est guardado numa varivelatualizada a cada transio), enquanto que o segundo CASE tomar a sua deciso a partir do caracter que acaba de ser lido. A ordemem que estes dois cases so realizados pode ser alterada segundo a convenincia do processo de busca, isto , caso seja maisconveniente primeiro selecionar pelo caracter de entrada e depois pelo estado, podemos faz-lo assim sem maiores complicaes. Adeciso sobre qual ordem a ser adotada deixada ento a cargo do implementador.

    Como pode ser visto, uma vez definido o AEF temos que a sua implementao trivial se o mesmo puder ser expresso por umconjunto reduzido de estados e de caracteres de entrada. Entretanto isso no o que ocorre num compilador, fazendo com que aimplementao do AEF se torne trabalhosa devido ao grande nmero de estados e do tamanho do alfabeto existentes numa gramticaregular real. A soluo para este problema o uso de geradores automticos de scanners, tais como o lex ou o flex presentes noambiente UNIX.

    4.2 Implementao via gramtica

    O scanner pode ser implementado usando-se um gerador automtico, tal como o lex. Para tanto, usamos gramticas reescritas na formade expresses regulares, que devidamente arranjadas segundo a sintaxe do lex podem gerar de forma automtica o cdigo do scanner.

    Esta abordagem tem enormes vantagens com relao implementao direta a partir do autmato pois, como a gramtica (e asexpresses regulares que a representam) tem que ser definida de qualquer maneira, uma vez que a partir dela que sabemos quais soos strings permitidos para a dada linguagem, torna-se desinteressante tranformarmos a gramtica num autmato que teria que serimplementado manualmente, se sabemos que existem geradores automticos de scanners a partir das produes da prpria gramtica.Entretanto, em ambos casos existem problemas que precisam ser resolvidos para que a implementao seja funcional, tanto quanto sua correo como quanto sua eficincia. A seo seguinte faz um tratamento destes problemas.

    4.3 Problemas de implementao

    1. Tamanho do alfabeto de entrada: Como o autmato usa dois cases aninhados, em que um deles decidido pelos diferentescaracteres do alfabeto de entrada, torna-se necessrio que o alfabeto no seja muito extenso, uma vez que em geral temos cerca de 50estados diferentes na gramtica de um compilador normal.

    O alfabeto ASCII tem 128 caracteres (muitos no imprimveis), logo se o estamos usando, precisamos de algo para reduzir o seutamanho. Uma ttica usar subconjuntos que tenham uma caracterstica em comum para que possam ser representados por apenas umnico smbolo, tais como todas as letras (maisculas e minsculas) serem representadas pelo conjunto [A-Za-z].

    2. Critrios de parada: Um outro problema a determinao de quando uma certa sequncia de entrada representa um token vlidoou no. Por exemplo, para expresso regular d*d* fica impossvel determinar se a sequncia de entrada 12345 representa os strings "1"e "2345" ou "123" e "45".

    Para este problema temos duas solues. Na primeira a estratgia antecipar sempre a leitura do prximo caracter quando estivermostrabalhando com um dado caracter. Assim, se estivermos num estado final que tenha transies de sada, usamos o prximo caracterpara decidir se ele permite uma transio ou no.

    A outra soluo simplesmente ignora os estados finais at que o autmato bloqueie. Neste caso ele verifica se o bloqueio ocorreu numestado final. Caso isso seja verdade ele aceita o token, caso contrrio o token rejeitado. Nos dois casos o scanner reinicia seufuncionamento a partir do caracter que causou o seu bloqueio.

    3. Eliminao de espaos e comentrios: Outro aspecto a ser cuidado a eliminao de espaos em branco e de comentrios dasequncia de entrada. A finalidade de sua existncia dar mais clareza ao texto fonte mas, durante a compilao, no existe maisnenhuma razo para que os mesmos sejam mantidos, uma vez que o scanner j separa todos os tokens a serem trabalhados peloanalisador sinttico.

    Alis, se os espaos e comentrios fossem mantidos aps a passagem pelo scanner, teramos que aumentar a quantidade de tokensaceitveis pela linguagem do parser, o que o tornaria muito mais complexo. Assim, temos que fazer com que o scanner reconheaespaos e comentrios e os descarte aps detectar algo diferente de espao ou comentrio, o que obtido modificando a sua gramticade forma que suas expresses regulares incluam agora espaos e comentrios.

    4. Passagem de valores: Como o scanner existe apenas para fazer a separao dos tokens de entrada do parser (que quem ativa oscanner), temos que encontrar uma forma de faz-lo passar valores para o parser.

    Uma forma elegante de fazer isso atravs da adio de aes semnticas s produes da gramtica regular. Uma ao semntica simplesmente uma atribuio de valor de retrno que o scanner faria no instante em que chegasse em um bloqueio num estado final.

    Isto pode ser implementado de vrias formas, mas a mais simples atravs de atribuies diretas dentro dos comandos case criados(tanto manualmente como de forma automtica) para fazer a anlise lxica. No caso do uso do lex isto feito diretamente em cadaexpresso regular.

    5. Tabela de smbolos: Dentro do processo de identificao de tokens da gramtica surge o problema de como identificarindividualmente cada varivel ou constante definida no programa. Essa tarefa resolvida pelo uso de uma tabela de smbolos, em queso armazenadas todas as informaes sobre cada varivel (tratada aqui como um smbolo), tais como seu nome, seu escopo, endereolgico, tipo, etc.

    Um grande problema envolvido na implementao do scanner a forma em que a tabela de smbolos criada e manipulada. Isto sedeve ao fato de que a tabela de smbolos tem que ser consultada, e atualizada, cada vez que um token identificado. Logo, temos queter mecanismos que faam isso de forma bastante eficiente.

    Dentre as possveis estratgias temos a implementao da tabela como sendo uma tabela hash, em que atravs de uma funo hashpudessemos encontrar smbolos dentro da tabela de forma bastante rpida. Esta forma ao mesmo tempo eficiente e econmica emtermos de memria, desde que dentro de cada posio da tabela no tenhamos que percorrer listas extensas para identificar um token deforma nica.

    Uma possvel melhoria obtida ao custo de um aumento no espao ocupado na memria, fazendo-se com que cada caracter de cadatoken ocupe um n de uma rvore de busca. Tal rvore chamada "trie" (de re"trie"val) e consiste basicamente em fazer com que cadan seja um vetor que aponte para n possveis caracteres que seguiriam ao n em questo.

    Para efeito de comparao temos a seguir uma tabela apresentando o espao ocupado e tempo de busca para tabelas de smbolosimplementadas atravs de busca linear, tabela hash e rvore trie:

    Algoritmo

    Tamanho da tabela(bytes) Tempo de scan

    50 ident. 500 ident. 50ident. 500ident.

    Buscalinear 600 6000 2960 29600

    TabelaHash 1400 10400 250 540

    rvore trie 5720 36000 250 250