Вы находитесь на странице: 1из 49
Plane O Gerador de Analisador léxico rapido Copyright © 1998-2009 por Gerwin Klein Manual do Usuario JFlex Versdo 1.4.3, 31 de janeiro de 2009 Conteuido © Introductio © Objetivos do projeto © Sobre este manual © Instalando ¢ executando JFlex © Instalando JFlex © Execucio Flex © Umexemplo simples: Como trabalhar com JFlex © Cédigo para inclur © Opedes e Macros © Regras e acdes © Co seéela © Especificagdes lexical © Codificacdes, plataformas e Unicode © O Problema © Digitalzacdo de arquivos de texto © Digitalizacdio binirios © Algumas palavras sobre o desempenho © Comparaco de JLex e JFlex © Comp escrever um ripido especificaedo © Questées portar © Portando a partir JLex © Portando de lex / flex © Trabalhando juntos © JFkxe CUP © Copia e Licenea © Bibliografia Introdugao JFlex 6 um gerador de analisador Kxico para Java’ ferramenta muito util [ 3 ] que foi de Ez escrito em Java. E também uma reescrita da JLex snvolvido por Elliot Berk na Universidade de Princeton. Como Vern Paxson estados para sua C / C++ ferramenta flexivel ( 11. s ndo compartifham nenhum eédigo embora, Objetivos do projeto Os objetivos do projeto principal de JFlex so: © Suporte total a Unicode © Rapido scanners gerados © Geragio de scanner ripido “s ‘ago conveniente © Independéncia de plataforma © Compatibilidade JLex taxe especi Sobre este manual Este manual dé uma descrigdo breve mas completo da JFlex ferramenta. Ele assume que voc’ esteja famibiarizado coma questio da andlise lexical. As reféréncias [ 1 ], [2] ¢ [ 13 ] fornecem uma boa introdugdo a este tpico. A proxima sego deste manual descreve os procedimentos de instalacdo para JFlex. Se vocé munca trabalhou com JLex ou apenas quer comparar um JLex e uma especificagao scanner JFlex vocé também deve ker Trabathando com JFlex - um exemplo (segao 3 ). Todas as opgbes ea sintaxe especificagdo completa sto apresentados em especificacdes Lexical (segio 4); Codificacdes, plataformas e Unicode (seo 5 ) fornece informagdes sobre digitalizago de texto versus arquivos bindtios. Se vocé estiver interessado em considerages sobre o desempenho e comparando com JLex JFlex velocidade, algunas palavras sobre o desempenho (Seedo 6 ) pode ser apenas adequado para vocé. Aqueles que querem usar as suas especificagdes JLex velho pode querer veriicar para fora seco 7,1 Portando de JLex para evitar possiveis problemas com 0 comportamento JLex no portitl ou ndo padrio que fbi fixado em JFlex. Seedo 7,2 fala sobre scanners portar a partir das ferramentas Unix lex e flex. Interface scanners JFlex como analisador LALR geradores CUP ¢ byace / 1.6 explicado em trabalhar em conjunto (segio & ), Segio 9 erros dé uma lista de erros atualmente conhecidos ativo. © manual conchii com notas sobre Cépia e Licenca (segao 10.) referéncias Instalando e executando JFlex Instalando JFlex Windows Para instalar no Windows JFlex 95/98/NT/XP, siga estes trés passos: 1. Descompacte 0 arquivo que vocé baixou para o ditetério que vocé deseja JFlex in (usando algo como o WinZip ), Se voc descompactou dizer c: \ , a seguinte estrutura de diretério deve ser gerado: cr \ aFlex \ = Bin \ (script \ (FAQ e manual) amples \ 1 = Binario \ (aig: +> Byacc} \ (exemple = cup \ (exemple ca zagko de arquivos bindrios) culadora para byace / J) ‘ Ladera para cop) + prete \ (exemple in ¥ > Java \ (Java especificacso Lexer} + -\ Simples (scanner exenpl =n rete para copo! “maven \ (exemple com maven) one \ (um = Standalone-maven \ (acima com maven) += \ Lib (as classes pré. nner simples standalone) compilados) += sre \ + = JFlex \ (eédigo: + = SPlex \ qui (cédigo-fonts + - Java_cup \ runtime \ (c6: onte do JFlex) das classes JFlex Ur) go-fonte das classes copo runtime) 2. Editar 0 arquivo bin \ $£1ex.bat (no exemplo &c: \ gFlex \ bin \ jfiex.bat )talque © gava_Home contém o diretétio onde o Java JDK esti instalado (por exemplo c: \ java )e © SFLEX_HOME 0 diretério que contém JFlex (no exemplo:c: \ Flex) 3. Inclua o bin \ ditetério de JFlex em seu caminho. (Aquele que contém o script de inicializagio, no exempl:c: \ oFlex \ bin). Unix com tar Para instalar JFlex em um sistema Unix, siga estes dois passos: © Descomprimir o arquivo para um diretério de sua escolha como GNU tar, por exemple para / usr / ¢ / usr / share-xv2f JFlex-1.4.3.t (0 exemplo & para a instalagdo do site de largura Vocé precisa ser raiz para que a instalagdo do usurio fianciona exatamente da mesma maneira - basta escolher um diretério onde vooé tem permissio de escrita) * Faga um link simbélico de algum lugar em seu caminho bindrio para bin / JP 1ex , por exempl: s/w x / share / Jflex / bin / JPlex / usr / pin / JPlex Se o interpretador Java niio esté em seu caminho bindrio, vocé precisa fomecer a sua localizagio no script bin / JFiex ‘Vocé pode verificar a integridade do arquivo baixado como MDS checksum disponivel no pagina de download JEkx . Se voe’ colocar o arquivo de checksum no mesmo diretétio como o arquivo, vocé executa: 1.4.3.tar.gz.md5 Deve dizer-lhe Linux com RPM © tomar-se root © questi zpm-u JPlex-1.4.3 Vocé pode verificar a inte lade do download rpm arquivo com rpm ~ checksig JFlex-1.4.3-0.rpm Execugao JFlex Executar JFlex com: Também é possivel ignorar o script de inivialiagdo em bin \ e inchtiro arquivo 1i® \ gPiex.jar na sua CLASSPA# varivel de ambiente em seu higar. Em seguida, executar JFlex com: ava Main Os arquivos de entrada e as opgdes so em ambos os casos opcionais. Se voc’ nfo fornecer um nome de arquivo na linha de comando, JFlex ird aparecer uma janela para pedir-Ihe um, IFlex sabe sobre as seguintes opgGes: diretério> gyava o arquivo gerado para 0 diretorio usa esqueleto extemo <£iie> Isto é prineipalmente para a manutengo JFlex e especial personalizagde: de nivel baixo, Use somente quando voeé sabe que vocé esté faendo! JFlex vem com um arquivo esqueleto no sxc diretério que reflete exatamente a interna, 0 esqueleto pré-compilido e pode ser usado como ~skel oped. pular a etapa de minimizagaio DFA durante a geragdo do scanner. tenta ainda mais dificil de cumprir a interpretagao JLex de expecificagdes = Dot gaphviz gerar arquivos ponto para o NFA, DFA DFA ¢ minimizados. Este recurso ainda est em estado alpha, € niio totalmente implementadas. = Dump exibir tabels de transigiio de NFA, DFA inicial, e DFA minimizado ~ Verbose ou-v mostrar geragdo de mensagens de progresso (ativado por padrio) = Quiet ou-q cexibir mensagens de erro apenas (sem conversa sobre © que esta fazendo atualmente JFlex) ~ Tempo de cexibir estatisticas de tempo sobre o processo de geragdo de cédigo (no muito preciso) ~ versio nlimero versio para impressio do sistema de impressio ¢ informagdes JDK (tt se vocé gostaria de relatar um problema) - Pacote de usar 0 pacote% método de geragdo de cédigo por defeito = Mesa ae usar a tabela% método de geragdo de cédigo por deftito -a sar 0 interruptor% método de geragdo de eédigo por defeito ave de Help ou-h imprimir uma mensagem de ajuda explicando as opgdes e uso de JFlex Um exemplo simples: Como trabalhar com JFlex Para demonstrar o que uma especificagdo lexical com JFlex parece, esta segdo apresenta uma parte da especificago para a finguagem Java, O exemplo niio descreve toda a estrutura lexical de programas Java, mas apenas uma pequena parte e simplificada da mesma (algumas palavras-chave, alguns operadores, comentarios © apenas dois tipos de lterais). Ele também mostra como a interface com o gerador de analisador LALR CUP [ 8 J, portanto, usa uma classe syx (gerados por CUP), onde constantes inteiras para o terminal de tokens da gramitica CUP so declarados. JFlex vem com um diretério de exempios , onde vocé pode encontrar um scanner auténomo pequeno que nio precisa de outras ferramentas como CUP para the dar um exemple em execugio. Os " exenplos “diretSrio também contém um completo especificagao JFlex da estrutura lexical de programas Java, juntamente coma especificagdo do parser CUP para Java por C. Scott Ananian , obtidos a partir da CUP [8 ] web site (ele foi modificado para fazer a interface com o scanner JFlex). Ambas as especificagdes aderir a linguagem Java [Especificagdo 7 J. /* Bxamplo JFlex: parte da linguagem Java lexer especificagao * / importagao java_cup.runtime . sa classe é un exemplo simples lexer. hexer classe’, Unicode’ cups inka’ colunas a StringBuffer string - new StringBuffer ()7 simbolo Symbol privada (tipo int) { reterno nove simbole (tipo, yyline, yycoluan); } simbolo Symbol privada (int tipo de valor, Object) { retorne novo sinbolo (tipo, yyline, yycolumn, valor); ) a hineverminator = Vir | Val \ Va InputCharacter = [* \ x \ nl Espagos em branco = {} LineTerminator | [\ t \ £] /* Comentarios * / Comment = (Traditionalcomnent} | {SndOfLinecomment} | {} DocumentationComment wraditionalcomment = "/ «™ [* *} ="4/" | m/f am mem 4 nym EndOfLineConment = "/ /" (} * (InputCharacter LineTerminator} DocumentationComment - {"/**" CommentContent} "*" + "/" CommentContent = ((* *] | \ "+ 1°/*]) * Identificador = [: jletter:] [: jletterdigit:] * DecIntegerLiteral = 0 | [1-9] [0-9) * STRING estadot a /* Palavras~chave * / "Abstrato” {simbolo de retorno (sym.ABSTACT) :} "Boolean" (return simbolo (sym.BOOLEAN) ; } "Break" {simbolo de retorno (syn.BREAK) ;} { /* Identificadores * / () (Return Identifieador simbolo (sym. IDENTIFIER) ;} 7 Literais + / {} {DecIntegerLiteral simbolo de retorno (sym. INTEGER LITERAL) ;} ring.setLength (0); yybegin (STRING); (Return simbolo ( Return simbolo (sym.2. (Return einbolo (sym + Comentarios * / {Comentario} {/ * ignore * / //* Espace em branco * / (Whitespace) {/ * ignore * / np (8YINTTIAL) + rial de retorno (sym.S?RING_1 Dat LITERAL, string. id (yybext (Ys appe \.\T {string.append \\N (steing-append (1) 2')3) \\R (steing-append (1\ 243) end CV"): DG * Fallback de erzo * / | \W (throw new Error ( < ‘A partir desta especificagao JFlex gera um . java arquivo com uma classe que contém o eédigo para o scanner. A classe teré um construtor tomar um java. io. Reader a pattir do qual a entrada é ler. A classe também tem uma fingdo yylex () que executa o scanner ¢ que pode ser usado para obter o préximo token da entrada (neste exemplo, a fungdo tem realmente © nome next coker () porque a especificago usa 0 copo% switch) ‘Tal como acontece com JLex, a especificagdo consiste em trés partes divididas por 8 © usercode , © opcies e declaragdes € © regras lexicais Cédigo para incluir ‘Vamos dar uma olhada na primeira segdo, “0 cédigo do usuétio": © texto até a primeira linha comegando com, ** & copiado na integra para o topo da classe gerada lexer (antes da declaragdo da classe real). Ao lado pacote ¢de importacae declaragdes no hi normalnente muito para fazer aqui. Se o cédigo termina com 4rio javadoc da classe, a classe gerada vai ter este comentitio, se nio, vai gerar um JFlex automaticamente. Opgées e Macros ‘A segunda secgdo a opsdo " e"declaragdes é mais interessante. E constituida por um conjunto de opgdes de cédigo, que esta incluido dentro da classe scanner gerado, afirma lexical e declaragées macro, Cada opgao JFlex deve comegar uma linha de especificagdo e comeca comum § . No nosso exemplo as seguintes opgdes sio usadas © exer diz JFkx para dar a classe gerada 0 nome “* Lexer'e esctever 0 cédigo para um arquivo * Lexer java" define o conjunto de caracteres que o scanner itd trabathar. Para a digitalizacdo de arquivos de texto, unicode’ devem ser sempre utizados. Ver também secedo 5 para mais informagdes sobre conjuntos de caracteres, codificagdo e digitalizagdo de texto versus arquivos bindrios. ‘© cups muda para CUP modo de compatibilidade para fazer a interface com um analisador CUP gerado. * LinhaS line interruptores contando com (o niimero da linha atual pode ser acessado através da varidvel yyline) © coluna coluna contando com interruptores (coluna atual é acessado via yycot umn ) cédigo inchuido no ¢1...1 € copiado na integra na fonte gerado lexer classe. Aqui vocé pode declarar variiveis de membro e fimgdes que so usadas dentro agdes scanner. No nosso exemplo nés declaramos um StringBurfer” cadeia "em que ird armazenar pegas de litrais string e duas fimedes auxiliares "* simboie 1M java_cup. runt ine. Symbol objetos com informagses sobre a posizdo do token atual (ver secedo S.LJElex CUP e de como a interface como gerador de analisador CUP). Como opgies JFkex, tanto © ( €§ \) deve comecar uma linha A especificagdo continua com deckaragdes macro. Macros sio abreviagdes de expressdes regulares, usado para fazer especiticagdes lexical mais ficil de ler ¢ entender. A declarago de macro consiste em um identificador macro seguido por ~ , seguido pela expressdo regular que representa. Esta expressdo regular pode conter em si 6s usos macro. Embora isso permite uma gramitica como o estilo de especificagdo, macros ainda sdo apenas abreviaturas e terminais nao ndo - ndo pode ser recursiva ou mutuamente recursivos. Ciclos nas definigées de macro so detectados ¢ relatados no momento da geragdo de JFlex. ‘Aqui algumas das macros exemplo mais detalhadamente: © Lineverminatox significa a expresso regular que corresponde a um CR ASCIL, um LF ASCII ou um CR seguido de LF. representa todos os personagens que nio so um CR ou LF @ Traditianatonnment fa eunteesia ane carecnande a seniiineia # / + cponida nari caraoters - LALLA Wo wayinenouny yim SUHELOpiRiN 4 oun) ONgURN PH SuSE que milo é um * , seguido por qualquer coisa que no contém, mas termina em"/ +" . Como este nfo corresponde comentarios como /****/ , nés adicionamos "/ = seguido de um nimero arbitratio (pelo ‘menos um) de "+" seguido pelo fechamento */» . Esta ndo é a tinica, mas uma das expresses mais simples correspondéncia comentirios nao nidificagdo Java. i tentador simplesmente escrever algo como expresso "/ *" .* "+ /*, mas isso corresponderia a mais do que queremos. Seria, por exemplo coincidir coma totalidade da / * + / x = 0; / * * /,emvezde dois e quatro comentarios tokens real. Ver DocumentationComment ¢ CommentContent para uma alternativa, corresponde a zero ou mais ocorréncias de quakjuer caractere, exceto um * ou ‘qualquer nimero de * seguido por um caractere que nio é um / © identifica ‘orresponde a cada cadeia que comega com um personagem da classe j 1 seguido por zero ou mais caracteres de clisse j1etterdigit . jletter € jletzerdigit sHo classes de personagens pré-definidos. j1eccex inchii todos os personagens para os quais a fungo Java sJavaldentifierstart reloma verdadelro e }letterdigtt todos os caracteres Part retoma v Character. para esse ch Lsvavazden! edadeiro A titima parte da segunda seco do nosso especificagao lexical é uma declarago de estado lexical srk aatadas declara um estado lexical sT21NG que pode ser usado nas regras ‘"lexical parte da especific declaragio de estado é uma linha comecando com estado’ seguido por um espago ou virgula separados lista de identiticadores do Estado. Nao pode haver mais de uma linha comecando com estado% Regras e agées "kxical regras" sego de uma especificayao JFlex contém expresses regulates e agGes (Java de cédigo) que sdo executados quando o scanner corresponde 4 expressdo associada regular. Como o scanner Ié sua entrada, eke mantém o controle de todas as expresses regulares ¢ ativa a ago da expressdo que tem a mais longa partida, Nossa especificagdo acima, por exemplo, faria com input " breaker "corresponder & expresso regular para idensi ficadox e nifo a palavra "pause ", segnido do Identifier" ex ", porque a regra ( dent ificader partidas mais esta entrada de uma sé vez (ou seja, corresponde a todos os de -lo) do que qualquer outra regra na especificagdo, Se duas expressdes regulares ambos tém.a mais longa partida para uma entrada certa, o scanner escolhe a aco da expressdo que aparece em primeiro lugar na especificagdo. Dessa forma, temos de "input quebrar "a palavra" pause "e no um Identifier" quebear " ‘Adicionais para jogos de expresses regulares, pode-se usar estados lexical para refinar uma especificagao. Um. estado lexical fimciona como uma condigdo de inicio. Se o scanner esta em estado lexical sta Nc , apenas expresses que so precedidas pela condigdo de inicio podem ser combinados. A condigdo de inicio de uma expressio regular pode conter mais de um estado lexical. Em seguida, ¢ compensada quando o lexer & «em qualquer um desses estados lexical. O estado lexical vv ur rA%, € predefinido e é tambémo estado em que © lexer comeca a digitalizar, Se uma expresso regular ndo tem condigdes de inicié-lo é correspondida em todos cs estados lexical. Uma vez que muitas vezes voed tem um monte de expressdes com as condigdes de inicio mesmo, Flex permite (que a mesma abreviatura como a ferramenta Unix flexive { exprl {) expr? {) a significa que ambos expr? ¢ expr? tém condigdo de inicio As trés primeiras regras em nosso exemplo demonstra a sintaxe de uma expresso regular precedida pela condigdo de inicio < INITIAL> x sinbi i ALS (sym. ABSTAA’ corresponde & entrada " abst rata "somente se o scanner esté em seu estado inicial" yv2w2r1a1, ", Quando a sting " abst rata "é comespondida, a fingao de scanner retomna o simbolo CUP sym.assTanct . Se uma agdo no retoma um valor, o processo de digitalizagdo é retomada imediatamente apés a execupdo da ago. ‘As regras fechados em demonstrar a sintaxe abreviada e também sio apenas acompanhado no estado YY INITIAL Destas regras, pode ser de especial interesse: ‘Seo scanner corresponde a uma aspas duplas no estado yyzNrrrax, reconhecemos o inicio de uma string literal. Portanto, clara a nossa stxing3uffer que conterd o contetido desta string literal e dizer ao scanner com 1» (STRING) para mudar para o estado lexical sTRTNG . Porque nbs ainda no retomar um valor para o analisador, o nosso scanner prossegue imediatamente. No estado lexical struc outra regra demonstra como referenciar a entrada que tem sido encontrados: Phvw yey sna. append Acxpressiio [> \ n \ x \ "] + corresponde a todos os personagens da entrada até a barra invertida ao lado (indicando uma seqiiéncia de escape como \ = ), aspas duplas (indicando o fim da string), ou terminador de linha (que nao deve ocorrer em uma seqiiéncia literal). A regido correspondent da entrada & referido com yytext 11 ¢ anexados ao contetido da string literal analisado até o momento. A tina regra lexical na especificagao exemplo é usado como um fallback erro. Ela corresponde a qualquer caractere em qualquer estado que no tenha sido acompanhada por uma outra regra, Ele ndo entra em contlito com qualquer outra regra, pois tema menor prioridade (porque & a ikime regra) e porque apenas um personagem (por isso néfo pode ter mais longa partida precedéncia sobre qualquer outra regra). Como ir busca-la 4 Instale JFlex (ver secgio 2 Instalando JFlex ) * Se voc’ tiver escrito 0 seu arquivo de especifcagao (ou escolhido um dos exenpios do diretéro), salvi- o (por exemplo, como nome java-lana. flex ). © Executar com JFlex ex java-lang. flex ¢ JFlex deve, entdo, algumas mensagens relatério de progresso sobre a geragdo do scanner e escrever 0 cédigo gerado para o diret6rio do seu arquivo de especificagao. © Compilar os arquivos . java arquivo e suas préprias classes. (Se vocé usa o CUP, gerar classes de seu analisador primeiro) © Eisso ai, Especificagées lexical Como mostrado acima, um arquivo de especificagao lexical para JFlex consiste em trés partes divididas por uma ‘imica linha comegando coms : Em todas as partes dos comentirios especificagdo na forma 0 com / * * /¢0 fim do estilo de comentérios Java linha de partida com / / sio permitidos. Comentarios JFlex fazer ninho - assim o némero de / + e* / deve ser equibrada Cédigo de usuario A primeira parte contém o eédigo do usuirio que & copiado na integra no inicio do arquivo fonte do lexer gerados antes a classe scanner & declarada. Como mostrado no exemplo acim, este & o lugar para colocar © de declaragées e importacao declaragdes. E possivel, mas no considerado como um bom estilo de programasao Java ppara colocar propria classe auxiar (tals como classes token) nesta segio. Bles devem Leomeyatt Us seus propims . java wyuve eM vez. Opgées e declaragées A segunda parte da especiticagaio lexical contém opedes para personalizar o seu lexer gerados (IFlex directivas © cédigo Java a inchuir em diferentes partes do lexer), declaragdes de estados lexical e definigdes macro para uso ta terceita seo“ regras"Lexical de 0 processo de especificagio lexical Cada directiva JFlex deve ser situado no inicio de uma linha e comega como & de cariter, Directivas que tém um ou mais pardmetros estio descritos a seguir: % ba classe "classname" significa que voc® inicie uma linha com classes seguido por um espaco, seguido do nome da classe para 0 scammer gerados (as aspas sto ndo devem ser inscrtas, consulte a especificagdo de exemplo na segiio 3 ). Opgées de classe e cédigo de classe de usuario Estas opgdes de nome de respeito, o construtor, API, ¢ respectivas pesas da classe scanner gerado, © ba classe “classname” Diz JFlex para dar a chasse gerada o nome de" arquivo" cia: "e escrever 0 cédigo gerado para um > opedo de linha de comando nio € usado, 0 cédigo gravado no diretério onde o arquivo de especificagio reside. Se nenhuma classe directiva esti presente na especificagio, a classe gerada vai ter 0 nome " yy ex "e seri gravado em um arquivo" vYylex. java ", Deve haver apenas uma ciasse% directiva em uma especificagio. ame java", Se 0-6 regra. O sipot directiva substitui as configuragdes do copo' switch. © yylexthrowt { “exceptionl” [", exception2”, ... ] yylexthrowt) ‘ou (em uma tinica linha) apenas & wylexthrow "exception!" [", exception2", ...] As excegdes listadas no interior yylexthrow’ ( ... } yylexthrow’ seri declarado na cliusula throws do método de varredura, Se houver mais de um yylexthrow’s ( ... 18 yylexthrow eléusula a especificagdo, todas as excegdes especificadas serio declarados. O fim do arquivo Hi sempre um valor padrdo que o método de varredura retomnaré quando o fim do arquivo foi atingido, Vos pode, contudo, defini um valor especifico para retomar e uma parte especifica do cédigo que deve ser executado quando 0 fim do arquivo é aleangado. final padrao de valores do arquivo depende do tipo de retomo do método de varredura: © Pata inteirot , método de digializagao ird retomnar o valor ¥¥EOF , que é um pub! static int membro da chsse gerada. © Para intwrapt , nenhum tipo especificado, ou um * tipo definido pelo usuario, declarados usando aigites , 0 valor é nute © CUP em modo de compatibilidade, usando xicara’ , 0 var & nova java_cup.runtime.Symbol (sym.ZOF) Valores de usuario e cédigo a ser executado no final do arquivo pode ser definida usando essas diretrizes: © Eofvals { eofvals) 0 cédigo incluido no eofval’ { eotval’ sero copiados na integra para 0 método de Aigitalizagdo e seré executado cada vez que quando o fim do arquivo ¢ alcangado (isto € possivel quando ‘0 método de varredura é chamado novamente apés o fim do arquivo foi atingido). O cddigo deve retomar 0 valor que indica o final do arquivo para o analisador. Deve haver apenas uma eofval® ( 1% eofval eldusula na especificagdo, O cofval’ {... Bofvals} directiva substi as configuragdes do interruptor ¢ byace13 switch, A partir da versio 1,2 JFlex fornece uma maneita mais legivel para especificar 0 valor final do arquivo usando 0 <> reera (ver também secgao 4.3.2 ). © note { }% eof 0 cédigo inchikdo no {3 eof ... Eos) seri executado exatamente uma ver, quando o fim do arquivo Ealcangado. O cédigo esti inchuido dentro de um método yy_do_eof void () endo deve retomar nenhum valor (use 8 eofval {.. or>> para este fim). Se mais de um final de directiva cédigo do arquivo estiver presente, 0 cédigo sera concatenado em ordem de aparigéo na especificagao. © Bofthrows ( “exceptioni" [", exception2", ... ] eofthrowt) ‘ou (em uma ‘nica linha) apenas % Eofthrow “exception!” [", exception2", ...] As excegdes lstadas no interior § soZthrow (...% eofthrow) serd declarado na ebusula throws do mélodo yy_do_eof () (veja 208 para mais informagGes sobre esse método). Se houver mais de um + cofthrow {...¥ eofthrow) eldusukt na especificagdo, todas as excegdes especificadas sero declarados. © Eofcloset ‘Causas JFlex para fechar 0 fuxo de entrada no final do arquivo. © cédigo yyclose () € anexado ao método yy_do_eof () (untamente com o cédigo especificado nos eof {...% eof} ) ea excerdo java. io. TORxcestion € declarada na ckiusula throws do método (em conjunto comos de eof throm’ © & Zofclose falsa Transtorma o eftito de entrada € nfo queria depois x: ff novamente (por exemplo, em caso de fechamento fluxo de 0 Scanners auténomo © Debugt Cria uma finigdo principal na classe gerada, que espera que o nome de um arquivo de entrada na linha de comando e ent executa o scanner sobre esse arquivo de entrada de informagdes de impressdo sobre cada token retornado para 0 console Java até o final do arquivo é alcangado. As informagGes incluem: © ‘iimero da linha (se a contagem de linha estiver ativada), cohma (se a contagem de cohina & ativado), © texto correspondente, ea agdo executada (como nimero da linha na © standalonet Cria uma finngdo principal na classe gerada, que espera que © nome de um arquivo de entrada ma linha de comando e entiio executa o scanner neste arquivo de entrada. Os valores retornados pelo scanner so ignorados, mas qualquer texto inigualével ¢ impresso para 0 console Java vez (como 0 C/C++ ferramenta Flex faz, se executado como programa aulénomo). Para evitar ter que usar uma classe extra token, o método de digitalizagdo serd dectarado como tendo padro tipo int , no ¥¥coken (se no houver qualquer outro tipo explicitamente especificada). Isso ¢ itrelevante na maioria dos casos, mas pode ser ttl para saber quando fazer outro standalone scanner para algum propésito. Vocé também deve considerar 0 uso do debus' directiva, se vocé quer apenas ser capaz de executar o scanner sem um analisador ligado para testes ete Compa idade CUP ‘Vocé também pode querer ler a segdo 8,1 JFlex CUP e se voc® estiver interessado em saber como a interface do scanner gerado com CUP. © cupt A cacas directiva permite que 0 modo de compatibiidade CUP e & equivalente ao seguinte conjunto de directivas: & implementa Next token |_cup. runtime. Scanner untime . Symbol mibol nove ( © vabr da padres para sym e pode ser alterado coma cvpsynt direetiva, Em JLex modo de compatibilidade ( 31. chave na linha de comando), ee fe: nao sera ligado. © 4 Cupsym "classname" Personaliza o nome da classe gerada CUP / interface com os nomes dos tokens terminal. Padrdo & sym A directiva nfo deve ser utllzado apés xi cara’ , mas antes. © cupdebugt ‘Cra uma tungao principal na classe gerada, que espera que © nome de um arquivo de entrada na tmha de comando e endo executa 0 scanner neste arquivo de entrada. Imprime linha, cokma, texto cotrespondente, ¢ CUP nome de simbolo para cada token retomado ao padrao fora. Byacc / J compatibilidade ‘Vocé também pode querer le a segao 8,2 JFlex e byace /J, se vocé estiver interessado em como a interface do scanner gerado com byace / J. * Byacct 0 byaces diteetiva permite que © modo de compatibilidade byace / Je & equivalente ao seguinte conjumto de directivas: Geragao de cédigo As seguintes opgdes definir que tipo de JFlex lexical analisador de eédigo ira produ.» pacote €a contiguragdo padrio e ser usado, quando nio ha método de geragdo de cédigo é especiticado, © Interruptort Com sate os JPlex ird gerar um scanner que tema dificil DFA codificado em wma instrugo switch aninhadas. Este método dé uma boa dose de compressdo em termos do tamanho da compilado classe de arquivo enguanto contin er um desempenho muito bom. Se o seu seanner comega a sggande embora (dizem que mais de cerca de 200 estados) o desempenho pode muito degenerada e vo deve considerar 0 uso da tab: irectivas. Se o seu scammer fica ainda maior (cerea de 300 estados), o compilador Java javac poderia produzir cédigo corrompidos, que ir falhar quando executados ou Ihe dard uma java. 1ang.versfy2rro= quando marcada pela meiquina virtual. Isto & devido A limitagdo de tamanho de 64 KB de métodos de Java, conforme descrito na Especificagao de Maquina Virtual Java [ 10 ]. Neste caso, voc® seré forgado a usar 0 pacotes directiva, uma vez interruptor’ normalmente fornece mais compressdo da tabelt DFA que a tabeta’ directiva, a forne ae OU pacotes © Tabelat A cabelas diregdo causas JFlex para produzir um scanner de mesa clissica que codifica impulsionado sua tabela de DFA em uma matriz. Neste modo, JFlex s6 fiz uma pequena quantidade de compactagao de tabelas (ver [6 ], [12 ], [1] €[ 13 ] para mais detalhes sobre o assunto da compressdo de mesa) & usa o mesmo método que JLex fez até versio 1.2.1. Consuite a seco 6 desempenho deste manual para comparar estes métodos. Mesma razio acima (64 KB limitagdo de tamanho de métodos) fiz.com que o mesmo problema, quando o scanner & muito grande. Isto é, porque a miquina virtual trata iniialisers estitica de matrizes como métodos normais. Vocé vai, neste caso, vokar a ser forgado a usar 0 pacotes directiva para evitar 0 problema. © Pacotet Pacotes JFkex causas para comprimir a tabela DFA gerada e armazend+lo em um ou mais literas string, IFlex cuida para que as cordas néio stio mais do que 0 permitido pelo formato de arquivo de classe. As cordas tem que ser descompactado quando o objeto primeiro scanner & criado e inicializado. Apés descompactar 0 acesso interno 4 mesa DFA é exatamente 0 mesmo que coma opgio de Lavelat - 0 ‘inico trabalho extra para ser feito em tempo de execupdo & processo de descompactagdo que & bastante rapido (ndo perceptivel em casos normais). Ena complexidade de tempo proporcional ao tamanho da tabela DFA expandida, ¢ ¢ estiti , feito apenas uma vez para uma classe scanner certa -nifo importa quantas vezes ele é instanciado, Mais uma ver, ver secedio 6 de desempenho sobre 0 desempenho destes scanners Com pacote’ , deve haver praticamente nenfuma limitago para 0 tamanho do scammer. pacote’ & a configuragao padrio ¢ sera usado quando nenhum método de geragio de cédigo & especificado. Conjuntos de caracteres ou mie Faz.com que o scanner gerado para usar um conjunto de caracteres de 7 bits de entrada (cédigos de caracteres 0-127), Se um caractere de entrada com um cédigo maior que 127 é encontrado em uma entrada em tempo de execusdo, 0 scammer ind langar uma ArraytadexoutofBoun tion Nao s6 por causa disso, vocé deve considerar 0 uso do unicode’ directiva, Ver também seccdo 5 para obter informagSes sobre codificagdo de caracteres. Este & 0 padrio no JLex modo de compatiblidade. © 4 votal 8 abit Ambas as opges com que o scanner gerado para usar um conjunto de caracteres de 8 bits de entrada (cédigos de caracteres 0-255). Se um caractere de entrada com um cédigo maior que 255 & encontrado ‘em uma entrada em tempo de execugio, o scanner ird langar uma hevayIndexoutofsoundssxcept ion . Note que mesmo que a sua plataforma usa apenas um byte por caractere, 0 valor Unicode de um personagem ainda pode ser maior que 255. Se estiver a digitalizar arquivos de texto, vocé deve considerar 0 uso do unicodes directiva. Ver também secgao 5 para mais informagdes sobre codificagao de caracteres. © 4 unicode & leit Ambas as opcdes com que o scanner getado para usar o total de 16 bits conjunto de caracteres Unicode de entrada que Java suporta nativamente (pontos de cédigo de caracteres 0-65535). Nao haverd estouro de temno de execneso 20 ufilizar este coniunio de carncteres de entrada ons cnaes. niko sionfiea ane 0 scanner ira ler dois bytes de cada vez. O que ¢ lido eo que constitui um personagem depende da plataforma de execugdo, Ver também secgaio 5 para mais informagdes sobre codificagdo de caracteres, Este ¢ 0 padrdo a menos que 0 modo de compatibildade JLex ¢ usado (opgdo de linha de comando - jlex). © + caseless ignorecaset Esta opeo fiz com JFlex para lidar com todos os caracteres e strings na especificagdo, como se fossem_ especificados no formulirio maidsculas ¢ minisculas. Isto permite uma maneira ficil de especificar um scanner para uma linguagem com palavras-chave case insensitive. A seqiléncia d especificagdio é, por exemplo, tratado como a expresso ((bB] IRR [eF] [AA] {KK]) .O caseless’ opgio nito altera o texto correspondente € nfo efeito classes de personagens. Eno, [21] ainda s6 comesponde ao personagem un ¢ no a , também. Que as letras maiisculas © que as letras minisculas, é definido pelo padrdo Unicode ¢ determinado por JFlex com os métodos Java case . Em JLex modo de compatibilidade ( j 12x- orecases também afetam classes de personagens. Character. tollppe: cchave na linha de comando), Caractere de linha, e contando coluna * chart ‘Vira personagem contando, © int. variével de membro year contémo niimero de caracteres (comegando com 0) desde o inicio da entrada para o inicio do token atual. © Liha: ‘Transforma linha contando, O int variével de membro yy2ine contém o nimero de linhas (comegando com 0) desde o inicio da entrada para o inicio do token atual © colunat Transforma contagem colina, © int variivel de membro yycolune contémo nimero de caracteres (comegando com 0), desde o inicio da linha atual para o inicio do token atual Obsoletos opgées JLex #4 wotunix Esta opedo € obsoleta no JLex JFlex mas ainda reconhecida como valida directiva. E usado para akernar entre Windows e Unix tipo de terminadores de linha (\ : \ ne \ n) para o $ operador em expressOes regulares. JFlex sempre recouhece ambos os estilos de dependente de plataforma terminaddaras da isha * vyeoes Esta opgo ¢ obsoleta no JLex JFlex mas ainda reconhecida como vilida directiva. Em JLex declara um membro do piblico constante v¥FoF . JFlex declara-lo em qualquer caso. Declaragées Estado Declaragdes estaduais tém o seguinte: ", identificador de est para, inclusive, ado", | para 45 (tate) tado" ous x [estado] estados exclusive den dor de estado" (", identificador de Pode haver mais de uma linha de declaragdes estaduais, cada uma comegando com estado’ ouxstates (0 primeiro caractere ¢ suficiente, = ¢ s obras, também). Identificadores de estado sdo letras seguidas por uma seqtiéncia de letras, digitos ou underscores. Identificadores de estado podem ser separados por espago em branco ou virgula. A seqiiéncia de 2 estadol STATES, XYZ ABC STATES , STATE_10 declara 0 conjunto de identifcadores estadot, STATE3, XYZ, STATE 10, ABC, STATES como estados lexical, estado1 , ASC, STATES como inchisiva, € STAT=3 , x¥2 , STATE_10 tdo exclusivo. Consuite também a segdo 4.3.3 sobre a forma como os Estados lexical influenciam 0 modo como a entrada ¢ correspondida. Definigées de macro A definigdo de macto tem a forma macroidentifier expressdo = regular Isso significa que, uma definigo de macro é um identificador de macro (letra seguida por uma seqiéncia de letras, digitos ou underscores), que pode ser usado posteriormente para fazer referéncia a macro, seguido por espago embranco opcional, seguido por um " = ", seguido por espago em branco opcional, seguido por uma expressdo regular (ver seegdo 4,3 regras lexicais para mais informagGes sobre expressdes regulares). A expresso regular no lado direito deve ser bem formado e nfo deve conter a ~, / ou . operadores Diferentemente de JLex, macros nio so apenas pedagos de texto que so expandidas, copiando - ks so analisados e devem ser bem formados, teal CAE CUTIE ARRUNNS IHU UUICESS UE EMEUIUGH ELLOS 18S ESPECIALLY KERICAL (AS ‘como no ter parénteses mais macros complicadas - que nio é necessério com JFlex). Consulte a Portando de JLex para mis detalhes sobre os problemas de macros estilo JLex. Uma vez que & permitido ter usos macro em definigSes de macro, ¢ possivel usar uma gramitica como notagao para especificar a estrutura desejada lexical, Macros no entanto permanecem apenas abreviaturas das expresses regulares que representam. Eles ndo so terminais néo de uma gramitica e no pode ser usado recursivamente de forma alguma, JFlex detecta ciclos nas definigées de macro e relatérios-los no momento da geragdo. JFlex também avisa sobre macros que foram definidos, mas nunca utilzado nas regras " lexical'segio da especificagao. Regras lexicais As regras lexicais “"'segdo de uma especificagao JFlex contém um conjunto de expresses regulates ¢ agdes associada regular (cédigo Java) que s4o executados quando o scanner corresponde & expres Sintaxe A sintaxe do "Exico regras" seedo € descrita pela gramitica BNF seguinte (simbolos terminais sao fechados em. "aspas’) IRvles:: = Regra = [StateList] * Regexp Regixp RegExp "U RegExp ')" Hetpt=") Regexp Regkxp (121) '4" | 124) Regexp "(" Number [ "UT ['8"] (Personagem | Charac PedefinedClass "(Ut Tdentificador ')* te" StringCharacter + ger PredefinedClass:: = '[: jletter:]* "Er gletterddi ‘A gramiética usa os simbolos terminal seguintes: uma seqiiéncia de B1ockstatements , conforme descrito na Especificagio da Linguagem Java [ 7 ], segdo 14.2. © Nimero ‘um inteiro decimal nio negativo, © Identiticade: ‘uma carta (2-24-21 seguido por uma seqiiéncia de zero ou mais letras, digitos ou underscores [a-2A- 20-9) uma seqiiéncia de escape ou qualquer outro caractere unicode que nfo & um desses personagens meta: OOD e\. tee cape ou qualquer outro caractere unicode que niio & um desses personagens meta: \ # Uma seqiiéneia de escape o\N\r\E\ eve tum \ x seguido por dois digitos hexadecimais (4 escape padrdo ASCID, 0-91 (denotando uma se guido de quatro digitos hexadecimais {a-Fa-£0-9) (denotando uma seqiiéncia de ape Unicode), © uma barra invertida seguida de um nimero octal de trés digtos 000-377 (que denota uma seqiiéncia de escape padrio ASCII), ou © uma barra invertida seguida por qualquer outro caractere unicode que representa esse personagem. Por favor, note que 0 \n seqiiéncia de escape representa o caractete ASCII LF - nio para o fim da linha, Se vocé gostaria de combinar o terminador de linha, vocé deve usar a expresso \ r | \ | \ © \ ase voce quer as convengdes Java, ou\ x | \n | \ re \ a | \ 12028 | \ 42028 | \ uoo0B | \ uo0: \ 9085 se voce quiser ser totalmente compativel com Unicode (ver também [ 5 J). ‘A partir da versdo 1.1 do JFlex os caracteres de espago em branco "* (espago) € "\ " (guia) pode ser usado para melhorar a legiblidade das expressdes regulares. Eles setdio ignorados por JFlex. Nas classes de caracteres e strings no entanto, espago em branco caracteres manter em pé por simesmos (de modo a string *" ainda corresponde exatamente um caractere de espago € {\ »1 ainda corresponde um LF ASCII ou um caractere de espago). JFlex aplica as seguintes precedéncias dos operadores padrio de expresso regular (maior para 0 menor): © unirio postfix operadores (**", +", 124, (ai, (a, a) # unirio operadores de prefiso (11", 1") * concatenagio (Regixp:: = Regixp Regexp) © unio (Regexp:: = Regzxp ‘| ' Regex) Portanto, a expressioa | abe |! cd +, porexemplo, é analisado como (a | (abe)) | (1 (e) td *)) Semantica Esta secedo dé uma descrigdo informal de que o texto é acompanhado por uma expressdo regular (ou seja, uma expressio descrita pelo Rect» produgdo da gramitica apresentado acim ). Uma expressdio regular que consiste unicamente em © umcarater coresponde a esta personagem. © uma classe de caracteres "{' (Personagem | Ch qualquer caractere dessa classe, Um Personagen é considerado um elemento de uma classe, se ela esta listada na classe, ou se seu eédigo estd dentro de um intervalo de caracter ‘character . Eno, (20-3 \ n] , por exemplo, coincida com os caracteres ex'="Chazacter) * ') * corresponde a listados char: uno 123\n Se a lista de personagens estd vazia (ou seja, apenas ¢) ), a expresso corresponde a nada (0 conjunto vavio), nem mesmo a cadeia vazia. Isto pode ser itil em combinago com o operador de negagdo * sonagen | Cha! © uma classe de caracteres negada "(* *( Character) **] corresponde a todos os caracteres no incluidos na classe. Se a Ista de personagens esti vazia (ou seja, I+) ), @ expressdo corresponde a qualquer caractere do conjunto de caracteres de entrada, © um string cter + '® * comesponde ao texto exato entre aspas duplas. Todos os personagens meta, mas \ e " perder o seu significado especial dentro de uma string. Veja também o ionorecase switch. st © umuso macro *{' tdentis do macro como "nome cador *}' coincide coma entrada que é acompanhada pelo lado diteito ador" © um classe de caracteres predefinidos corresponde a qualquer dos personagens dessa classe. Existem as seguintes classes de personagens pré-definidos: contém todos os personagens, mas \ Todas as outras classes de personagens pré-definidos so definidos na especificagio Unicode ou a especificago da linguagem Java ¢ Java determinados pelas fngSes da clas: sJavaldentifiers ] isJavatdent. ter 0) it 0) isUppercase () islowercase () Ekes sio especialmente titeis quando se trabalha como conjunto de caracteres unicode. Se un e b sto expressdes regulates, enlio (Unio) a expresso regular, que corresponde a todos de entrada que é acompanhada por um ou por» ab (Concatenagio) &a expresso regular, que corresponde & entrada acompanhado por un seguido pela entrada ‘acompanhado por i (Kleene fechamento) ‘Combina com zeto ou mais repetigdes da entrada acompanhado por un (lteragio) & equivalente a + (Opsao) corresponde & entrada vazia ou a entrada acompanhado por wm (Negagao) combina com tudo, mas as cordas acompanhado por una . Use com cautela: a construgdo de un! envolve uma NFA, adicionais, possivelmente exponencial para DFA transformacdo na NFA para vx Note-se que coma negagdo ¢ unio também tem (através da aplicago de DeMorgan) intersecgao © conjunto diferenga: a interseegio de un eb & |! (a,b!) , a expresstio que combina com tudo de una niio correspondida por €(! a |) (Ate) combina com tudo até (¢ inchindo) a primeira ocorréncia de um texto acompanhado por um . A expressio ~ a € equivalemte aun !((>)* um [*]*) . Um comentirio no estilo C tradicional & acompanhada por" / *" ~"+/* (Repete) é equivalente a» vezes a concatenagao de un . Assim, a (4} por exemplo, é equivalente & expresso aaa . O inteiro decimal n deve ser positivo. aly m & equivalente a pelo menos n vezes € no méximo m vezes a concatenago de un. Assim,» (2,4) , por exemple, ¢ equivalente & expresso aaa? ana? . Ambos n em nilo sao inteiros decimais negativas e niio deve ser menor que a w corresponde 4 entrada mesmo que un . Em uma regra lexical, uma expresstio regular » pode ser precedido por um’ * (0 inicio de operador de linha). » € enttio combinada somente no inicio de uma linha na entrada, A linha comega depois de cada ocorréncia de \ ri \a | \ 2 \ a | \ 32028 | \ u2029 | \ 000s | \ u000C | \ uodes (ver também| $ ]) e no inicio da entrada. A linha anterior terminator na entrada no é consumido e pode ser acompanhado por outra regra Em uma regra lexical, uma expresso regular » pode ser seguido por uma expressdo de olhar pata frente. Um obar a frente expressdo ou é um' 5 ‘(final de operador de linha) ou um * /* seguido por uma expresso arbitréria regular. Em ambos os casos, a olhar de frente ndo é consumido ¢ ndo incluidos na regido de texto correspondente, mas é considerado ao determinar qual a regra tem a mais longa partida (ver também 4.3.3 Como a entrada é correspondido ), No''s case’ = 6 é igualada no final de uma linha na entrada. O fim de uma linha & denotada pela expresso regular\ | \in | \ tr \n | \ 2028 | \ w2029 | \ s000B | \ wooo | \ u008s . Eno, ae us séequivalnteaun /\r | \n | \r\n | \ uz028 | \ uzo29 | \ woop | \ aoo0c | \ 4.0085 Isto é um pouco diferente para a situagio descrita em [. 5 ]:uma vez que em JFlex s é um verdadeiro contexto de filga, o fim do arquivo se no contar como o fim da linha. Para arbitréria look-ahead (também chamado de fuga de contexto ) a expressdo ¢ acompanhada somente quando seguido da entrada que coincide com o contexto a diteta A partir da versio 1.2, permite JFlex lex / flex estilo «oF» regras nas especificagdes lexical. Uma regra StateList] <> {algum cédigo action} muito semelhante ao 2ofvais directiva (segdo 4.2.3 ), A diferenga reside no opcionais statel.ist que podem preceder 0 «#0» regra. O eédigo de agdo s6 ser executada quando o fim do arquivo & lido eo ‘scanner esta atualmente em um dos estados listados no Kxico stateList . O mesmo stateGroup (ver secgao 4.3.3 Como a entrada é correspondido ) ¢ regras de precedéncia, como no caso regra "> normal'aplicar (ou seja, se houver mais de um «207» regra para um determinado estado lexical, a agdo de a que aparece no inicio da especificagao serd executado). "zoF» regras substituem as configuragdes do copos € byaces* opgdes € no deve ser misturado como $ eotvat directiva Uma acao consiste de um pedaco de cédigo Java entre chaves ou é 0 especial | ago. A | ago é uma abreviatura para a ago da seguinte expressio. Exemplo: expression3 {alguna ace} € equivalente a forma expandida expressiol (alguma agao expressdo2 {alguma acao expression3 {alguma acao} Ekes sto siteis quando vocé trabatha com trailing expresses contexto. A expresso a | (2 / d) | bio é sintaticamente legal, mas pode faciimente ser expresso usando a | agdo: al e/al b {alguma agao Como a entrada é correspondido ‘Ao consumir a sua entrada, 0 scanner determina a expressdo regular que corresponde a maior parte da entrada (regra de jogo hi mais tempo). Se houver mais de uma expresso regular que correspond a maior parcela de entrada (ou seja, todos os coincidi com a mesma entrada), o scanner gerado escolhe a expresso que aparece em primeiro lugar na especificago. Apds a determinago da expressio ativa regular, a ago associada & executada, Se nifo existe uma expresso regular comespondente, o scanner termina o programa com uma mensagem de erto (se 0 aut énono’ ditectiva tem sido utilizado, o scanner imprime a entrada inigualivel de sem.out veze recomeca a digtalizagdo). Estados lexical pode ser usada para restringir ainda mais 0 conjunto de expressdes regulares que correspondam, a entrada atual «Umma expresso regular s6 pode ser combindo quando o seu conjunto associado de estados lexical inchit © estado ativo lexical do scanner ou se 0 conjunto de estados associndos lexical esté vazia e0 estado ativo lexical é inclusiva, Estados exchisiva e inciusiva s6 diferem nesse ponto: regras com um conjunto vazio de estados associados. #0 estado ativo lexical do scanner pode ser alterada dentro de uma ago de uma expresso regular usando o metodo yybegin () . 0 scanner inicia no estado inclusive lexical vvzwrozar, , que & sempre declarada por padrao. © 0 conjunto de estados lexical associada a uma expresso regular é 0 statezist que antecede a expressdo. Se uma regra esté contida em um ou mais stateGroups , ento os estados destas também, esto associados com a regra, ou seja, eles se acumlam ao longo StazeGroups

{ 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 das expresses 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 poderiam ter 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. Ao construir 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 desempenho Esta 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 regras 0 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 0 A 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-9 as / * 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 = -17 tch (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

Вам также может понравиться