Tecnológico Nacional de México
Instituto Tecnológico de Pachuca Ingeniería en Sistemas Computacionales Materia: Lenguaje Y Autómatas I Alumno: Miguel Castillo López No. e control: 14200855 !nidad ": Investigación sobe el genea!o !e analiza!o sint"ctico YACC # $avaCC
GENERADOR DE ANALIZADOR SINTÁCTICO YACC YACC
Yacc es un programa para generar analizadores sintácticos. Las siglas del nombre significan Yet Another Compiler-Compiler, es decir, "Otro generador de compiladores más". Genera un analizador sintáctico la parte de un compilador !ue comprueba !ue la estructura del cdigo fuente se a#usta a la especificacin sintáctica del lengua#e$ basado en una gramática anal%tica escrita en una notacin similar a la &'(. Yacc genera el cdigo para el analizador sintáctico en el Lengua#e de programacin C. (ue desarrollado por )tephen C. *ohnson en A++ para el sistema operatio ni/. 0espu1s se escribieron programas compatibles, por e#emplo &er2ele3 Yacc, G' isn, 45) 3acc 3 Abra/as 3acc una ersin actualizada de la ersin original de A++ !ue tambi1n es soft6are libre como parte del pro3ecto de Open)olaris de )un$. Cada una ofrece me#oras lees 3 caracter%sticas adicionales sobre el Yacc original, pero el concepto ha seguido siendo igual. Yacc tambi1n se ha reescrito para otros lengua#es, inclu3endo 7atfor, 8(L, 4L, Ada, *aa, 3 Limbo. 9uesto !ue el analizador sintáctico generado por Yacc re!uiere un analizador l1/ico, se utiliza a menudo con#untamente con un generador de analizador l1/ico, en la ma3or%a de los casos le/ o (le/, alternatia del soft6are libre. 8l estándar de :888 9O):; 9<==>.? define la funcionalidad 3 los re!uisitos a Le/ 3 Yacc. La ersin Yacc de A++ se conirti en soft6are libre@
VERSIONES • • •
ersin Yacc de A++ 4L-Yacc, una ersin de 3acc para el lengua#e )tandard 4L. Yecc, una ersin de 3acc para 8rlang.
MODO DE USO Construccin de un traductor usando YaccB
9artes de las !ue consta un programa fuente en YaccB
{declaraciones} %% {reglas} %% {rutinas de apoyo en C} -0eclaraciones <$ 0eclaraciones ordinarias en C, delimitadas por D 3 E. ?$ 0eclaraciones de los componentes l1/icos de la gramática esto se e/plica más adelante$. 9odr%a estar ac%a -7eglas de traduccin Cada una de ellas consta de una produccin de la gramática 3 la accin semántica asociada. 8s decir,
→ | | ... | pasar%a a ser en YaccB : {acción se!ntica 1} | {acción se!ntica 2} ... | {acción se!ntica n} "
n carácter simple entre comillas Fc se considera como el s%mbolo terminal c. Las cadenas sin comillas de letras 3 d%gitos no declaradas como componentes l1/icos se consideran no terminales. 8l primer lado iz!uierdo se considera como s%mbolo inicial por defecto, o bien se declara B start s%mbolo na accin semántica es una secuencia de proposiciones en C, dnde HH se refiere al alor del atributo asociado con el no terminal del lado iz!uierdo, mientras !ue Hi se refiere al alor asociado con el i-1simo s%mbolo gramatical del lado derecho. )e e#ecuta siempre !ue se reduzca por la produccin asociada. 9or defecto es DHHIH<@E. na accin semántica no tiene por !u1 enir al final de su regla. Yacc permite !ue una accin sea escrita en mitad de una regla. 8sta regla deuele un alor, accesible de forma normal por las acciones !ue están a
su derecha, !ue pueden acceder a los alores deueltos por los s%mbolos a su iz!uierda 8#emploB #:$ {&1"} C {'&2" y&("} 8l efecto es poner / a < e 3 al alor deuelto por C.
Las acciones !ue no terminan una regla son mane#adas por Yacc como si fueran un nueo nombre de no-terminal, con una nuea regla para 1l con el )tring ac%o en su parte derecha, 3, como accin de esa regla, ella misma. 8s decir, el e#emplo anterior lo mane#a como si se hubiera escrito as%B #C) : *+ epty +* {&1"}" # : $ #C) C {'&2" y&("}" 'O+AB 9uede haber conflictos cuando ocurre una accin interior en una regla antes de !ue el parser pueda estar seguro de !u1 regla está siendo reducida. 8n muchas aplicaciones, la salida no iene dada directamente con las acciones@ en su lugar, una estructura de datos, tal como un árbol de análisis, se constru3e en memoria 3 se aplican transformaciones en 1l antes de !ue la salida sea generada. Los árboles de análisis son particularmente fáciles de construir, si se tienen rutinas para realizar 3 mantener la estructura de árbol deseada. Ejemplo.- +enemos una funcin C !ue se llama nodo, de forma !ue nodo,-n1n2/ crea un nodo con eti!ueta L 3 descendientes n< 3 n?, 3 deuele el %ndice del nueo nodo. 8l árbol de análisis podr%a ser realizado suministrando acciones en la especificacin como e'pr : e'pr 00 e'pr {&nodo,001(/"} 9ueden definirse tambi1n otras ariables para ser usadas por las acciones. +anto las declaraciones como las definiciones deben aparecer en la seccin de declaraciones, entre D 3 E. +ienen ámbito global. 0eben eitarse los nombres de ariables !ue empiecen por 33, pues los nombres de ariables internas de Yacc comienzan de esta forma todos.
EJEMPLOS 4ini calculadora A continuacin, amos a analizar un e#emplo sencillo de una erdadera especificacin de 3acc, !ue es la gramática para una calculadora sencilla !ue permite hacer operaciones como suma, resta, multiplicacin, diisin 3 e/ponente. %{ include <at3.3> %} %union{ dou4le d5al" } %to6en %to6en %to6en %to6en
789$; -8= 978= )9= ?@? AB; -)D#;7)E== ;FE)D#;7)E== 7?
%leGt -8= 978= %leGt )9= ?@? %leGt 7F %rig3t AB; %type 'pression %start nput %% nput: -ine | nput -ine " -ine: 7? | 'pression 7? " 'pression: 789$;
{ printG,H;esult: %GInH1/" } { &1" }
| 'pression -8= 'pression { &1(" } | 'pression 978= 'pression { &1J(" }
| 'pression )9= 'pression { &1+(" } | 'pression ?@? 'pression { &1*(" } | 978= 'pression %prec 7F { &J2" } | 'pression AB; 'pression { &poK,1(/" } | -)D#;7)E== 'pression ;FE)D#;7)E== { &2" } " %% int yyerror,c3ar +s/ { printG,H%sInHs/" } int ain,5oid/ { yyparse,/" }
Defii!ioe" 8n esta primera seccin, al igual !ue en le/, incluimos las librer%as !ue usaremos en el programa, definiciones de los to2ens, tipos de datos 3 precedencia de la gramática. %union 8sta definicin, se traduce a una union de C !ue a su ez dará el tipo de dato a una ariable global de nombre 33lal !ue será de donde 3acc tomara los datos a procesar, en la union se definen miembros cu3os correspondientes tipos de datos serán usados para dar el tipo de dato a los to2ens como se e/plicara en la siguiente seccin. union se traduce de la siguiente forma B 8n 3acc B %union{ dou4le d5al" } 8n C B typedeG union { dou4le d5al" } LL=)L" Con esta definicin, 3acc declara algunas uniones de este tipo, de las cuales la mas importante es B LL=)L yyl5al"
!ue será usada en la especificacin de le/, del mismo programa para asignarle alor a los to2ens !ue 3acc usara para realizar operaciones. 8sta estructura puede llegar a ser mu3 comple#a, 3 para saber de !ue tipo es cada to2en deuelto por 33le/$, se usan las definiciones to2en 3 t3pe. %to6en y %type to2en sire para definir los to2ens !ue ha3, 3 si es necesario, el tipo de dato !ue usan, todos los to2ens son tomados como s%mbolos terminales, lo cual eremos me#or refle#ado en la seccin de reglas, estos tambi1n tienen el ob#etio de serir como eti!uetas !ue 33le/$ regresa a 3acc para identificar el to2en !ue se ha le%do recientemente. )u uso es como sigue B %to6en M<ie4roDdeDunion>N )O8)#1 M)O8)#2 ... )O8)#nN 0onde todo lo !ue esta entre J 3 K es opcional. miembroMdeMunionN B :ndica el miembro al !ue serán mapeados los to2ens en la union 33lal dentro de le/. 8+:8+A) B 8stos son los nombres con los !ue se identificaran los to2ens mismos, !ue serán traducidos en C como nPmeros en instrucciones Qdefine del preprocesador de C. t3pe es análogo a to2en, solo !ue este define el tipo de dato para s%mbolos no terminales de nuestra gramática, la Pnica diferencia es !ue el tipo de dato a usar es obligatorio. 8n nuestro e#emplo B %to6en %to6en %to6en %to6en
789$; -8= 978= )9= ?@? AB; -)D#;7)E== ;FE)D#;7)E== 7?
. . . t3pe dalN 8/presin La primera l%nea indica !ue el to2en '487O será del tipo de miembro de dal, es decir, un doubl1. Las siguientes tres l%neas, son para definir algunos to2ens mas !ue serán usados en la gramática, pero no necesitan un tipo de dato ni un miembro en 33lal asociado. 8n la ultima l%nea definimos el tipo de dato !ue usara nuestro no terminal 8/presin.
%leGt y %rig3t 8l siguiente paso, es definir el tipo de precedencia de nuestros to2ens operadores, en este punto tenemos dos factores, la precedencia por si misma, 3 la agrupacin de los operadores. 9recedencia La precedencia es asignada en orden inerso al !ue aparecen, es decir, el ultimo operador declarado, tiene ma3or precedencia !ue el anterior 3 as% sucesiamente. Asociatiidad left 3 right indican si el operador se agrupa a la derecha o a la iz!uierda, por e#emplo, en el caso de 9OR87 8/ponente$ debe asociarse a la derecha, por !ue buscamos !ue se resuela de ese modo, de derecha a iz!uierda, por e#emplo B &uscamos !ue ST>TUT?TV sea ealuado as% B ST>TUT?TV$$$ 9or lo contrario, las sumas 3 restas !ueremos resolerlas de iz!uierda a derechaB &uscamos !ue S->WUW?-V sea ealuado as% B S->$WU$W?$-V sar este tipo de declaraciones es importante para disminuir la posibilidad de ambigXedades en el lengua#e generado. %start 8n algunos casos es coneniente indicarle a 3acc cual es el s%mbolo no terminal$ inicial a la hora de hacer el parseo, es decir, el s%mbolo !ue se trata de reducir, si esta opcin no es especificada, 3acc toma al primer s%mbolo de la seccin de reglas como s%mbolo inicial. 8n nuestro e#emplo, se presentan ambos casos, nuestro s%mbolo inicial ":nput" se encuentra al inicio del archio 3 tambi1n esta declarado como s%mbolo inicial. %start nput 7eglas
8n esta parte finalmente llegamos a la definicin de la gramática, acá podemos obserar !ue cada s%mbolo se define con su nombre, seguido de dos puntos "B" seguidos de arios s%mbolos !ue conformaran su composicin gramatical !ue en caso de tener arias opciones, son separados por "" or$ indicando !ue se tienen arias opciones para reducir ese s%mbolo 3 para terminar cada regla, un "@". 8#emplo B )i tomamos la gramática !ue definimos al principio de esta seccin B <'presion> 7uero <'presion> 7uero J <'presion> 7uero Y la transformamos a una regla de 3acc, se er%a como estoB 8/presionB 789;A 00 'presion { & 1 ("} | 789;A 0J0 'presion { & 1 J ("} | 789;A { & 1"} " en el e#emplo 3a transformado a una regla gramatical de 3acc, podemos er !ue 3a se especifica !ue hacer con los s%mbolos de la gramática una ez !ue son resueltos en la parte de cdigo de C. 8n este e#emplo, 8/presion es el s%mbolo no terminal !ue se esta definiendo de manera recursia, el alor !ue tomara una ez resuelto es el alor asignado a la ariable HH, !ue traducida a C es una ariable mapeada al s%mbolo no terminal, H<, H? 3 H> son ariables !ue son mapeadas al alor de los s%mbolos de cada l%nea de cada regla, estas son numeradas de iz!uierda a derecha. 8#emplo B 8n este segmento de regla B 8/presionB '487O ZWZ 8/presion 8/presion e!uiale a HH '487O e!uiale a H< ZWZ e!uiale a H? 3 8/presion la parte recursia$ e!uiale a H> todo esto claro, en la parte de acciones en C para cada l%nea de la regla en 3acc. 8n el e#emplo tambi1n podemos encontrar el uso de prec !ue sire para cambiar la precedencia de un operador dependiendo del conte/to en el e#emplo, le estamos dando una más alta precedencia a la operacin "menos" cuando esta en un conte/to unario, !ue a la ma3or%a de los operadores e/cepto el 9OR87 e/ponente$ B .
. . | 978= 'pression %prec 7F { &J2" } . . . 7educcin Yacc reduce sus reglas generando un parse tree no literalmente$, 3 a resoliendo cada regla completa tan pronto como puede, lo cual nos trae un detalle de dise[o de gramaticas en 3acc, 3 es la diferencia entre especificar la recursiidad por la derecha o por la iz!uierda, para e/presiones mu3 sencillas !ue generen un parse tree pe!ue[o no ha3 ningPn problema pero para casos donde la reduccin es comple#a, puede desbordar la pila 3a !ue cuando la recursin es derecha, para resolerla, tiene !ue guardar los datos de la iz!uierda, 3 si estos son demasiados, no puede mane#arlos. 9or lo contrario, cuando la recursin es iz!uierda, no tiene !ue guardar datos !ue no a a utilizar por !ue recorre el árbol de iz!uierda a derecha 3 resuele las reglas tan pronto como puede. 8n el e#emplo anterior tenemos la recursin por la derecha, un análogo recurrente por la iz!uierda seri como este B 8/presionB 'presion 00 789;A { & 1 ("} | 'presion 0J0 789;A { & 1 J ("} | 789;A { & 1"} " 8specificacin de Le/ para el e#emplo 9ara !ue el 8#emplo pueda funcionar, al igual !ue cual!uier otro programa en 3acc, necesita un to2enizer, 3 a continuacin tenemos su to2enizer correspondiente escrito en le/. %{ include Hy.ta4.3H include include %} K3ite digit integer
M ItN MPJQN {digit}
%% {K3ite} { *+ gnoraos espacios en 4lanco +* } He'itH|HquitH|H4yeH {printG,H)erinando prograaInH/"e'it,P/"}
{integer}
{ yyl5al.d5al&atoG,yyte't/" return,789$;/" }
HH return,-8=/" HJH return,978=/" H+H return,)9=/" H*H return,?@?/" HRH return,AB;/" H,H return,-)D#;7)E==/" H/H return,;FE)D#;7)E==/" HInH return,7?/" %% Acerca de la seccin de definiciones de este le/er, lo Pnico releante !ue podemos mencionar es la l%nea de C !ue dice B include Hy.ta4.3H esta l%nea inclu3e al archio 3.tab.h !ue contiene algunas de las definiciones de 3acc !ue le/ necesita para poder interactuar con el, entre las mas importantes se encuentran definidas todas las eti!uetas de los to2ens, como 9L), 4:'), '4&87, etc1tera. 8stas constantes son los alores !ue 33le/$ regresara a 33parse$ la funcin del parser de 3acc$ para identificar el tipo de to2en !ue reci1n se ha le%do. 8n la seccin de reglas, en la parte del cdigo, podemos er como al final de cada regla, se hace un return especificando la eti!ueta !ue fue declarada como to2en o como left\rigth en la especificacin 3acc. 9ara compilar 3 correr este e#emplo en sistemas ':; o similares B le' eSe1.1.l yacc Jd eSe1.1.y cc Jo eSe1.1 le'.yy.c y.ta4.c Jly Jll Jl eSe1.1 2T+TJT ;esult: 12P.PPPPPP TR2+2 ;esult: TP.PPPPPP TR,2+2/ ;esult: U2T.PPPPPP 4ye )erinando prograa =u4rutinas
8n esta ultima seccin, es posible reimplementar, siguiendo la misma idea de le/, algunas funciones !ue pueden ser Ptiles en algPn momento dado o declarar nueas funciones para usar dentro de nuestro cdigo o nuestras reglas, no ha3 mucho !ue reimplementat a este niel 3acc$ a menos !ue sea con propsitos realmente espec%ficos. Las funciones mas comPnmente implementadas son main$ e 33error$, la primera se usa para personalizar el programa con mensa#es antes o despu1s del parser, o para llamarlo arias eces en el cdigo 3 la segunda la ocupa 33parse$ cada ez ue encuentra un error de sinta/is, en este e#emplo, se inclu3en ambas con su contenido m%nimo.
GENERADOR DE ANALIZADOR SINTÁCTICO JAVACC *aaCC *aa Compiler Compiler$ es un generador de analizadores sintácticos de cdigo abierto para el lengua#e de programacin *aa. *aaCC es similar a Yacc en !ue genera un parser para una gramática presentada en notacin &'(, con la diferencia de !ue la salida es en cdigo *aa. A diferencia de Yacc, *aaCC genera analizadores descendentes top-do6n$, lo !ue lo limita a la clase de gramáticas LL5$ en particular, la recursin desde iz!uierda no se puede usar$. 8l constructor de árboles !ue lo acompa[a, **+ree, constru3e árboles de aba#o hacia arriba bottom-up$. *aaCC está licenciado ba#o una licencia &)0. 8n
VERSIONES todas las modificaciones !ue han tenido lugar desde LA L:&87AC:^' 08 LA 87):^' =.U 08 OC+&78 08 =.`preS =.`preU =.`pre]
=.`pre` =.` =.`.< =._pre< =._pre? <.= <.? ?.= ?.< >.= >.< >.? S.= S.< S.? ].=
MODO DE USO 8)+7C+7A G8'87AL 08 ' 97OG7A4A 8' *AACC Cual!uier cdigo escrito para *aaCC obedece a la siguiente estructuraB
8l fichero de entrada comienza con una lista de opciones, la cual es opcional. )eguidamente nos encontramos la unidad de compilacin #aa la cual se encuentra encerrada entre 9A7)87M&8G:'nombre$ 3 9A7)87M8'0nombre$. 0espu1s nos encontramos con una lista de reglas de produccin cada una de estas partes son claramente distinguibles en el e#emplo$. 8l nombre !ue sigue a 9A7)87M&8G:' 3 a 9A7)87M8'0 debe ser el mismo, 3 1ste identifica al analizador sintáctico !ue a a ser generado con posterioridad. 9or e#emplo si nuestro nombre es Gramática, se generan los siguientes archiosB Gramatica.#aaB 8l analizador sintáctico. Gramatica+o2en4anager.#aaB gestor de to2ens para el analizador l1/ico. GramaticaConstants.#aaB 8l analizador l1/ico no mane#a los to2ens por el nombre !ue especificamos nosotros en el cdigo, sino !ue a cada uno de ellos le asigna un nPmero. 8n este archio se encuentra cada uno de los to2ens #unto con el nPmero !ue le ha sido asignado por el analizador l1/ico. Además de 1stos, tambi1n se generan otros ficheros +o2en.#aa 3 9arse8/ception.#aa, A)C::MChar)tream.#aa, +o2en4gr8rror.#aa$, pero estos
ficheros son los mismos para cual!uier gramática 3 pueden conserarse de una para otra.
8ntre 9A7)87M&8G:' 3 9A7)87M8'0, se encuentra una unidad de compilacin *aa el contenido completo de un archio escrito en *aa$. sta puede ser cual!uier cdigo *aa siempre !ue contenga una declaracin de clase cu3o nombre sea el mismo !ue el analizador sintáctico !ue a a ser generado. Gramática en el e#emplo anterior$. 8sta parte del archio de gramática tiene esta formaB
*aaCC no realiza un che!ueo minucioso de la unidad de compilacin por lo !ue es posible !ue un fichero de gramática pase el test de *aaCC 3 genere los archios correspondientes 3 luego produzca errores al ser compilados. 8l archio correspondiente al analizador sintáctico !ue es generado por *aaCC contiene la unidad de compilacin *aa en su totalidad, además del cdigo generado por el analizador sintáctico, el cual se inclu3e al final de su clase. 8n el caso del e#emplo la siguiente formaB
8l cdigo del analizador sintáctico inclu3e la declaracin de un m1todo pPblico correspondiente a cada no terminal de la gramática. La realizacin del análisis sintáctico a partir de un no terminal se consigue inocando al m1todo correspondiente a ese no terminal.
EJEMPLOS Construir un analizador l1/ico con *aaCC. 8n la programacin, un analizador l1/ico es la parte de un compilador o analizador parser$ !ue trata de descomponer el lengua#e proporcionado como entrada en to2ens. n to2en es la unidad m%nima con significado. +o2ens habituales son los identificadores, enteros, flotantes, constantes, etc. 9ara el desarrollo, utilizaremos una herramienta incre%blemente Ptil, *aaCC. 4ediante e/presiones regulares podemos definir cmodamente los to2ens de nuestro lengua#e. Caso práctico, construir analizador l1/ico para un determinado lengua#e de programacinB Las especificaciones de nuestro lengua#e sonB
+o2ensB
•
•
•
Co"#$#e"B C$%e$"B Caracteres entrecomillados, e#emploB "cadena" E#e&o"B 'Pmeros positios, e#emploB ?>S o = L'(i!$"B +78 3 (AL)8 I%e#ifi!$%o&e"B +odos los identificadores son una secuencia de letras a-zA-$ 3 nPmeros !ue obligatoriamente deben comenzar con una letra 3 no un nPmero$. Lo" i%e#ifi!$%o&e" )*e "e &efie&$ $ !$%e$" #e&mi$&+ e ,,.
P$l$&$" &e"e&/$%$"0 8n el lengua#e ha3 palabras reseradas !ue darán ida al lengua#e, estas seránB " o#1 if1 e%1 le#1 !$ll1 #2e1 !$"e1 el"e1 ip*#1 p&i#1 "ele!# 3 "#$#i!". Además el lengua#e será " !$"e i"e"i#i/e" o lo !ue es lo mismo, un identificador llamado "id" apuntará al mismo lugar !ue ":d", "i0" o ":0". De i(*$l fo&m$ "e&+ p$&$ l$" p$l$&$" &e"e&/$%$". Cdigo *aaCC e/parser.##$B options { F7A;DC#= & true" } #;=;D$F7,'aplearser/ pu4lic class 'aplearser { **Secución del analizador pu4lic static 5oid ain , =tring args M N / { **nicialización del analizador 'aplearser parser" iG,args.lengt3 && P/{ =yste.out.println ,H'aplearser: -eyendo de la entrada estandar ...H/" parser & neK 'aplearser,=yste.in/" } else iG,args.lengt3 && 1/{ =yste.out.println ,H'aplearser: -eyendo de Gic3ero H argsMPN H ...H /" try { parser & neK 'aplearser,neK Sa5a.io.ilenput=trea,argsMPN//" } catc3,Sa5a.io.ile7otound'ception e/ { =yste.out.println ,H'aplearser: l Gic3ero H argsMPN H no 3a sido encontrado.H/" return" } } else { =yste.out.println ,H'aplearser: ?e4es utilizarlo de una de las siguientes Goras:H/" =yste.out.println ,H Sa5a 'aplearser < Gic3eroH/" =yste.out.println ,HArH/" =yste.out.println ,H Sa5a 'aplearser Gic3eroH/" return " } try {
copilador.=tart,/" =yste.out.println ,H'aplearser: -a entrada 3a sido leida con V'ito.H/"
} catc3,arse'ception e/{ =yste.out.println ,H'aplearser: Ea ocurrido un error durante el an!lisis.H/" =yste.out.println ,e.get9essage,//" } catc3,)o6en9grrror e/{ =yste.out.println ,H'aplearser: Ea ocurrido un error.H/" =yste.out.println ,e.get9essage,//" } } } #;=;D7?,'aplearser/ **=);8C)8;#= L C#;#C);= ? =C# =W : { H H | HItH | HInH | HIrH | } **)AW7= =)Y)CA= )AW7 : { <7)F;DCA7=)#7): ,F)>/> | <-AFCDCA7=)#7): HtrueH | HGalseH | HJ1H> | <=);7FDCA7=)#7): HIHH , XMHIHHHIIHHInHHIrHN | HIIH , MHnHHtHH4HHrHHGHHIIHHI0HHIHHN | , MHInHHIrHN | HIrInH///+ HIHH> | <?F): MHPHJHQHN> } **#-#$;#= ;=;@#?#= )AW7 : { <7A): HnotH> | <: HiGH> | <7?: HendH> | <=8$: Hsu4H> | <-): HletH> | | <)E7: Ht3enH> | | <-=: HelseH> | <78): HinputH> | <;7): HprintH> | <=-C): HselectH> | <=)#)C: HstaticH>
} **)AW7 ?7)C#?A; )AW7 : { <?7);: <-));>,<-));>|F)>/+,MHHN/Z> | <-));: ,MHaHJHzHH#HJH[HN/> } **87?#? ;7C#5oid =tart ,/ : {} { , 7)F;DCA7=)#7) | =);7FDCA7=)#7) | -AFCDCA7=)#7) | 7A) | | 7? | =8$ | -) | C#-- | )E7 | C#= | -= | 78) | ;7) | =-C) | =)#)C | ?7); /+ <A> } 9ara compilar este fichero, se debe hacer con " j$/$!!" 3 posteriormente con " j$/$!"B Sa5acc e'parser.SS Sa5ac +.Sa5a 9ara e#ecutar el programaB Sa5a 'aplearser Gic3ero
CONCLUSI4N 8l analizador sintáctico 3a se a YACC o *aaCC recibe los to2ens o palabras generadas por el analizador l1/ico 3 determina si la secuencia u orden !ue presentan es correcta 3 permitida por el lengua#e. La salida !ue generará será el árbol sintáctico. Gracias a estas e/celentes herramientas, nosotros como programadores no tenemos !ue reinentar la rueda cuando de crear un analizador sintáctico se trate, las numerosas opciones !ue nos brindan los generadores hacen !ue esta tarea sea mas fácil.
RE5ERENCIAS httpB\\es.6i2ipedia.org\6i2i\Yacc httpB\\666.lcc.uma.es\galez\theme\:ntroduccionA*aaCC.pdf httpB\\2i66ito.com\construir-un-analizador-le/ico-con-#aacc