Sunteți pe pagina 1din 12

Tutorial Jlex Y Java Cup

TutorialJlexyJavaCup
http://openfecks.wordpress.com/ porJosuOrtega

http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


JLexyJavaCUP JLEX Jlexnoesmsqueungeneradordeunanalizadorlxicoparecido aLEX,elcualtomaunacadenacomoentradaunacadenade caracteres,yloconvierteenunasecuenciadetokens. CUP CupesungeneradordeanalizadoressintcticosLALRenJavael cualrecibedeentradaunarchivoconlaestructurade lagramticaysusalidaesunparserescritoenJavalistopara usarse. Deciddividireltutorialenvariasseccionesparahacermsfcil elaprendizajedeestasherramientas. INDEX EstructuradeunArchivoJlex EstructuradeunarchivoCup IntegracinJlexconCup CompilacionyEjecucion

EstructuraArchivoJLex EstructuradelArchivoJlex UnarchivodeentradaJlex,esunarchivoplanoconlasiguiente estructura: codigodelusuario %% DirectivasJlex %% ReglasparalasExpresionesRegulares CdigodelUsuario Eslapartedelarchivodeentradadondesecolocaelcodigojava quedeseamosusarenlaclasequesergenerada,estoquieredecir queJlexcopiardirectamenteelcodigoalaclasegenerada,aqui debenirlosimportesaotraslibrerias.TODOESTOANTESDELOS PRIMEROS(%%).

http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


DirectivasJLex Enestasecconirnlasdirectivas,oespecificacionesparaque opereJLEX,paraobtenerlasalidadeseada. ReglasparalasExpresionesRegulares EnestasecciondelarchivoJlex,esdondesedefinenlasreglas paraobtenerlostokensdelacadenaqueseestaleyendo. Conunejemploexplicaremejorcadaunadeestassecciones. Paraelejemploescribunprogramaquereconocelassiguientes palabrasreservadas: int,string,if,then,else,for,while Reconoceidentificadores,yenteros. ElcodigoparahacerJlexparageneraelanalizadorlexicodel ejemploeselsiguiente: /*AQUIPUEDENIRLOSIMPORTS*/ %% %{ /*CODIGOUSUARIO*/ /*Pequeafuncionparaimprimirenpantalla*/ publicvoidimprime(Stringfoo){ System.out.println(foo) } %} /*DIRECTIVASJLEX*/ %classYylex %public %full %char %line %cup %eofval{ System.out.println("FINDELARCHIVO"); %eofval} entero=[09] Id=[azAZ][azAZ09]* %% /*MANEJODELASPALABRASRESERVADAS*/ "while"{imprime("while"); }
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


"int"{imprime("int");} "if"{imprime("if");} "then"{imprime("then");} "for"{imprime("for");} /*expresionregularparaunentero,tomandoelconjuntodefiniddo anteriormentecomoentero*/ /*unentero1omasveces*/ ({entero})+{imprime("entero"+} {Id}{imprime("Identificador");} /*conlasiguientelinesaignoramoslosespaciosenblanco*/ (""){System.out.println("espacio");} /*conestaignoramoslossaltosdelinea,tabulaciones,*/ [\t\r\n\f]{} /*errorlexico:*/ .{System.out.println("error");} }/*errorlexico:*/.{System.out.println("error");} Elcdigoescritodentrodeloscorcheteseselelcdigoque queremosqueseejecutecadavezqueelscannerencuentralos tokensasuizquierda.Estecdigoquedasinmodificaralahorade generarelarchivodesalidajava EstructuradeArchivoCup Acontinuacindetallarcomoseestructuraunarchivodeentrada paraCup. BsicamenteunarchivoparaCuptienelasiguienteestructura: <importsjava> <codigodelusuarioparaelparser> <codigodelusuarioparalasaccionesdelagramatica> <DeclaraciondeVariablesparalagramatica> <Gramatica> Imports:Enestaseccincreoquenotengoqueampliarmucho desdequeprogramamosJavasabemoscomosonlosimportsde librerias. CdigodelUsuarioparaelParser:ComoelcdigoJavaesgenerado porlaherramientaesmuydifcilmodificarloenelarchivode salida.Asqueaqupodemosdeclararmtodosyvariablesque pensamosusarenlaclaseresultante.Sisedeclaranvariableso mtodospblicosenestaseccinestospodranseraccedidospor otrasclases. Sedeclara: parsercode{:/*Codigodelparser*/:} CdigodelUsuarioparalasAccionesdelaGramtica:Como nuestropropsitoeseldegenerarunCompiladorconestas
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


herramientasouninterprete,necesitamosgenerarunasalidayasea estaerroressemnticos,sintcticosotraduccinauncdigo equivalente,paraestotenemosquehacerusodetraducciones dirigidasporsintaxis. Seramuyengorrosoprogramarlargasfuncionesen cadaaccindelgramticaasqueestaslaspodemosdeclararen estaseccinysolomandarlasallamarencadaaccingramatical. Sedeclaradelasiguientemanera: actioncode{:/*Codigoparalasacciones*/:} DeclaracindeVariablesparalaGramtica:Enestaseccintoca declararlasvariablesqueseutilizaranenlagramtica,estas variablespuedenserdedostipos: VariablesTerminales<terminal> VariablesNoTerminales<nonterminal> Lasvariablesterminalesserntodoslossmbolosterminalesdela gramticaylasvariablesNoTerminalesserntodas lasvariablesquerepresentaranproducciones. Lasintaxisparaladeclaracineslasiguiente: <tipodevariable><tipodedato><iddelavariable> Donde<tipodevariable>puedeserTerminaloNoterminal <tipodedato>puedesercualquiertipodedatoprimitivodeJavao unocreadopornosotrosmismos.Sisenoseespecificaeltipode datoCuplotrabajarcomountipodedatoSymbol. <iddelavariable>aquseespecificaeliddelavariable,se puedeusarunalistadeidentificadoresseparadasporcomasi deseamosvariablesdelmismotipo. Gramtica:Enestaseccindelarchivoesdondeescribiremos nuestragramatica.Lagramaticatienelasiguientesintaxis: <nonterminal>::=<terminalesoNoterminales>; ComounnoterminalpuedetenermasdeunladoderechoenCupse utilizaelsimbolo| <nonterminal>::=<terminalesoNoterminales> |<terminalesoNoterminales>; Comoesesperadosepuedenescribirmuchasproducciones. EjemplodeunarchivocupparaunaExpresionBooleana: /*Porelmomentodejaremoselactioncodeyparsercodevaciosesto se
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


explicaramasadetalleenotrasecciondeltutorial*/ actioncode{::} parsercode{::} /*Declaraciondevariablesnoterminales*/ nonterminalCOND, OREXP,ANDEXP,IGEXP,CMP,SIMBOLOSCOMPARAR,TIPO_DATO; /*DECLARACIONDEVARIABLESTERMINALES*/ terminalor_,and_,igual_igual,no_igual,mayor,menor, mayor_igual,menor_igual, open_par,close_par,id,numero,true,false; StartwithCOND;//startwithsirveparaindicarlealparsercon queproduccionempezar COND::=OREXP; OREXP::=OREXPor_ANDEXP |ANDEXP; ANDEXP::=ANDEXPand_IGEXP |IGEXP; IGEXP::=IGEXPigual_igualCMP |IGEXPno_igualCMP |CMP; SIMBOLOS_COMPARAR::=mayor |menor |mayor_igual |menor_igual; CMP::=CMPSIMBOLOS_COMPARARTIPO_DATO |TIPO_DATO |open_parCONDclose_par; TIPO_DATO::=id |numero |true |false; IntegracinJlexconCup YaquesabemoscomohacerarchivosdeentradaparaJlexyCupahora eshoradehacerquefuncionenenconjunto.Parahacerdemas ilustrativoelejemplousaremosunaclaseexternaalscanneryal parserquenosservirparaalmacenarinformacindecadatoken queseestaleyendo.Llamaremosaestaclasetoken classtoken(){ intposicionX; intposicionY; Stringvalor;
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


publictoken(Stringval,intx,inty){ this.valor=val; this.posicionX=x; this.posicionY=y; } publicintgetX(){returnthis.posicionX;} publicintgetY(){returnthis.posicionY;} publicStringgetValor(){returnthis.valor;} } Seguiremosconelejemplodelaexpresincondicional,paraesto debemosescribirelarchivojlexparaquereconozcalaspalabras reservadasterminalesdellenguaje.Elarchivoquedaradela siguienteforma: importjava_cup.runtime.Symbol; %% %{ publicvoidimprime(Stringstr){ System.out.println(str+""+yychar+""+yyline); } %} %classlexc %public %char %line %ignorecase %cup %full %typejava_cup.runtime.Symbol %implementsjava_cup.runtime.Scanner %eofval{ System.out.println("FINDELARCHIVO"); returnnull; %eofval} letra=[azAZ] entero=[09] id=[azAZ][AZaz09]* %% "("{imprime("AbreParentesis"); returnnewSymbol(csym.open_par,new token(yytext(),yychar,yyline)); } ")"{imprime("CierraParentesis"); returnnewSymbol(csym.close_par,new token(yytext(),yychar,yyline));
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


"true"{ imprime("true"); returnnewSymbol(csym.true_,new token(yytext(),yychar,yyline)); } "false"{ imprime("false"); returnnewSymbol(csym.false_,new token(yytext(),yychar,yyline)); } "<="{imprime("menorigual"); returnnewSymbol(csym.menor_igual,new token(yytext(),yychar,yyline)); } ">="{imprime("mayorigual"); returnnewSymbol(csym.mayor_igual,new token(yytext(),yychar,yyline)); } "||"{imprime("or"); returnnewSymbol(csym.or_,new token(yytext(),yychar,yyline)); } "&&"{imprime("and"); returnnewSymbol(csym.and_,new token(yytext(),yychar,yyline)); } "=="{imprime("igual_igual"); returnnewSymbol(csym.igual_igual,new token(yytext(),yychar,yyline)); } "!="{imprime("noigual"); returnnewSymbol(csym.no_igual,new token(yytext(),yychar,yyline)); } ({id})+("_")*({id})*{imprime("id"); returnnewSymbol(csym.id,new token(yytext(),yychar,yyline)); } {entero}+{imprime("entero"); returnnewSymbol(csym.entero,new token(yytext(),yychar,yyline)); } [\t\r\f]{} [\n]{yychar=0;} ""{}
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


.{imprime("error:"+yytext()); } Explicarelfragmentodecdigoqueseutilizalladoderecho: ")"{imprime("CierraParentesis"); returnnewSymbol(csym.close_par,new token(yytext(),yychar,yyline));} Sellamalafuncinimprimequesedefinialiniciodelarchivo. Ahorabien,elscanneresconstruidodetalmaneraquedentrode elexisteunafuncionconunasentenciadecontroldondesedecide quetipodetokenseestaleyendoyquevalorretornar.Allreside elhechodeescribirelreturn.Comopodemosverseretornauntipo dedatoSymbol,esteensuconstructorrecibedosparmetros: Elprimeroqueesunenteroqueesdeclaradoenlaclasesym generadaporcup(Explicarmasadelante) ElsegundoquerecibeesdetipoObject,estonosfacilitapoder enviarcualquiertipodedatoquedeseemos.,enestecasofueun tipotoken,elquehemosdefinidoaliniciodeestaseccin .Unavezterminadonuestroarchivojlexeshoradeescribirel archivocup: actioncode{: publicvoidImprimeValor(Stringstr){ System.out.println("elvalordeltoken"+str); } :} parsercode{: publicvoidsyntax_error(Symbolst){ tokent=(token)st.value; report_error("ErrorSintactico:"+t.getValue()+""+t.getX() +""+t.getY(),null); :} /*Declaraciondevariablesnoterminales*/ nonterminaltokenCOND, OREXP,ANDEXP,IGEXP,CMP,SIMBOLOSCOMPARAR,TIPO_DATO; /*DECLARACIONDEVARIABLESTERMINALES*/ terminaltokenor_,and_,igual_igual,no_igual,mayor,menor, mayor_igual,menor_igual, open_par,close_par,id,numero,true,false; StartwithCOND;//startwithsirveparaindicarlealparsercon queproduccionempezar COND::=OREXP; OREXP::=OREXPor_ANDEXP
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


|ANDEXP; ANDEXP::=ANDEXPand_IGEXP |IGEXP; IGEXP::=IGEXPigual_igualCMP |IGEXPno_igualCMP |CMP; SIMBOLOS_COMPARAR::=mayor:m{:RESULT=m:} |menor:m{:RESULT=m:} |mayor_igual:m{:RESULT=m:} |menor_igual:m{:RESULT=m:}; CMP::=CMP:cSIMBOLOS_COMPARAR:scTIPO_DATO:t{: Stringval1=c.getValor(); Stringval2=t.getValor(); if(sc.getValor().equals(">")){ ImprimeValor(val1+"mayor"+val2); } if(sc.getValor().equals("<")){ ImprimeValor(val1+"menor"+val2); } if(sc.getValor().equals("<=")){ ImprimeValor(val1+"menorigual"+val2); } if(sc.getValor().equals(">=")){ ImprimeValor(val1+">="+val2); } :} |TIPO_DATO:T{:RESULT=T;:} |open_parCOND:cclose_par{:RESULT=c;:}; TIPO_DATO::=id:i{:RESULT=i;:} |numero:n{:RESULT=n;:} |true:t{:RESULT=t;:} |false:f{:RESULT=t;:}; Llegolahoradeexplicarcadapartedeelarchivocup: Enlaseccinactioncodecomoexpliquanteriormentesedefinen lasfuncionesquequeutilizarancuandoseesterecorriendo lagramtica,enestecasodefinlafuncinImprimeValorque recibedeparmetrounacadena,lonicoquehaceesimprimirel valordelacadenaquerecibedeparmetro. Enlaseccinparsercodeseencuentranlosmtodospropiosdel parser,aquihiceunoverridedelafuncinsyntax_error.
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


Estafuncinnospermiteejecutarunaaccincuandoelparser encuentraunerrorsintctico. Enladeclaracindeterminalesynoterminalessedefinencomo tipotokenparapodermanejarusarlosdeunaformamascmodaen lasaccionesdelagramtica. Ahoravamosconlasaccionesenlagramatica,Cuppermiteagregar accionescomolasquepodemosverenelejemploanteriorestas puedenirencualquierlugardelladoderechodelaproduccinen estetipodeherramientassesugiereponerlasalfinalparaevitar ambigedadesyaqueCuptomalaproduccincomounsmbololasen lagramticayalestarenelmediopuedenhabererrores dereduccinodemovimientodelparser.Lasintaxisparaparalas accioneses:{:/*acciones*/:}dondeaccionespuedesercualquier sentenciadecdigo. LavariableRESULTesusadaporCUPparadevolverelvaloral padredelaproduccin,bsicamentedevuelveelvalorasignadoal noterminaldelladoderecho.Estevalordebeserelmismotipode datoqueelnoterminalobviamente. Enelejemploseimprimirnlosoperadoresrelacionalesenformade textojuntoconlosvaloresdecadamiembrodelaexpresin.

CompilacinyEjecucin Eslahoradelpasofinalcompilaryejecutarnuestroscannery parser. CompilacionJlex: ParacompilarelJlexsolobastaconescribirenconsola: $jlex<archivojlex> YsitodosegenerabiencrearanuestrasalidaencdigoJava. CompilacionCup: ParacompilarCupsepresentanmasopcionescomoespecificarla clasequellevalasconstantesdelossimbolos,elpaquetedela clase,elnombrequedeseamosparalasalidadelparserentre otras.Paranuestroejemplomodificaremoselnombredelaclasecon lossimbolosyelnombrequerecibiraelparser: $cupparser<nombredelaclasedelparser>symbols <nombreclaseconsimbolos><archivodenetradacup> Paraverlasdemasopciones: $mancup Cdigodeejecucin:
http://openfecks.wordpress.com/

Tutorial Jlex Y Java Cup


Supongamosquenuestrasalidadejlextieneelnombre:scanner.java ynuestrasalidadeCupParser.java.Parapoderhacerqueel scanneryelparserfuncionenconjuntamentelassiguienteslineas decdigosontiles: Enelcasoqueleamosunarchivodeentrada: Filefile=newFile("urldelarchivo"); try{ FileReaderfr=newFileReader(file); scannerlex=newscanner(fr); ParsermiParser=newParser(lex); miParser.parse(); }catch(Exceptione){ System.out.println(e); } } LaclasedelscannerrecibeenelconstructorunStreamde caracteresenestecasoloqueseleydelarchivo. scannerlex=newscanner(fr); Yparaintegrarloalparsersolodebemosenviarloalconstructor delnuevoobjetoparsercreado ParsermiParser=newParser(lex); Paraquenuestroobjetoempieceaejecutarelparserllamamosasu metodoparse(); miParser.parse(); Sinuestraentradanoesunarchivosinountextoledodeun TextAreaoalgoparecidopodemosusarlaclaseStringReaderdeJava enlugardelFileReader.

http://openfecks.wordpress.com/

S-ar putea să vă placă și