Добро пожаловать в Scribd!
Академический Документы
Профессиональный Документы
Культура Документы
Хобби и ремесла Документы
Личностный рост Документы
{ expe? (ag! Exprd {ago} ) ‘A primeira linha declara duas (inclusive) afirma lexical a ¢ s , a segunda linha um estado exclusivo lexic padrio (inclusive) Estado vvTr +TAX, & sempre implicitamente lé ndio precisa ser declarado, A regra com expr1 nio tem estados lstados, e &, portanto, corresponde em todos os estados, mas os exchisivos, ou seja 8, € Y¥INITIAL . Na sua acgdo, o scanner é ligado ao estado 1. A segunda regra exp? s6 pode corresponder quando o scanner esté em estado de vvrnr7 ran ow a . Aregra expr3 86 pode ser acompanhado no estado A ¢ expr4 nos estados a, & «Estados lexicais sto declarados ¢ usados como Java int constantes na classe gerada sob o mesmo nome que eles so usados na especitficagio. Nao hi garantia de que os valores destas constantes inteiras so distintos. Ekes so ponteiros para a tabela DFA gerados, e se reconhece JFlex dois estados como lexicalmente equivalente (se eles so usados com exatamente o mesmo conjunto de expresses regulares), entio as duas constantes terd 0 mesmo valor. Aclasse gerada JFlex gera exatamente um arquivo contendo uma classe a partir da especificagdo (a menos que vocé tenha dcclarado uma outra classe na segdo primeira especificagio), A classe gerada contém (entre outras coisas) as tabelas DFA, um buffer de entrada, os estados lexical da especificagdo, um construtor, eo método de varredura com as ages do usuario fornecido. © nome da classe é, por padriio yyiex , é personalizivel coma ciasse% directiva (ver também secgdo 4.2.1 ). buffér de entrada do lexer esta conectado com um fuxo de entrada sobre 0 java. io.Reader objeto que & passado para o lexer no construtor gerado, Se vocé quiser fornecer seu proprio construtor para o lexer, voce deve sempre chamar o gerado nela para inicialzar 0 bufler de entrada, O buller de entrada ndo devem ser acessados diretamente, mas apenas sobre a API anunciados (ver também secgo 4.3.5 ), Sua implementago intema pode mudar entre as versdes ou arquivos esqueleto sem aviso prévio, A interface principal para o mundo exterior é 0 método de varredura gerado (default nome yyiex , padrao tipo: de retomo vycoken ). A maioria de seus aspectos podem ser personalizados (nome, tipo de retomo, declarou excegdes, ete, ver tambéma secgio 4.2.2 ). Se for chamado, ele vai consumir de entrada até que uma dasexpresses na especifcagdo & comespondido ou ocorre um erro, Se uma expresso for correspondido, a ago correspondente é executada. Ele pode retornar um valor do tipo de retomno especificado (neste caso 0 retomo do método de varredura com este valor), ou se ee ndo retorna um valor, o scanner de entrada retoma consumir até a proxima expressdo & correspondido, Se o fim do arquivo for atingido, o scanner executa a agdio EOF, (também a cada novo convite para o método de varredura) retorna 0 valor EOF especiticado (ver também secgio 4.2.3 ), Scanner métodos e campos acessiveis em agées (API) Métodos gerados ¢ campos de membro em scanners JFlex sto prefixados com aa para indicar que gerados ¢ para evitar confitos de nome com o eédigo do usurio copiado para a classe. Ume vez que 0 eédigo do usuirio & parte da mesma classe, JFlex nfo tem lingua significa como a privada modificador para indicar que os membros e métodos sdo intermos e quais pertencem a API. Emvvez disso, JFlex obedece a uma convengdo de nomenclatura: tudo comegando com um 22 prefixo como z»5tartead deve ser considerada interna ¢ sujeito a ateragdo sem aviso prévio entre os langamentos JFlex. Métodos e membros da classe gerada, que ndo tém um 22 prefixo como yycharat pertencem 4 API que a classe scanner fornece aos usustios em cédigo de ago da especificagdo. Elks sero permanecem estaveis ¢ suportados entre releases JFlex o maior tempo possivel, Atualmente, a API é composta dos seguintes métodos campos membro: * cadeia yytext () retoma o texto correspondente regio de entrada © yylength int 0 retoma o comprimento da regio correspond a entrada de texto (no requer uma corda objeto a ser eriado) © cazactere yycharat (1 retoma 0 caractere na posizdo pos do texto comespondente. E equivalente a yytext (). chacat (pos) , mas mais ripido, pos deve serum valor de 0 a yy! pos) ngth () -1 © yyclose vazio 0) fecha o fluxo de entrada. Todas as chamadas subseqiientes para o método de digitalizagao ira retomar o valor final do arquivo # vazio yyresct (java.to.Reader 1 fecha o fluxo de entrada de corrente, e redefine o scanner para ler a partir de um fluxo de entrada nova. ‘Todas as varidveis intemas sdo repostas, o fhixo de entrada de idade ndo podem ser reutiizados (contetido do buffer interno & descartado e perdeu). O estado lexical esta definido para yy_tN=7TTar, © vazio yypushStream (java.io.Reader leitoz) Armazena o fhixo de entrada atual em uma piha, ¢ Ié a partir de um novo fluxo. Estado lexical, linha, char, € contando colina permanecem intocados. O fluxo de entrada de corrente pode ser restaurada com vypopat ream (geraknente em um «E08» aco).Um exempl tipico para isso sto inchir arquivos no estilo do C pré-processador. A especificacio correspondente JFlex poderia olhar mais ou menos assiny 4 Include" (FILE) [yypushStream (new FileReader (getFile (yytext ())})s) > (TE tyme: Leeams ()) yypopStream (); else return Este método s6 esté disponivel no arquivo esqueeto skeleton. nested . Voeé pode encontré-la no ze da distribuisdio do JFlex. yypopstream vazio () Fecha o fluxo de entrada atual e continua a ler o de cima da pilha de fluxo, Este método s6 esté disponivel no arquivo esqueeto skeieton.nesved . Voeé pode encontréela no sxe da distrbuigio do JFlex. yynoreStreams boolean ( reloma verdadeiro sse ainda existem fuxos para yypopst rean esquerda para ler na pilha de xo, Este método s6 esté disponivel no arquivo esqueketo skeleton nested . Vocé pode encontré-la no da distribuigdo do JFlex int yystate Q) retorna o estado atual lexical do scanner. vazio yb entra no Wxico estado Lexicalstate gin (int lexicalstate) yypushback v at) empura ninero de caracteres do texto correspondente de volta para o fluxo de entrada. Eles serio lidos novamente na préxima chamada do método de varredura. O nimero de caracteres a ser ido novamente, no deve ser maior que o comprimento do texto correspondente. Os caracteres empurrado para tris apds a chamada vai de yypushback nfo ser incluido no yyiengeh € yytext 1) . Por favor, note que em strings Java sto imutaveis, ou seja, um eédigo de ago como String combinada ~ yytext (J; yypusnback (1); retorno alinhados: retomaré todo o texto correspondente, enquanto yypushback (1); retorno yytext (7 ind retomar o texto correspondente menos o titimo caractere. int yyline contém a atual linha de entrada (comegando com 0, apenas ativos com a Linhas directiva)contémo mimero de caracteres atual na entrada (comegando com 0, apenas ativa como chars directiva) © int yycotunn contéma coluna atual da linha atual (comecando com 0, apenas ativos com a co“ una’ directiva) Codifica¢ées, plataformas e Unicode Esta segdo tenta langar alguma luz sobre as questdes de Unicode e codificagdes, a digitalizagio multi plataforma, e como lidar com dados bindrios. Meus agradecimentos vio para Stephen Ostermller por sua contribuigdo sobre este tema, O Problema Antes de mergulhar de cabega em detalhes, vamos dar uma olhada no que esté 0 problema. O problema é a independéncia da plataforma Fava quando vocé quiser usi-to, Para scanners a parte interessante sobre a independéncia de plataforma € codificagao de caracteres e como eles so manipulados, Se um programa Ié um arquivo do disco, ele recebe um fhuso de bytes. Nos tempos antigos, quando a gram era verde, eo mundo era nmito mais simples, todo mundo sabia que o valor de byte 65 &, naturalmente, um A. Nao {foi problema para ver 0 que significava que personagens bytes (na verdade minca existiu nestes tempos, mas de qualquer maneira), © alfabeto latino normais s6 tem 26 caracteres, para 7 bits ou 128 valores distintos deve certamente ser 0 suficente para mapeé-los, mesmo se vocé se permitir o xo de maiisculas € minisculas. Hoje em dia, as coisas so diferentes. O mundo de repente ficou muito maior, ¢ todos os tipos de pessoas queria todos os tipos de caracteres especiais, apenas porque usé-los em sua linguagem ¢ da eserita, Esta é a bagunga foram comega. Desde os 128 valores distintos jd estavam cheios de outras coisas, as pessoas comegaram a usar todos os & bits do byte, e estendeu os mapeamentos byte / caractere para atender sua necessidade, e, claro, todo mundo fez isso de forma diferente, Algumas pessoas, por exemplo, pode ter dito ™ vamos usar o valor 213 para o personagem akemio a". Outros podem ter descobriu que 213 deve significar muito mais e, porque nao precisa alemio ¢ fianeés, em vez escreveu. Contanto que vocé use 0 seu programa ¢ os arquivos de dados apenas em uma plataforma, isso nio & problema, como todos sabem o que isso significa 0 qué, ¢ tudo fica utiizado de forma consistent. Agora Java entra em jogo, ¢ quer correr por toda parte (uma vez por escrito, que &) ¢ agora de repente & um problema: como fago para obter o mesmo programa para dizer que um byte para um certo quando cexecutado na Alemanha e, talvez, e quando é executado em Franga? E também o contrério: quando eu quero dizer e na tela, cujo valor byte devo enviar para o sistema operacional? Java para isso ¢ usar Unicode intemamente, Unicode pretende ser um superconjunto de todos os conjuntos de caracteres conhecidos e, portanto, uma base perfeita para a codificagdo de coisas que poderiamter usado em todo o mundo, Para fazer as coisas fimcionarem corretamente, vocé ainda tem que saber onde voc’ esti e como mapear valores de bytes para caractetes Unicode e vice-versa, mas 0 importante é que esse mapeamento é pelo menos possivel (vocé pode mapear caracteres Kanji para Unicode, mas vocé niio pode maped-los para ASCII ou ISO-Latin-1). Digitalizagao de arquivos de texto Digitalizagao de arquivos de texto é a aplicagao padrio para scanners como JFIex. Por isso, também deve ser 0 mais conveniente. Na maioria das vezes & seguinte cenério fimciona como uma brisa: Vocé trabalha em uma plataforma X, escreva sua especificagao lexer ld, pode utilizar qualquer caractere Unicode na obscura-lo como quiser, e compilar o programa, Seus usuditios fimcionar em qualquer plataforma Y (possivelmente, mas no necessariamente algo diferente de X), escrevem seus arquivos de entrada em Y ¢ executar o seu programa em Y. Sem problemas. Java faz isso da seguinte forma: Se vocé quiser ler alguma coisa em Java que é suposto conter texto, vocé usa um FileReader ou algum rnp: an juntamente com um IaputStreanReader . os bytes brutos, © raps converte os bytes em caracteres Unicode com o da plataforma codilficagdo padrdo, Se um arquivo de texto & produzido na mesma plataforma, a codificacdo padrio da plataforma deve fizer o mapeamento corretamente. Desde JFlex também usa Unicode intemamente e ketores, esse mecanismo também funciona para as especificagdes de scanner, Se vocé escreve um A no seu editor de texto eo editor usa a codificagaio da plataforma (digamos a ¢ 65), em seguida, Java traduz para a Unicode Iogica a intermamente, Se um usudrio escreve uma sobre uma plataforma completamente diferente (digamos a é de 237 hd), entdo Java também traduz para a Unicode légica tm internamente. A varredura é realizada depois que a tradugdo ¢ ambos coincidem, putStreans retornar amReads Note-se que por causa deste mapeamento de bytes de caracteres, vocé deve sempre usar 0 unie interruptor em vocé especificagdo lexer se vocé quiser verificar os arquivos de texto. 8iies pode ndo ser suficiente, mesmo se vocé sabe que a sua phitaforma usa apenas um byte por personagem. A codificagao Cp1252 usado em muitas miquinas do Windows, por exemplo, sabe 256 caracteres, mas o personagem ‘com Cp1252 cddigo \. x92 temo valor Unicode \ 2019 , que é maior do que 255 e que faria o seu scanner langar ds=xception se for encontrado, um Arrayrndexoutote: Assim, para 0 caso de costume, voe€ no precisa fazer nada, mas usar 0 unicode’ interruptor ma sua especificago lexer, AS coisas podem quebrar quando vocé produz um arquivo de texto em X plataforma e consumi-l em uma plataforma diferente Y. Digamos que vocé tem um arquivo escrito em um PC com Windows usando a codificagdo Cp1252. Entio vocé mover este arquivo para um PC Linux com encoding ISO 859-1 € lb vo deseja executar 0 seu scanner nele, Java agora acha que 0 arquivo esti codificado em ISO 8859-1 (codificagto padrao da plataforma), enquanto que ele realmente é codificado em Cp1252. Para a maioria dos personagens Cp1252 e ISO 8859-1 so os mesmos, mas para os valores de byte \ x80 para x9 \ discordam: ISO 8859- 1 6 indefinido I. Vocé pode cortigir o problema, dizendo expliitamente que Java codificagdo a utilizar. Aoconstruir 0 Epa anaeadex , voce pode dar a codificago como argumento. A linha anReader (input, "Cp1252' ird fazer 0 truque. E claro que a codificagdo a ser usado também pode vir a partir dos dados em si: por exemplo, quando voce escanear uma pagina HTML, ele pode ter embutido informagdes sobre a sua codificagdo de caracteres nos cabegalhos, Mais informagses sobre codificagdes, quais sao suportadas, como sio chamados, e como configuré-los podem ser encontradas na documentagao do Java oficial no capitulo sobre a intemnacionalizagao. © link a .1/ leva a uma versio online deste para o JDK da Sun Digitalizagao binarios Digitalizagdo bindrios & tanto mais ficil e mais dificil do que a varredura de arquivos de texto. E mais ficil porque ‘voc’ quet os bytes brutos € ndo o seu sentido, isto é, vocé niio quer que quakquer tradugdo, E mais dif porque nio ¢ tio fil de obter nenhuma tradugdo" quando vocé usa leitores Java problema (para bindrios) ¢ que scanners JFlex so projetados para trabalhar no texto. Portanto, a interface & OSeitor de classe (ndo hi um construtor para Znpurst ream casos, mas é sé lé por conveniéncia e envolve para obter caracteres, ndo bytes). Voed ainda pode obter um scanner binirios quando vocé escreve o seu préprio costume Inputs=reankeader classe que faz explicitamente nenhuma tradugdo, mas apenas c6pias valores byte para cédigos de caracteres em seu higar. Parece mito facil, e realmente niio é grande coisa, mas hé algumas armadibhas pouco no caminho. Na especificagao do scanner voc? 86 pode inserir cédigos de caréter positivo (para bytes que é \ x00 para x=F \ ). Java byte tipo, por outro lado é um inteiro assinado bit 8 (-128 a 127), entdo vocé tem de converté-los corretamente em seu costume 2eitor . Akim disso, vocé deve tomar cuidado quando voc voc’ usar texto Ki dentro, ele ¢ interpretado por uma codificago em primeiro gar, e0 que vo como resultado pode depender de qual plataforma vocé executar JFlex quando vocé gerar o scanner (& isso que vocé quer para o texto, mas para os bindrios que fica no caminho). Se vocé nao tiver certeza, ou se a plataforma de desenvolvimento pode mudar, é provavelmente melhor usar escapes cédigo de caracteres em todos os lugares, pois eles no mudam o seu significado. um cnputstreamReader em tome del Para ihistrar estes pontos, 0 exemplo emexenplos / indie contém um scanner binario muito pequeno que tenta detectar se um arquivo é um Java classe de arquivos. Para esse eftito, olha se o arquivo comega como inlmeto migico \ xCAFEBAS! Algumas palavras sobre o desempenhoEsta sego apresenta alguns resultados empiticos sobre a velocidade da JFlex scanners gerada em comparagio com aqueles gerados por JLex, compara um scanner JFlex com um manuscrito um, ¢ apresenta algumas divas sobre como fazer sua especificagdo produzir um ripido scanner. Comparagao de JLex e JFlex ‘Scanners gerado pelo JLex ferramenta so bastante répido. No entanto, foi possivel methorar ainda mais 0 desempenho de scanners gerados usando JFlex. A tabela a seguir mostra os resultados que foram produzidos pela especificagdo scanner de uma linguagem de programagao pequeno brinquedo (o exemplo no site da JLex).. scanner foi gerada usando JLex 1.2.6 e 1.3.5 JFlex versio com os trés diferentes métodos JFlex geragio de cédigo. Em seguida, ele foi executado em um sistema W98 com o JDK da Sun 1.3 com entradas diferentes de amostra de que a linguagem de programagdo de brinquedo, Todas as execugdes de teste foram feitos nas ‘mesmas condigdes em uma miquina de outra forma ociosa, Os valores apresentados na tabela indicam o tempo da primeira chamada para o método de digitalizago de devolver o valor EOF eo speedup em porcentagem, Os testes foram executados tanto no misto (HotSpot) JVM 0 modo puro interpretado, O modo misto JVM traz.um fator de 10 a methoria do desempenho, a diferenga entre JLex e JFlex s6 diminui um pouco. [J s8|_ TLex|| = speedup| speedup [ ][ 496] otspot [325 ms 261 ms| 24.5% 24.5% [ ][187|[ hotspot [127 ms 98 ms| 29.6% 32.3% [ [93 hotspot [66 ms 50ms\| 32.0% 375% [ || 496|[intepr. [4009 ms [3025 ms] 32.5% 241% [| 187|[ inter. [1641 ms 1155 ms|_ 42.1% 33,0% [| 93] iterpr. [817 ms S73ms | 42,6% 33.3% Desde o tempo de varredura do analisador Iéxico examinados na tabela acima inchii ages lexical que mitas vezes precisa criarinsténcias de objetos novos, outra tabela mostra o tempo de execugdo para a mesma especificagdo com ages vazio lexical para comparat os mecanismos de varredura puro. speedup speedup 45,7%| 138ms| 47,8%| 140 ms||45,7% | | xe[ sv TLex speedup [ [496 hotspot [204 ms [ || 187|[ hotspot [83 ms || 93] howspot | 41 ing 50,9%| 52ms| 59,6%| — 52ms| —59,6% 46,4%| 26ms| 57,7%| 26 ms|| 57.7%Lit n n n I! n 1 n [| 496 || interpr. 2983 ms. 2036 ms 46,5% | 2230 ms 33,8% | 2232 ms 33,6% [][187|[itorpr. [1260 ms 793 ms| 58.9% 865m] 45,7% | 867 ms| —_45,3% [JL 93 imerpr. [628 ms 395ms| 59,0%|| 432ms| 454% | 432 ms) 454% ‘Tempo de execusdo de instrugdes tinico depende da plataforma ¢ da implementag3o da Méquina Virtual Java 0 programa ¢ executado. Portanto, as tabelas acima nio pode ser usado como uma referencia ao qual o método de gerago de cédigo de JFlex é 0 direito de escolher em geral, A tabela a seguir foi produzido pela mesma especificago lexical ea mesma entrada em um sistema Linx usando também da Sun IDK 1.3. Comagies: [J se|_ 2m Wex[ see=pce:]] speedup] =|) speedup | r" Custa miiiplas comparagdes adicionais por jogo. Em alguns casos um look-ahead extras personagem & necessério (quando o iiltimo caractere lido & \ r 0 scanner tem que ler um caractere a frente para verificar se o proximo é umn \ ou no). Jogo come texto tanto quanto possivel, em uma regra, ‘Uma regra é combinada na repetigdo intema do scanner. Depois de cada ago alguma sobrecarga para a‘cimgay Uo estguO MILLI GO SeAIMIEL © HECESNALN. ‘Note-se que escrever regras mais em uma especificagdo no fiz o scanner gerado mais lento (exceto quando vooé tem que mudar para outro método de geragdo de eédigo por causa do tamanho maior), ‘As duas principais regras de otimizagdo também aplicavel para as especificagdes lexical: 1. no fazé-lo 2. (Para especialistas apenas) nio fazé-lo ainda ‘Algumas das dicas de desempenho acima contradizem um estilo especificagdo legivel e compacto, Em caso de duivida ou quando os requisitos ndo so ou ainda ndo fixo: no usé-ls - a especificago sempre pode ser otimizado em um estado posterior do processo de desenvolvimento. Questées portar Portando a partir JLex JFlex foi concebido para ler especificagdes JLex velha inalterado e para gerar um scanner que se comporta exatamente 0 mesmo que a gerada pelo JLex coma iinica diferenga de ser mais répido, Isso fimciona como esperado em todas as especificagdes bem formados JLex. Uma vez que a afimagio acima é um tanto absohita, vamos dar uma obhada no que "bem formados significa aqui. A especificagdo JLex esti bem formado, quando gera um scanner trabalhar com JLex ‘* ndo contém os caracteres unescaped ! ¢ ~ Eks so operadores JFlex enquanto JLex trata-los como caracteres de entrada normal. Vocé pode facilmente portar tal especificagio JLex para JFlex substituindo cada ! com \! e cada ~ com’ - em todas as expresses regulares. © tem apenas completar expresses regulares entre parénteses nas definipSes macro Isto pode soar um pouco duro, mas poderiam ser um grande problema - ele também pode ajudar a encontrar alguns bugs nojentos na sua especificago que nio apareceu em primeiro lugar. Em JLex, um lado direito de uma macro é apenas um pedago de texto, que & copiado para o ponto onde © macro & usado. Com isso, algum tipo estranho de coisas como Macrol = ("ola" Macro? = {} Ma{foi possivel (com™acro2 expandindo para ("014") * ). Isso nio é permitido em JFlex e vooé ter de transformar tais definipSes. No entanto, existem alguns tipos mais sutis de erros que podem ser introduzidas por macros JLex. Vamos considerar uma defini como macro = a | be umuso como se expande em JLex paraa | b * eno ao provavelmente pretendia (2 |b) * 1} * macro . Es JFlex usa sempre a segunda forma de expansio, uma vez que esta é a forma natural de pensar sobre abreviagdes de expresses regulates, Maioria das especificagdes nao devem softer com este problema, porque muitas vezes contém apenas macros (inofensivo) classes de personagens como ai fa = [a-2A-2) ¢ definigdes mais perigosas como ident = (alpha) ({alpha} | {} digites) * sto usadas apenas para escrever regras como {} {ident .. agao . € niio expressdes mais complexas, como ty * (Ident. agao 3 onde o tipo de erro apresentado acima ira aparecer. Portando de lex / flex Esta seco procura dar uma visio geral das atividades e possiveis problemas ao portar uma especificago lexical da C/C++ ferramentas lex e flex [ LL] disponivel na maioria dos sistemas Unix para JFlex. ‘A maior parte do C / C + ~ caracteristicas especificas ndo esto presentes naturalmente nos JFlex, mas a ‘maioria ” limpar"lex / lex especificagdes lexical pode ser portado para JFlex sem muito trabalho. Esta seco € no muito completo e é baseado principalmente em uma pesquisa coma pagina man flex e nnuito pouca experigncia pessoal. Se vocé se entvolver em qualquer atividade de portar lex / flex para JFlex e encontrar problemas, temos as melhores solugdes para os pontos aqui apresentados ou ter apenas algumtas dicas que voc’ gostaria de compartihar, por favor, entre em contato comigo . Eu vou incorporar a sua experiéncia neste manual (com todo o crédito que the ¢ devido, é Estrutura basica A especificagao lexical sobre o flex tema seguinte estrutura basica: definicses as regras0 cédigo izador segdo geralmente contém um cédigo C que ¢ usada em agdes de regvas parte da especificagao. Para JFlex a maior parte deste cédigo teré que ser inchido no cédigo da classe +(..¢} ditectiva 2 se¢do (depois de traduzir 0 cédigo C para Java, & claro), no opgées © declarag: Macros e Sintaxe de Express6es Regulares A definicao de uma especificagdo sega flex & bastante semelhante a0 opcées © declaracées parte especificagdes JPlex. Definigdes de macro em flex tém a forma: Para a porta-ls para macros JFlex, basta inserir um = entre ‘A sintaxe ea semintica de expressées regulares em flex so praticamente o mesmo que em JFlex. A pouca atengdio é necessério para algumas seqiigncias de escape presentes em flex (tais como a \ ) que niio sdo suportados no JFlex. Essas seqiiéncias de escape deve ser transformada em suas octal ou hexadecimal equivalente, Outro ponto so as classes de caracteres pré-detinidos. Flex oferece os suportados diretamente pelo C, JFlex oferece as suportadas pelo Java. Essas classes, por vezes, tém de ser listados manualmente (se houver necessidade de este recurso, pode ser implementado em uma versdo JFlex fituro. Regras lexical Desde flex é em sua maioria baseados em Unix, 0" "(inicio da linha) e" $ "(fim de linha) operadores, considere ©.\ 86 personagem como terminador de linha. Isso deve causar problemas geralmente nao muito, mas voce deve estar preparado para ocorréneias de \ x ou\ r \ n ouumdos personagens \ 92028, \ u2029,\ 40008, \ u000C, 0u\ 30085 . Bes sdo considerados como terminadores de linha em Unicode e, portanto, no podem ser consumidos quando * ou $ esti presente em uma regra, Trabalhando juntos JFlex e CUP Um dos objetivos principais do projeto de JFlex era fazer a interface como gerador de parser Java livre CUP [8 ] to facil quanto possivel. Isso tem sido feito dando a aca’ directiva um significado especial, Uma interfice no entanto, sempre tern dois lados, Esta sego se concentra no lado CUP da histiria CUP versao 0.10j e acima Desde CUP versio 0.10), esta tem sido bastante simplificado pelo novo scanner de interface CUP java_cup. runtime Scanner . Lexers JFlex agora implementar esta interface automaticamente quando 0 entlo x: cara’ opgdo é usada. Nao hi especiais analisado= de céd Gigitalizar com mais opgdes que vocé tem para oferecer em sua espe: apenas se concentrar em sua gramiatica, seédigo de inicializacao ou io parser CUP. Voeé pode Seo seu lexer gerado tem o nome da cla Se Scanner , 0 analisador ¢ iniciado a partir do programa principal como esta: parser p 4 Scanner (new FileReader (fileName)))+ Interface personalizada simbolo Se voc8 jé usou 0 simboio- chave de linha de comando de CUP para mudar o nome da interface simbolo gerado, vocé tem que dizer JFlex sobre esta mudanga de interface para que 0 cédigo final de-arquivo correto & gerado. Vocé pode fazer isso ou usando umeofvals { directiva ou usando ¢ «kor» regra Se sua interfice novo simbolo é chamado nysyn por exemplo, 0 cédigo comespondente na especificagio JFlex setia ou Bofvals retorno mysym.FOF; Eofvall na segdo de macro / drectivas da especiticagao, ou seria <> (Mysym.£0F ret na segdo de regras do seu spec Usando existentes JFlex / CUP especificagées com CUP 0.10} Se vocé jé tem uma especificagdo existente ¢ voc’ gostaria de atualizar tanto JFlex e CUP & sua mais nova versio, vocé provavelmente terd de ajustar a sua especificagdo. A principal diferenga entre a chavena’ interruptor na JFkx 1.2.1 ¢ inferiores, ea versio atual & IFlex, que scanners JFlex agora implementar automaticamente 0 java_cup. runtime. Scanner interfice. Isto significa ue 2 fimedo de disitalizacto agora muda o seunome de vviex () para next token 0A principal diferenga de verses mais antigas CUP para 0.10} & que CUP agora tem um construtor padriio que aceita um java_cup.runtine. Scanner como argumento € que usa este scanner como pad (por isso no verificagse com cédigo & necessério mais). Se vocé tem uma especificago CUP existente, ele provavelmente vai se parecer mais ou menos assim: e6digo do analisador Lexer lexe piblico (java.io.Reade: exer = new Lexer (entrada) + scan com {: lexer.yylex return (71); Para atualizar para CUP 0.10}, voeé pode alteré-lo para ficar assim: c6digo do analisador leo (java.io-Reader entrada) super (nova Lexer (entrada) )} Se vocé nio se importa de mudar 0 método que esti chamando o analisador, vocé pode remover 0 construtor inteiramente (¢ se no hé mais nada nek 0, bem como, & claro). O procedimento de chamada principal, entdo, construir o parser como mostrado na segdo acima, todo 0 cédigo do analisador s A especificagao JFlex ndo precisa ser alterado, Usando versoes antigas do CUP Para pessoas que gostam ou tem que usar verses mais antigas do CUP, a segdo a seguir explica” a maneira antiga". Por favor, note que o nome padro da fingdo de digitalizacdo coma zacas switch nfo é yylex () , mas next_token (). Se vocé tiver uma especificagdo de scanner que comega assim: PACOTE pacote; java_cup.runtime importagao / / * isto é conveniéneia, mas nao 6 necessario + em seguida, ele corresponde a uma especificagéio CUP partida como PACOZE p:{e6dige do analisador: Lexer lexer; parser piblico (java.io.Reader entrada) { lexer = new Lexer (entrada) ; an com {: lexer.next_token return ()3:); Isso pressupde que 0 analisador gerado tera o nome parsex . Se niio, vocé tem que ajustar o nome do construtor. O interpretador pode entio ser iniciado em uma rotina princjpais como estes: try ( parser p ~ novo analisador (new FileReader (fileName)); P.parse resultado Object = () valor; , catch (Exception ¢) { Se vocé quiser a especificagiio analisador para ser independente do nome do scanner gerado, voeé pode escrever uma interfice em vez Lexex public interface Lexer { next token java cup.runtime.Symbol publica () throws java.io. T0Exceptio > aterar 0 eédigo de parser para: PACOTE pacote; {c6digo do analisadoi Lexer lexer; parser piblico (Lexer lexer) { this.lexer ~ lexer; ) scan com {: lexer-next_token return ();:}7 JFlex dizer sobre a interface usando 0 lexer 3 impiementa directiva: Classe% Scanner / * ndo Lexer agora desde que é a nossa interface! * / 8 Implementa Lexer cupt«, finalmente, mudar a rotina principal para parecer = nove analisador (new Scanner (new FileReader (fileName) ))+ se resultado Object = () valor; catch (Exception e) { Se vocé quiser melhorar as mensagens de erro que parsers CUP gerada produ, vocé também pode substitu ror € zeport_fatal_ezzor no cédigo parser segdo “da especificag’io CUP. Os novos métodos poderiam, por exemplo, use yyline € yycolumn (armazenado no esquerde € direito os membros da classe § ime. symbo ) para reportar as posigdes de erro de forma mais conveniente para 0 usuirio, O lexer ¢ analisador para a linguagem Java na exanpies / java diretério da distribuigdo JPlex usar este estilo de relatério de ertos. Estas especificagdes também demonstrar as técnicas acima em ago. 05 métodos report_ JFlex e byace /J JFlex tem suporte embutido para a extenséo Java byace /J [2] por Bob Jamison para o ckissico gerador de analisador Yace Berkeley. Esta segdo descreve como a interface byace / J com IFlex. Baseia-se nmitas sugestées titeis e comentirios de Larry Bell. Desde a arquitetura Yace & um pouco diferente da CUP, a configuragio da interface também fimciona de forma ligeiramente diferente, Byace / J espera uma fimgdo yylex int () ma classe parser que retoma cada token seguinte, Valores seminticos so esperados em um campo yyivai do tipo parserval onde” parse: "60 nome da classe parser gerado, Para um exemplo de calculadora pequena, pode-se usar um conjunto de como o seguinte no lado JFlex: joan yyparser parser privado; enar uma referéncia ao objeto parser * / /* Constzuter de tomar um publica yylex (java.io.R esta (z); chis.yyparser = yyparser: Jeto analisader adiclonals * / der r, yyparser parse 0-9as / * operadores * / ery ney my" (Return (Lat) yycharat (0);) 7 * Nova linha * / (NL} [return pars: NLP} /* Float * / (NUM) (yyparser.yylval = new parserval (Double.parseDouble (yytext ())); parser .NUM retorno:} exer espera uma referéncia para o analisador em seu construtor. Desde Yace permite 0 uso direto de caracteres de terminal, como '~" em suas especificagdes, nds apenas retomar 0 eédigo do caractere tinico partidas char (por exemplo, os operadores no exerplo). Simbélico nomes de token so armazenados como public static int constantes na classe parser gerado. Els so usados como no wz simbolo acima. Finalmente, para alguns tokens, um valor semantico pode ter de ser comunicadas ao analisador. O num regra demonstra que pouco. A eespeciticagao do parser comespondéncia byace / J poderia ficar assim: a import java.io. * Token de NL / * nova linha * / mbolo’ NUM / * um numero * / \ Exp tipo Sibert "7 14! S Certo '*' / exponenciagao * * / 38 exp: NUM {$$ = § 17) | Exp ‘tt exp ($ $= $245 37) | Exp '** exp ($ § Math.pow = (5 1, $ Deh 1 'C exp 1)" = {9 8 $ 23) rr + Uma referéncia ao objeto lexer * / privada yylex exer /* Interface para o lexer * / yylex private int () { int vi return = -17tch (10Exception e) m.err.printin ("Erro de I retorne yyl_return Erro de 7 ico (leitor r) { parser pat exer = new yylex (ry } / * 6 assim que vocé usar o parser * / public static void main (String args []) throws T0=xception | yyparser parser = new (new PileReader (args [01))7 yyparse: OF ? Aqui, a pega personalizada é principalmente na seedo de cédigo de usuario: Nés criamos o lexer no construtor do analisador e armazenar uma referéneia a ele para usar mais tarde no analisador de yyiex int () método. Este yylex no analsador apenas chamadas yylex int () do lexer gerada e passa o resultado diante. Se algo der errado, ele retoma -1 para indicar um erro, Runnable verses das especificagdes acima estio localizados no examples / byace) diretério da distribuigdo JEex. Erros e deficiéncias Deficiéncias Correspondéncia Unicode nio esti totalmente em conformidade com o relatério atual relevantes Unicode. Em vez disso, o suporte a Unicode em JFlex é 0 nativo de um a Java. Isso significa que, apenas 16 pontos de cédigo bit sdo suportadas ¢ classes de personagens mais Unicode no so diretamente suportados (embora eles podem ser personalizados definidos em macros). A verso de desenvolvimento Java 5 de JFlex contém um melhor suporte para Unicode, como vai langar o proximo grande.Erros A partir de 31 de janeiro de 2009, sem bugs foram relatados para JFlex versio 1.4.3. Todos os erros relatados em versdes anteriores foram corrigidos. Se vocé encontrar novos problemas, por favor use a segdo de erros do site JFlex relaté-bs. Copia e Licenga JFlex é um software livre, publicado sob os termos da GNU General Public License ‘Nao hi absolutamente nenhuma garantia para JFlex, seu cédigo e sua documentagdo, cédigo gerado pelo JFlex herda os direitos autorais da especificagao foi produzido a partir de. Se fosse sua especificagao, vocé pode usar 0 cédigo gerado, sem restrigbes. Veja o arquivo copvarcisr para mais informagdes. Bibliografia 1 A. Aho, Sethi, J. Ullman, Compiladores: Principios, Técnicas e Ferramentas , 1986 2 AW Appel, Jmplementagdo Compiler Moderna em Java: téenicas basicas , 1997 3 E. Berk, JLex: um gerador de analisadores léxicos para Java, wit»: / www neeton.edus appe ava / Ilex 4 K, Brouwer, W. Gellrich, B, Ploedereder, Mitos e Fatos sobre a implementagdo eficiente de Autématos Finitos e Andlise Lexical , in: Anais da 7 * Conferéneia Intemacional sobre Construg ‘Compiler (CC 98), 1998 5 M. Davis, Diretrizes Expressdo regular Unicode , Unicode Technical Report # 18, 2000 6 P. Dencker, K. Durre, J. Henft, Otimizacdo de Tabelas Parser para compiladores portéteis , in:UpeLayVES ALIVE UE LULYELS UE FLOEFAIIBYAY © OBLELES GE DH), 170 1 J. Gosling, B. Joy, G. Steele, a Especificagdo de Linguagem Java , 1996, http: //java,sun,com/doos /books/ile 8 SE Hudson, CUP Parser Generator LALR para Java , bzto appel / wodern / java / CUR / 9 B, Jamison, byace /J, bite 10 T. Lindholm, F. Yellin, A Maquina Virtual Java Specification , 1996, bitos/ M1 V. Paxson, flex - O gerador de analisador léxico répido , 1995 12 RE Tarjan, A. Yao, Armazenar uma Tabela Sparse , in: Communications of the ACM 22 (11), 1979 13 R. Wilhelm, D. Maurer, Ubersetzerbau , Berlin 1997 ? mathend000 # Notas de Rodapé .. Java Java é uma marca comercial da Sun Microsystems, Inc, ¢ refere-se a programagdo Java da Sun linguagem. JFlex nfo é patrocinado ou afilada com a Sun Microsystems, Inc. Séib 31 jan 2009 23:43:28 EST, Gerwin Klein