Está en la página 1de 110

Bison

El Generador de Analizadores Sintcticos compatible con YACC. a 12 Febrero 1999, Bison Versin 1.27 o

por Charles Donnelly y Richard Stallman

Copyright c 1988, 89, 90, 91, 92, 93, 95, 98, 1999 Free Software Foundation

Published by the Free Software Foundation 59 Temple Place, Suite 330 Boston, MA 02111-1307 USA Printed copies are available for $15 each. ISBN 1-882114-45-0 Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies. Permission is granted to copy and distribute modied versions of this manual under the conditions for verbatim copying, provided also that the sections entitled GNU General Public License and Conditions for Using Bison are included exactly as in the original, and provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one. Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modied versions, except that the sections entitled GNU General Public License, Conditions for Using Bison and this permission notice may be included in translations approved by the Free Software Foundation instead of in the original English.

Cover art by Etienne Suvasa.

Se concede permiso para hacer y distribuir copias literales de este manual con tal de que se preserven en todas las copias el anuncio de copyright y este anuncio de permiso. Se concede permiso para copiar y distribuir versiones modicadas de este manual bajo las condiciones de la copia literal, tambin con tal de que las secciones tituladas Licencia P blica General e u GNU y Condiciones para el uso de Bison se incluyan exactamente como en el original, y siempre que todo el resultado derivado del trabajo se distribuya bajo los trminos de un aviso de permiso e idntico a este. e Se concede permiso para copiar y distribuir traducciones de este manual a otros lenguajes, bajo las condiciones anteriores para versiones modicadas, excepto que las secciones tituladas Licencia P blica General GNU, Condiciones para el uso de Bison y este aviso de permiso podr ser u an incluidos con traducciones aprobadas por la Free Software Foundation en lugar del original en ingls. e

Dise o de cubierta por Etienne Suvasa. n

Introduccin o

Introduccin o
Bison es un generador de analizadores sintcticos de propsito general que convierte una desa o cripcin gramatical para una gramtica independiente del contexto LALR(1) en un programa en C o a que analice esa gramtica. Una vez que sea un experimentado en Bison, podr utilizarlo para desaa a rollar un amplio rango de analizadores de lenguajes, desde aquellos usados en simples calculadoras de escritorio hasta complejos lenguajes de programacin. o Bison es compatible hacia arriba con Yacc: todas la gramticas escritas apropiadamente para a Yacc deber funcionar con Bison sin ning n cambio. Cualquiera que est familiarizado con Yacc an u e deber ser capaz de utilizar Bison con pocos problemas. Necesita ser uente programando en C a para poder utilizar Bison o para comprender este manual. Comenzaremos con cap tulos introductorios que explican los conceptos bsicos del uso de Bison a y muestran tres ejemplos comentados, cada uno construido sobre el anterior. Si no conoce Bison o Yacc, comience leyendo estos cap tulos. A continuacin se encuentran los cap o tulos de referencia que describen los aspectos espec cos de Bison en detalle. Bison fue escrito originalmente por Robert Corbett; Richard Stallman lo hizo compatible con Yacc. Wilfred Hansen de la Universidad de Carnegie Mellon a adi los literales de cadenas multin o caracter y otras caracter sticas. Esta edicin corresponde a la versin 1.27 de Bison. o o

Nota: las secciones tituladas Licencia P blica General GNU, Condiciones para el uso de Biu son y el aviso de permiso son traducciones libres de las secciones originales en ingls GNU General e Public License, Conditions for Using Bison y el permiso original. Ninguna de estas traducciones ha sido aprobada por la Free Software Foundation ocialmente y se han inclu solamente para do facilitar su entendimiento. Si desea estar seguro de si sus actuaciones estn permitidas, por favor a acuda a la versin original inglesa. o La Free Software Foundation recomienda fervientemente no usar estas traducciones como los trminos ociales de distribucin para sus programas; en su lugar, por favor use las versiones e o inglesas originales, tal y como estn publicadas por la Free Software Foundation. a

Bison 1.27

Conditions for Using Bison

Conditions for Using Bison


As of Bison version 1.24, we have changed the distribution terms for yyparse to permit using Bisons output in non-free programs. Formerly, Bison parsers could be used only in programs that were free software. The other GNU programming tools, such as the GNU C compiler, have never had such a requirement. They could always be used for non-free software. The reason Bison was dierent was not due to a special policy decision; it resulted from applying the usual General Public License to all of the Bison source code. The output of the Bison utilitythe Bison parser lecontains a verbatim copy of a sizable piece of Bison, which is the code for the yyparse function. (The actions from your grammar are inserted into this function at one point, but the rest of the function is not changed.) When we applied the GPL terms to the code for yyparse, the eect was to restrict the use of Bison output to free software. We didnt change the terms because of sympathy for people who want to make software proprietary. Software should be free. But we concluded that limiting Bisons use to free software was doing little to encourage people to make other software free. So we decided to make the practical conditions for using Bison match the practical conditions for using the other GNU tools.

Bison 1.27

Condiciones para el uso de Bison

Condiciones para el uso de Bison


Al igual que en la versin 1.24 de Bison, hemos cambiado los trminos de la distribucin de o e o yyparse para permitir el uso de la salida de Bison en programas no-libres. En otro tiempo, los analizadores generados por Bison solamente pod utilizarse en programas que fuesen software an libre. Las otras herramientas GNU de programacin, tales como el compilador de C GNU, nunca han o tenido tal tipo de requisito. Estas herramientas siempre pod utilizarse para software no-libre. an La razn de que con Bison fuera diferente no fue debido a una decisin pol o o tica especial; ello result o de la aplicacin de la Licencia P blica General usual a todo el cdigo fuente de Bison. o u o La salida de la utilidad Bisonel archivo del analizador de Bisoncontiene una copia literal de un considerable fragmento de Bison, que es el cdigo para la funcin yyparse. (Las acciones o o de tu gramtica se insertan dentro de esta funcin en un punto, pero el resto de la funcin no se a o o modica.) Cuando aplicamos los trminos de la GPL al cdigo fuente para yyparse, el efecto fue e o la restriccin del uso de la salida de Bison en software libre. o No cambiamos los trminos debido a simpat con la gente que quiere hacer software propietario. e a El software deber ser libre. Pero hemos concluido que limitando el uso de Bison en software libre a era hacer poco por alentar a la gente a hacer otro software libre. As que hemos decidido hacer que concuerden las condiciones prcticas para el uso de Bison con las condiciones prcticas para usar a a las otras utilidades GNU.

Bison 1.27

GNU GENERAL PUBLIC LICENSE

GNU GENERAL PUBLIC LICENSE


Version 2, June 1991 Copyright c 1989, 1991 Free Software Foundation, Inc. 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.

Preamble
The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free softwareto make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundations software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) oer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each authors protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modied by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reect on the original authors reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in eect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyones free use or not licensed at all. The precise terms and conditions for copying, distribution and modication follow.

Bison 1.27

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION


0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The Program, below, refers to any such program or work, and a work based on the Program means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modications and/or translated into another language. (Hereinafter, translation is included without limitation in the term modication.) Each licensee is addressed as you. Activities other than copying, distribution and modication are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Programs source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option oer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a. You must cause the modied les to carry prominent notices stating that you changed the les and the date of any change. b. You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c. If the modied program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modied work as a whole. If identiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

GNU GENERAL PUBLIC LICENSE

3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a. Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b. Accompany it with a written oer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c. Accompany it with the information you received as to the oer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an oer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface denition les, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by oering access to copy from a designated place, then oering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.

10

Bison 1.27

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may dier in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program species a version number of this License which applies to it and any later version, you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are dierent, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM AS IS WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),

GNU GENERAL PUBLIC LICENSE

11

EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

12

Bison 1.27

How to Apply These Terms to Your New Programs


If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source le to most eectively convey the exclusion of warranty; and each le should have at least the copyright line and a pointer to where the full notice is found. one line to give the programs name and a brief idea of what it does. Copyright (C) 19yy name of author This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type show w. This is free software, and you are welcome to redistribute it under certain conditions; type show c for details. The hypothetical commands show w and show c should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than show w and show c; they could even be mouse-clicks or menu itemswhatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a copyright disclaimer for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program Gnomovision (which makes passes at compilers) written by James Hacker. signature of Ty Coon, 1 April 1989

GNU GENERAL PUBLIC LICENSE

13

Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License.

14

Bison 1.27

LICENCIA PUBLICA GENERAL GNU

15

LICENCIA PUBLICA GENERAL GNU


Versin 2, Junio de 1991 o Copyright c 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, EEUU Se permite a todo el mundo la copia y distribucin de copias literales o de este documento de licencia, pero no se permite su modicacin. o

Prembulo a
Las licencias que cubren la mayor parte del software estn dise adas para quitarle a usted la a n libertad de compartirlo y modicarlo. Por el contrario, la Licencia P blica General GNU pretende u garantizarle la libertad de compartir y modicar software librepara asegurar que el software es libre para todos sus usuarios. Esta Licencia P blica General se aplica a la mayor parte del software u de la Free Software Foundation y a cualquier otro programa cuyos autores se comprometen a utilizarla. (Alguna parte del software de la Free Software Foundation est cubierto por la Licencia a P blica General GNU para Librer u as). Usted tambin la puede aplicar a sus programas. e Cuando hablamos de software libre, estamos rerindonos a la libertad, no al precio. Nuestras e Licencias P blicas Generales estn dise adas para asegurarnos de que tenga la libertad de distribuir u a n copias de software libre (y cobrar por ese servicio si quiere), que reciba el cdigo fuente o que pueda o conseguirlo si lo quiere, que pueda modicar el software o usar fragmentos de l en nuevos programas e libres, y que sepa que puede hacer todas estas cosas. Para proteger sus derechos necesitamos algunas restricciones que prohiban a cualquiera negarle a usted estos derechos o pedirle que renuncie a ellos. Estas restricciones se traducen en ciertas obligaciones que le afectan si distribuye copias del software, o si lo modica. Por ejemplo, si distribuye copias de uno de estos programas, sea gratuitamente, o a cambio de una contraprestacin, debe dar a los receptores todos los derechos que tiene. Debe asegurarse de o que ellos tambin reciben, o pueden conseguir, el cdigo fuente. Y debe mostrarles estas condiciones e o de forma que conozcan sus derechos. Protegemos sus derechos con la combinacin de dos medidas: (1) ponemos el software bajo o copyright y (2) le ofrecemos esta licencia, que le da permiso legal para copiar, distribuir y/o modicar el software. Tambin, para la proteccin de cada autor y la nuestra propia, queremos asegurarnos de que e o todo el mundo comprende que no se proporciona ninguna garant para este software libre. Si el a software es modicado por cualquiera y ste a su vez lo distribuye, queremos que sus receptores e sepan que lo que tienen no es el original, de forma que cualquier problema introducido por otros no afecte a la reputacin de los autores originales. o Por ultimo, cualquier programa libre est constantemente amenazado por patentes sobre el a software. Queremos evitar el riesgo de que los redistribuidores de un programa libre individualmente obtengan patentes, haciendo el programa propietario a todos los efectos. Para prevenir esto, hemos dejado claro que cualquier patente debe ser concedida para el uso libre de cualquiera, o no ser concedida en absoluto.

16

Bison 1.27

Los trminos exactos y las condiciones para la copia, distribucin y modicacin se exponen a e o o continuacin. o

TERMINOS Y CONDICIONES PARA LA COPIA, DISTRIBUCION Y MODIFICACION


0. Esta Licencia se aplica a cualquier programa u otra obra que contenga un aviso colocado por el propietario del copyright diciendo que puede ser distribuido bajo los trminos de esta Licencia e P blica General. En adelante, Programa se referir a cualquier programa u obra de esta u a clase y una obra basada en el Programa se referir bien al Programa o a cualquier obra a derivada de este seg n la ley de copyright. Esto es, una obra que contenga el programa o una u porcin de este, bien en forma literal o con modicaciones y/o traducido en otro lenguaje. o Por lo tanto, la traduccin est incluida sin limitaciones en el trmino modicacin. Cada o a e o propietario de una licencia ser tratado como usted. a Cualquier otra actividad que no sea la copia, distribucin o modicacin no est cubierta por o o a esta Licencia, est fuera de su ambito. El acto de ejecutar el Programa no est restringido, a a y los resultados del Programa estn cubiertos unicamente si sus contenidos constituyen una a obra basada en el Programa, independientemente de haberlo producido mediante la ejecucin o del programa. Que esto se cumpla, depende de lo que haga el programa. 1. Usted puede copiar y distribuir copias literales del cdigo fuente del Programa, tal y como o lo recibi, por cualquier medio, supuesto que de forma adecuada y bien visible publique en o cada copia un anuncio de copyright adecuado y una renuncia de garant mantenga intactos a, todos los anuncios que se reeran a esta Licencia y a la ausencia de garant y proporcione a a, cualquier otro receptor del programa una copia de esta Licencia junto con el Programa. Puede cobrar un precio por el acto f sico de transferir una copia, y puede a su eleccin ofrecer o garant a cambio de unos honorarios. a 2. Usted puede modicar su copia o copias del Programa o cualquier porcin de l, formando de o e esta manera una obra basada en el Programa, y copiar y distribuir esa modicacin u obra bajo o los trminos del apartado 1 anterior, siempre que adems cumpla las siguientes condiciones: e a a. Debe procurar que los cheros modicados incluyan noticaciones destacadas manifestando que los ha cambiado y la fecha de cualquier cambio. b. Usted debe procurar que cualquier obra que distribuya o publique, que en todo o en parte contenga o sea derivada del Programa o de cualquier parte de l, sea licenciada como un e todo, sin cargo alguno para terceras partes bajo los trminos de esta Licencia. e c. Si el programa modicado lee normalmente ordenes interactivamente cuando al ejecutarse, debe hacer que cuando comience su ejecucin para ese uso interactivo de la forma ms o a habitual, muestre o escriba un mensaje que incluya un anuncio de copyright y un anuncio de que no se ofrece ninguna garant (o por el contrario que s se ofrece garant y que a a) los usuarios pueden redistribuir el programa bajo estas condiciones, e indicando al usuario cmo ver una copia de esta licencia. (Excepcin: si el propio programa es interactivo o o pero normalmente no muestra ese anuncio, no est obligado a que su obra basada en el a Programa muestre ning n anuncio). u Estos requisitos se aplican a la obra modicada como un todo. Si algunas secciones claramente identicables de esa obra no estn derivadas del Programa, y pueden razonablemente ser a consideradas como obras independientes y separados por s mismas, entonces esta Licencia y sus trminos no se aplican a esas partes cuando sean distribuidas como trabajos separados. e Pero cuando distribuya esas mismas secciones como partes de un todo que es una obra basada en el Programa, la distribucin de ese todo debe cumplir los trminos de esta Licencia, cuyos o e permisos para otros licenciatarios se extienden al todo completo, y por lo tanto a todas y cada una de sus partes, con independencia de quin la escribi. e o

LICENCIA PUBLICA GENERAL GNU

17

3.

4.

5.

6.

7.

Por lo tanto, no es intencin de este apartado reclamar derechos u oponerse a sus derechos sobre o obras escritas enteramente por usted; sino que la intencin es ejercer el derecho de controlar o la distribucin de obras derivadas o colectivas basadas en el Programa. o Adems, el simple hecho de reunir otro trabajo no basado en el Programa con el Programa a (o con un trabajo basado en el Programa) en un medio de almacenamiento o en un medio de distribucin no hace que dicho trabajo entre dentro del ambito cubierto por esta Licencia. o Usted puede copiar y distribuir el Programa (o una obra basada en l, seg n se especica en e u la Seccin 2) en forma de cdigo objeto o ejecutable bajo los trminos de las Secciones 1 y 2 o o e anteriores mientras cumpla adems una de las siguientes condiciones: a a. Acompa arlo con el cdigo fuente completo correspondiente en formato legible para un n o ordenador, que debe ser distribuido bajo los trminos de las Secciones 1 y 2 anteriores en e un medio utilizado habitualmente para el intercambio de programas, o b. Acompa arlo con una oferta por escrito, vlida durante al menos tres a os, por un coste no n a n mayor que el de realizar f sicamente la distribucin del fuente, de proporcionar a cualquier o tercera parte una copia completa en formato legible para un ordenador del cdigo fuente o correspondiente, que ser distribuido bajo las condiciones descritas en las Secciones 1 y 2 a anteriores, en un medio utilizado habitualmente para el intercambio de programas, o c. Acompa arlo con la informacin que usted recibi referida al ofrecimiento de distribuir n o o el cdigo fuente correspondiente. (Esta opcin se permite slo para la distribucin no o o o o comercial y slo si usted recibi el programa como cdigo objeto o en formato ejecutable o o o con una oferta de este tipo, de acuerdo con la Seccin b anterior). o Se entiende por cdigo fuente de un trabajo a la forma preferida de la obra para hacer modio caciones sobre este. Para una obra ejecutable, se entiende por cdigo fuente completo todo o el cdigo fuente para todos los mdulos que contiene, ms cualquier chero asociado de deo o a nicin de interfaces, ms los guiones utilizados para controlar la compilacin e instalacin o a o o del ejecutable. Como excepcin especial el cdigo fuente distribuido no necesita incluir nada o o que sea distribuido normalmente (ya sea en formato fuente o binario) con los componentes fundamentales (compilador, kernel y similares) del sistema operativo en el cual funciona el ejecutable, a no ser que el propio componente acompa e al ejecutable. n Si la distribucin del ejecutable o del cdigo objeto se realiza ofreciendo acceso a una copia o o desde un lugar designado, entonces se considera el ofrecimiento del acceso para copiar el cdigo o fuente del mismo lugar como distribucin del cdigo fuente, incluso aunque terceras partes no o o estn obligadas a copiar el fuente junto al cdigo objeto. e o No puede copiar, modicar, sublicenciar o distribuir el Programa excepto como est exprea samente permitido por esta Licencia. Cualquier intento de copiar, modicar sublicenciar o distribuir el Programa de otra forma es invlido, y har que cesen automticamente los derea a a chos que le proporciona esta Licencia. En cualquier caso, las partes que hayan recibido copias o derechos bajo esta Licencia no vern sus Licencias calceladas, mientras esas partes contin en a u cumplindo totalmente la Licencia. e No est obligado a aceptar esta licencia, ya que no la ha rmado. Sin embargo, no hay hada ms a a que le proporcione permiso para modicar o distribuir el Programa o sus trabajos derivados. Estas acciones estn prohibidas por la ley si no acepta esta Licencia. Por lo tanto, si modica o a distribuye el Programa (o cualquier trabajo basado en el Programa), est indicando que acepta a esta Licencia para poder hacerlo, y todos sus trminos y condiciones para copiar, distribuir o e modicar el Programa o trabajos basados en l. e Cada vez que redistribuya el Programa (o cualquier trabajo basado en el Programa), el receptor recibe automticamente una licencia del licenciatario original para copiar, distribuir o modicar a el Programa, de forma sujeta a estos trminos y condiciones. No puede imponer al receptor e ninguna restriccin ms sobre el ejercicio de los derechos aqu garantizados. No es usted o a responsable de hacer cumplir esta licencia por terceras partes. Si como consecuencia de una resolucin judicial o de una alegacin de infraccin de patente o o o o por cualquier otra razn (no limitada a asuntos relacionados con patentes) se le imponen cono

18

Bison 1.27

diciones (ya sea por mandato judicial, por acuerdo o por cualquier otra causa) que contradigan las condiciones de esta Licencia, ello no le exime de cumplir las condiciones de esta Licencia. Si no puede realizar distribuciones de forma que se satisfagan simultneamente sus obligacioa nes bajo esta licencia y cualquier otra obligacin pertinente entonces, como consecuencia, no o puede distribuir el Programa de ninguna forma. Por ejemplo, si una patente no permite la redistribucin libre de derechos de autor del Programa por parte de todos aquellos que reciban o copias directa o indirectamente a travs de usted, entonces la unica forma en que podr sae a tisfacer tanto esa condicin como esta Licencia ser evitar completamente la distribucin del o a o Programa. Si cualquier porcin de este apartado se considera no vlido o imposible de cumplir bajo cualo a quier circunstancia particular ha de cumplirse el resto y la seccin por entero ha de cumplirse o en cualquier otra circunstancia. No es el propsito de este apartado inducirle a infringir ninguna patente ni ning n otro derecho o u de propiedad o impugnar la validez de ninguna de dichas reclamaciones. Este apartado tiene el unico propsito de proteger la integridad del sistema de distribucin de software libre, que se o o realiza mediante prcticas de licencia p blica. Mucha gente ha hecho contribuciones generosas a u a la gran variedad de software distribuido mediante ese sistema con la conanza de que el sistema se aplicar consistentemente. Ser el autor/donante quien decida si quiere distribuir a a software mediante cualquier otro sistema y una licencia no puede imponer esa eleccin. o Este apartado pretende dejar completamente claro lo que se cree que es una consecuencia del resto de esta Licencia. 8. Si la distribucin y/o uso de el Programa est restringido en ciertos pa o a ses, bien por patentes o por interfaces bajo copyright, el poseedor del copyright que coloca este Programa bajo esta Licencia puede a adir una limitacin expl n o cita de distribucin geogrca excluyendo esos pa o a ses, de forma que la distribucin se permita slo en o entre los pa no excluidos de esta manera. o o ses En ese caso, esta Licencia incorporar la limitacin como si estuviese escrita en el cuerpo de a o esta Licencia. 9. La Free Software Foundation puede publicar versiones revisadas y/o nuevas de la Licencia P blica General de tiempo en tiempo. Dichas versiones nuevas sern similares en esp u a ritu a la presente versin, pero pueden ser diferentes en detalles para considerar nuevos problemas o o situaciones. Cada versin recibe un n mero de versin que la distingue de otras. Si el Programa especica o u o un n mero de versin de esta Licencia que se aplica a ella y a cualquier versin posterior, u o o tiene la opcin de seguir los trminos y condiciones, bien de esa versin, bien de cualquier o e o versin posterior publicada por la Free Software Foundation. Si el Programa no especica o un n mero de versin de esta Licencia, puede escoger cualquier versin publicada por la Free u o o Software Foundation. 10. Si usted desea incorporar partes del Programa en otros programas libres cuyas condiciones de distribucin son diferentes, escriba al autor para pedirle permiso. Si el software tiene copyright o de la Free Software Foundation, escriba a la Free Software Foundation: algunas veces hacemos excepciones en estos casos. Nuestra decisin estar guiada por el doble objetivo de preservar o a la libertad de todos los derivados de nuestro software libre y promover el que se comparta y reutilice el software en general.

AUSENCIA DE GARANT IA
11. YA QUE EL PROGRAMA SE LICENCIA LIBRE DE CARGAS, NO SE OFRECE NINGUNA GARANT SOBRE EL PROGRAMA, HASTA LO PERMITIDO POR LAS LEIA YES APLICABLES. EXCEPTO CUANDO SE INDIQUE LO CONTRARIO POR ESCRITO, LOS POSEEDORES DEL COPYRIGHT Y/U OTRAS PARTES PROVEEN EL PRO GRAMA TAL Y COMO ESTA, SIN GARANT DE NINGUNA CLASE, YA SEA EXIA PRESA O IMPLICITA, INCLUYENDO, PERO NO LIMITANDOSE A, LAS GARANT IAS

LICENCIA PUBLICA GENERAL GNU

19

IMPL ICITAS DE COMERCIABILIDAD Y APTITUD PARA UN PROP OSITO PARTICULAR. TODO EL RIESGO EN CUANTO A LA CALIDAD Y FUNCIONAMIENTO DEL PROGRAMA LO ASUME USTED. SI EL PROGRAMA SE COMPROBARA QUE EST A O DEFECTUOSO, USTED ASUME EL COSTO DE TODO SERVICIO, REPARACI ON CORRECCION QUE SEA NECESARIO. 12. EN NINGUN CASO, A NO SER QUE SE REQUIERA POR LAS LEYES APLICABLES O SE ACUERDE POR ESCRITO, PODRA NINGUN POSEEDOR DE COPYRIGHT O CUALQUIER OTRA PARTE QUE HAYA MODIFICADO Y/O REDISTRIBUIDO EL PRO GRAMA, SER RESPONSABLE ANTE USTED POR DA NOS O PERJUICIOS, INCLU YENDO CUALQUIER DANO GENERAL, ESPECIAL, INCIDENTAL O CONSECUENTE DEBIDO AL USO O LA IMPOSIBILIDAD DE PODER USAR EL PROGRAMA (INCLU YENDO PERO NO LIMITANDOSE A LA PERDIDA DE DATOS O LA PRODUCCION DE DATOS INCORRECTOS O PERDIDAS SUFRIDAS POR USTED O POR TERCERAS PARTES O LA IMPOSIBILIDAD DEL PROGRAMA DE OPERAR JUNTO A OTROS PROGRAMAS), INCLUSO SI EL POSEEDOR DEL COPYRIGHT U OTRA PARTE HA SIDO AVISADO DE LA POSIBILIDAD DE TALES DA NOS.

FIN DE TERMINOS Y CONDICIONES

20

Bison 1.27

Cmo aplicar estos trminos a sus nuevos programas. o e


Si usted desarrolla un nuevo Programa, y quiere que sea del mayor uso posible para el p blico u en general, la mejor forma de conseguirlo es convirtindolo en software libre que cualquiera pueda e redistribuir y cambiar bajo estos trminos. e Para hacerlo, a ada los siguientes avisos al programa. Lo ms seguro es a adirlos al principio de n a n cada chero fuente para comunicar lo ms efectivamente posible la ausencia de garant Adems a a. a cada chero deber tener al menos la l a nea de copyright y una indicacin del lugar donde se o encuentra la noticacin completa. o una l nea para indicar el nombre del programa y una rpida idea de a lo que hace. Copyright (C) 19aa nombre del autor Este programa es software libre; usted puede redistribuirlo y/o modificarlo bajo los trminos de la Licencia Pblica General GNU tal y como est e u a publicada por la Free Software Foundation; ya sea la versin 2 de la o Licencia o (a su eleccin) cualquier versin posterior. o o Este programa se distribuye con la esperanza de que sea util, pero SIN NINGUNA GARANTA; ni siquiera la garanta implcita de COMERCIABILIDAD o I APTITUD PARA UN PROPSITO ESPECFICO. Vea la Licencia Pblica General O I u GNU para ms detalles. a Usted debera haber recibido una copia de la Licencia Pblica General junto u con este programa. Si no ha sido as, escriba a la Free Software Foundation, Inc., en 675 Mass Ave, Cambridge, MA 02139, EEUU. A ada tambin informacin sobre cmo contactar con usted mediante correo electrnico y postal. n e o o o Si el programa es interactivo, haga que muestre un peque o anuncio como el siguiente, cuando n comience a funcionar en modo interactivo: Gnomovision versin 69, Copyright (C) 19aa nombre del autor o Gnomovision no ofrece ABSOLUTAMENTE NINGUNA GARANT A; para ms I a detalles escriba show w. Esto es software libre, y se le invita a redistribuirlo bajo ciertas condiciones. Escriba show c para ms detalles. a Los comandos hipotticos show w y show c deber mostrar las partes adecuadas de la Lie an cencia P blica General. Por supuesto, los comandos que use pueden llamarse de cualquier otra u manera. Podr incluso ser pulsaciones del ratn o elementos de un men lo que sea apropiado an o u para su programa). Tambin deber conseguir que el empresario (si trabaja como programador) o su centro e a acadmico, si es el caso, rme una renuncia de copyright para el programa, si es necesario. e A continuacin se ofrece un ejemplo, cambie los nombres: o Yoyodyne, Inc. con la presente renuncia a cualquier inters de e

LICENCIA PUBLICA GENERAL GNU

21

derechos de copyright con respecto al programa Gnomovision (que hace pasadas a compiladores) escrito por Pepe Programador. rma de Pepito Grillo, 20 de diciembre de 1996 Pepito Grillo, Presidente de Asuntillos Varios. Esta Licencia P blica General no permite incorporar su programa a programas propietarios. Si u su programa es una librer de subrutinas, puede considerar ms util el permitir el enlazado de a a aplicaciones propietarias con la librer Si este es el caso, use la Licencia P blica General GNU a. u para Librer en lugar de esta Licencia. as

22

Bison 1.27

Capitulo 1: Los Conceptos de Bison

23

1 Los Conceptos de Bison


Este cap tulo introduce muchos de los conceptos bsicos sin los que no tendrn sentido los a a detalles de Bison. Si no conoce ya cmo utilizar Bison o Yacc, le sugerimos que comience por leer o este cap tulo atentamente.

1.1 Lenguajes y Gramticas independientes del Contexto a


Para que Bison analice un lenguaje, este debe ser descrito por una gramtica independiente del a contexto. Esto quiere decir que debe especicar uno o ms grupos sintcticos y dar reglas para a a contruirlos desde sus partes. Por ejemplo, en el lenguaje C, un tipo de agrupacin son las llamadas o expresiones. Una regla para hacer una expresin ser Una expresin puede estar compuesta de o a, o un signo menos y otra expresin. Otra regla ser Una expresin puede ser un entero. Como o a, o puede ver, las reglas son a menudo recursivas, pero debe haber al menos una regla que lleve fuera la recursin. o El sistema formal ms com n de presentar tales reglas para ser leidas por los humanos es a u la Forma de Backus-Naur o BNF, que fue desarrollada para especicar el lenguaje Algol 60. Cualquier gramtica expresada en BNF es una gramtica independiente del contexto. La entrada a a de Bison es en esencia una BNF legible por la mquina. a No todos los lenguajes independientes del contexto pueden ser manejados por Bison, unicamente aquellos que sean LALR(1). Brevemente, esto quiere decir que debe ser posible decir cmo anao lizar cualquier porcin de una cadena de entrada con un solo token de preanlisis. Hablando o a estrictamente, esto es una descripcin de una gramtica LR(1), y la LALR(1) implica restricciones o a adicionales que son dif ciles de explicar de manera sencilla; pero es raro en la prctica real que se a encuentre una gramtica LR(1) que no sea LALR(1). Ver Seccion 5.7 [Conictos Misteriosos de a Reduccin/Reduccin], pgina 77, para ms informacin a cerca de esto. o o a a o En las reglas gramaticales formales para un lenguaje, cada tipo de unidad sintctica o agrua pacin se identica por un s o mbolo. Aquellos que son construidos agrupando construcciones ms a peque as de acuerdo a reglas gramaticales se denominan s n mbolos no terminales; aquellos que no pueden subdividirse se denominan s mbolos terminales o tipos de tokens. Denominamos token a un fragmento de la entrada que corresponde a un solo s mbolo terminal, y grupo a un fragmento que corresponde a un solo s mbolo no terminal. Podemos utilizar el lenguaje C como ejemplo de qu signican los s e mbolos, terminales y no terminales. Los tokens de C son los identicadores, constantes (numricas y cadenas de caractee res), y las diversas palabras reservadas, operadores aritmticos y marcas de puntuacin. Luego los e o s mbolos terminales de una gramtica para C incluyen identicador, n mero, cadena de caraca u teres, ms un s a mbolo para cada palabra reservada, operador o marca de puntuacin: if, return, o const, static, int, char, signo-ms, llave-abrir, llave-cerrar, coma y muchos ms. (Estos a a tokens se pueden subdividir en caracteres, pero eso es una cuestin lxica, no gramatical.) o e Aqu hay una funcin simple en C subdividida en tokens: o int cuadrado (x) /* palabra reservada int */ /* identicador, parntesis-abrir */ e /* identicador, parntesis-cerrar */ e

24

Bison 1.27

/* /* return x * x; /* /* } /*

int x;

palabra reservada int, identicador, punto y coma */ llave-abrir */ palabra reservada return, identicador, */ asterisco, identicador, punto y coma */ llave-cerrar */

Las agrupaciones sintcticas de C incluyen a las expresiones, las sentencias, las declaraciones, a y las deniciones de funciones. Estas se representan en la gramtica de C por los s a mbolos no terminales expresin, sentencia, declaracin y denicin de funcin. La gramtica completa o o o o a utiliza docenas de construcciones del lenguaje adicionales, cada uno con su propio s mbolo no terminal, de manera que exprese el signicado de esos cuatro. El ejemplo anterios es la denicin o de una funcin; contiene una declaracin, y una sentencia. En la sentencia, cada x es una expresin o o o y tambin lo es x * x. e Cada s mbolo no terminal debe poseer reglas gramaticales mostrando cmo est compuesto de o a construcciones ms simples. Por ejemplo, un tipo de sentencia en C es la sentencia return; esta a ser descrita con una regla gramatical que interpretada informalmente ser as a a : Una sentencia puede estar compuesta de una parabra clave return, una expresin o y un punto y coma. Aqu existir muchas otras reglas para sentencia, una para cada tipo de sentencia en C. an Se debe distinguir un s mbolo no terminal como el s mbolo especial que dene una declaracin o completa en el lenguaje. Este se denomina s mbolo de arranque. En un compilador, este representa un programa completo. En el lenguaje C, el s mbolo no terminal secuencia de deniciones y declaraciones juega este papel. Por ejemplo, 1 + 2 es una expresin vlida en Cuna parte vlida de un programa en Cpero o a a no es vlida como un programa en C completo. En la gramtica independiente del contexto de C, a a esto se reeja en el hecho de que expresin no es el s o mbolo de arranque. El analizador de Bison lee una secuencia de tokens como entrada, y agrupa los tokens utilizando las reglas gramaticales. Si la entrada es vlida, el resultado nal es que la secuencia de tokens a entera se reduce a una sola agrupacin cuyo s o mbolo es el s mbolo de arranque de la gramtica. a Si usamos una gramtica para C, la entrada completa debe ser una secuencia de deniciones y a declaraciones. Si no, el analizador informa de un error de sintaxis.

1.2 De las Reglas Formales a la Entrada de Bison


Una gramtica formal es una construccin matemtica. Para denir el lenguaje para Bison, a o a debe escribir un archivo expresando la gramtica con la sintaxis de Bison: un archivo de gramtica a a de Bison. Ver Capitulo 3 [Archivos de Gramtica de Bison], pgina 45. a a Un s mbolo no terminal en la gramtica formal se representa en la entrada de Bison como un a identicador, similar a un identicador en C. Por convencin, deber estar en min sculas, tales o an u como expr, stmt o declaracion.

Capitulo 1: Los Conceptos de Bison

25

La representacin en Bison para un s o mbolo terminal se llama tambin un tipo de token. Los e tipos de tokens tambin se pueden representar como identicadores al estilo de C. Por convencin, e o estos identicadores deber estar en may sculas para distinguirlos de los no terminales: por an u ejemplo, INTEGER, IDENTIFICADOR, IF o RETURN. Un s mbolo terminal que represente una palabra clave en particular en el lenguaje deber bautizarse con el nombre despus de pasarlo a may sculas. a e u El s mbolo terminal error se reserva para la recuperacin de errores. Ver Seccion 3.2 [Simbolos], o pgina 46. a Un s mbolo terminal puede representarse tambin como un caracter literal, al igual que una e constante de caracter en C. Deber hacer esto siempre que un token sea simplemente un unico a caracter (parntesis, signo-ms, etc.): use el mismo caracter en un literal que el s e a mbolo terminal para ese token. Una tercera forma de representar un s mbolo terminal es con una cadena de caracteres de C conteniendo varios caracteres. Ver Seccion 3.2 [Simbolos], pgina 46, para ms informacin. a a o Las reglas gramaticales tienen tambin una expresin en la sintaxis de Bison. Por ejemplo, aqu e o est la regla en Bison para una sentencia return de C. El punto y coma entre comillas es un token a de caracter literal, representando parte de la sintaxis de C para la sentencia; el punto y coma al descubierto, y los dos puntos, es puntuacin de Bison que se usa en todas las reglas. o stmt: RETURN expr ; ;

Ver Seccion 3.3 [Sintaxis de las Reglas Gramaticales], pgina 48. a

1.3 Valores Semnticos a


Una gramtica formal selecciona tokens unicamente por sus clasicaciones: por ejemplo, si una a regla menciona el s mbolo terminal constante entera, quiere decir que cualquier constante entera es gramaticalmente vlida en esa posicin. El valor preciso de la constante es irrelevante en cmo a o o se analiza la entrada: si x+4 es gramatical entonces x+1 o x+3989 es igualmente gramatical. Pero el valor preciso es muy importante para lo que signica la entrada una vez que es analizada. Un compilador es inservible si no puede distinguir entre 4, 1 y 3989 como constantes en el programa! Por lo tanto, cada token en una gramtica de Bison tiene ambos, un tipo de token y un valor a semntico. Ver Seccion 3.5 [Deniendo la Semntica del Lenguaje], pgina 50, para detalles. a a a El tipo de token es un s mbolo terminal denido en la gramtica, tal como INTEGER, a IDENTIFICADOR o ,. Este dice todo lo que se necesita para saber decidir dnde podr apao a recer vlidamente el token y cmo agruparlo con los otros tokens. Las reglas gramaticales no saben a o nada acerca de los tokens excepto de sus tipos. El valor semntico tiene todo el resto de informacin a cerca del signicado del token, tal como a o el valor de un entero, o el nombre de un identicador. (Un token tal como , que es solo un signo de puntuacin no necesita tener ning n valor semntico.) o u a Por ejemplo, un token de entrada podr clasicarse como un tipo de token INTEGER y tener el a valor semntico 4. Otro token de entrada podr tener el mismo tipo de token INTEGER pero valor a a

26

Bison 1.27

3989. Cuando una regla gramatical dice que se admite un INTEGER, cualquiera de estos tokens se acepta porque cada uno es un INTEGER. Cuando el analizador acepta el token, este no pierde la pista del valor semntico del token. a Cada agrupacin puede tener tambin un valor semntico al igual que su s o e a mbolo no terminal. Por ejemplo, en una calculadora, una expresin t o picamente tiene un valor semntico que es un a n mero. En un compilador para un lenguaje de programacin, una expresin t u o o picamente tiene un valor semntico que es una estructura en arbol describiendo el signicado de la expresin. a o

1.4 Acciones Semnticas a


Para que sea util, un programa debe hacer algo ms que analizar la entrada; este debe producir a tambin alguna salida basada en la entrada. En una gramtica de Bison, una regla gramatical e a puede tener una accin compuesta de sentencias en C. Cada vez que el analizador reconozca una o correspondencia para esa regla, se ejecuta la accin. Ver Seccion 3.5.3 [Acciones], pgina 50. o a La mayor parte del tiempo, el propsito de una accin es computar el valor semntico de la o o a construccin completa a partir de los valores semnticos de sus partes. Por ejemplo, suponga que o a tenemos una regla que dice que una expresin puede ser la suma de dos expresiones. Cuando o el analizador reconozca tal suma, cada una de las subexpresiones posee un valor semntico que a describe cmo fueron elaboradas. La accin para esta regla deber crear un tipo de valor similar o o a para la expresin mayor que se acaba de reconocer. o Por ejemplo, he aqu una regla que dice que una expresin puede ser la suma de dos subexpre o siones: expr: expr + expr ; { $$ = $1 + $3; }

La accin dice cmo producir el valor semntico de la expresin suma a partir de los valores de las o o a o dos subexpresiones.

1.5 La Salida de Bison: el Archivo del Analizador


Cuando ejecuta Bison, usted le da un archivo de gramtica de Bison como entrada. La salida a es un programa fuente en C que analiza el lenguaje descrito por la gramtica. Este archivo se a denomina un analizador de Bison. Tenga en cuenta que la utilidad Bison y el analizador de Bison son dos programas distintos: la utilidad Bison es un programa cuya salida es el analizador de Bison que forma parte de su programa. El trabajo del analizador de Bison es juntar tokens en agrupaciones de acuerdo a las reglas gramaticalespor ejemplo, construir expresiones con identicadores y operadores. A medida que lo hace, este ejecuta las acciones de las reglas gramaticales que utiliza. Los tokens provienen de una funcin llamada el analizador lxico que usted debe proveer de o e alguna manera (por ejemplo escribindola en C). El analizador de Bison llama al analizador lxico e e cada vez que quiera un nuevo token. Este no sabe qu hay dentro de los tokens (aunque sus valores e semnticos podr reejarlo). T a an picamente el analizador lxico construye los tokens analizando los e

Capitulo 1: Los Conceptos de Bison

27

caracteres del texto, pero Bison no depende de ello. Ver Seccion 4.2 [La Funcin del Analizador o Lxico yylex], pgina 61. e a El chero del analizador de Bison es cdigo C que dene una funcin llamada yyparse que o o implementa esa gramtica. Esta funcin no forma un programa completo en C: debe proveer a o algunas funciones adicionales. Una es el analizador lxico. Otra es una funcin de informe de e o errores a la que el analizador llama para informar de un error. Adems, un programa completo en a C debe comenzar con una funcin llamada main; debe facilitarla, y colocar en esta una llamada o a yyparse o el analizador no ser ejecutado nunca. Ver Capitulo 4 [Interfaz del Analizador en a Lenguaje C], pgina 61. a A parte de los nombres de tipo de token y los s mbolos en las acciones que escriba, todos los nombres de variable y funciones usados en el archivo del analizador de Bison comienzan con yy o YY. Esto incluye las funciones de interfaz tales como la funcin del analizador lxico yylex, la o e funcin de informe de errores yyerror y la propia funcin del analizador yyparse. Esto tambin o o e incluye un gran n mero de identicadores utilizados para uso interno. Por lo tanto, deber evitar u a utilizar identicadores de C que comiencen con yy o YY en el archivo de la gramtica de Bison a excepto para aquellos denidos en este manual.

1.6 Etapas en el Uso de Bison


El proceso real de dise o de lenguajes utilizando Bison, desde la especicacin de la gramtica n o a hasta llegar a un compilador o intrprete funcional, se compone de estas etapas: e 1. Especicar formalmente la gramtica en un formato que reconozca Bison (ver Capitulo 3 a [Archivos de Gramtica de Bison], pgina 45). Para cada regla gramatical en el lenguaje, a a describir la accin que se va a tomar cuando una instancia de esa regla sea reconocida. La o accin se descibe por una secuencia de sentencias en C. o 2. Escribir un analizador lxico para procesar la entrada y pasar tokens al analizador sintctico. e a El analizador lxico podr escribirse a mano en C (ver Seccion 4.2 [La Funcin del Analizador e a o Lxico yylex], pgina 61). Este puede tambin generarse utilizando Lex, pero el uso de Lex e a e no se trata en este manual. 3. Escibir una funcin de control que llame al analizador producido por Bison. o 4. Escribir las rutinas de infome de errores. Para hacer que este cdigo fuente escrito se convierta en un programa ejecutable, debe seguir o estos pasos: 1. Ejecutar Bison sobre la gramtica para producir el analizador. a 2. Compilar el cdigo de salida de Bison, al igual que cualquier otro chero fuente. o 3. Enlazar los cheros objeto para producir el producto nal.

1.7 El Formato Global de una Gramtica de Bison a


El chero de entrada para la utilidad Bison es un archivo de gramatica de Bison. La forma general de una gramtica de Bison es la siguiente: a

28

Bison 1.27

%{ declaraciones en C %} Declaraciones de Bison %% Reglas gramaticales %% Cdigo C adicional o Los %%, %{ y %} son signos de puntuacin que aparecen en todo archivo de gramtica de Bison o a para separar las secciones. Las declaraciones en C podr denir tipos y variables utilizadas en las acciones. Puede tambin an e usar comandos del preprocesador para denir macros que se utilicen ah y utilizar #include para , incluir archivos de cabecera que realicen cualquiera de estas cosas. Las declaraciones de Bison declaran los nombres de los s mbolos terminales y no terminales, y tambin podr describir la precedencia de operadores y los tipos de datos de los valores semnticos e an a de varios s mbolos. Las reglas gramaticales denen cmo construir cada s o mbolo no terminal a partir de sus partes. El cdigo C adicional puede contener cualquier cdigo C que desee utilizar. A menudo suele o o ir la denicin del analizador lxico yylex, ms subrutinas invocadas por las acciones en la reglas o e a gramaticales. En un programa simple, todo el resto del programa puede ir aqu .

Capitulo 2: Ejemplos

29

2 Ejemplos
Ahora presentaremos y explicaremos tres programas de ejemplo escritos utilizando Bison; una calculadora de notacin polaca inversa, una calculadora de notacin algebraica (inja), y una o o calculadora multi-funcin. Los tres han sido comprobados bajo BSD Unix 4.3; cada uno produce o una utilizable, aunque limitada, calculadora de escritorio. Estos ejemplos son simples, pero las gramticas de Bison para lenguajes de programacin reales a o se escriben de la misma manera.

2.1 Calculadora de Notacin Polaca Inversa o


El primer ejemplo es el de una simple calculadora de doble precisin de notacin polaca inversa o o (una calculadora que utiliza operadores postjos). Este ejemplo provee un buen punto de partida, ya que no hay problema con la precedencia de operadores. El segundo ejemplo ilustrar cmo se a o maneja la precendencia de operadores. El cdigo fuente para esta calculadora se llama rpcalc.y. La extensin .y es una convencin o o o utilizada para los archivos de entrada de Bison.

2.1.1 Declaraciones para rpcalc


Aqui estn las declaraciones de C y Bison para la calculadora de notacin polaca inversa. Como a o en C, los comentarios se colocan entre /*. . .*/. /* Calculadora de notacin polaca inversa. */ o %{ #define YYSTYPE double #include <math.h> %} %token NUM %% /* A continuacin las reglas gramaticales y las acciones */ o La seccin de declaraciones en C (ver Seccion 3.1.1 [La Seccin de Declaraciones en C], pgina 45) o o a contiene dos directivas del preprocesador. La directiva #define dene la macro YYSTYPE, de este modo se especica el tipo de dato de C para los valores semnticos de ambos, tokens y agrupaciones (ver Seccion 3.5.1 [Tipos de Datos de a Valores Semnticos], pgina 50). El analizador de Bison utilizar cualquier tipo que se dena para a a a YYSTYPE; si no lo dene, por defecto es int. Como hemos especicado double, cada token y cada expresin tiene un valor asociado, que es un n mero en punto otante. o u La directiva #include se utiliza para declarar la funcin de exponenciacin pow. o o

30

Bison 1.27

La segunda seccin, declaraciones de Bison, provee informacin a Bison a cerca de los tipos de o o tokens (ver Seccion 3.1.2 [La Seccin de Declaraciones de Bison], pgina 45). Cada s o a mbolo terminal que no sea un caracter literal simple debe ser declarado aqu (Los caracteres literales simples no necesitan ser declarados.) En este ejemplo, todos los operadores aritmticos se designan por un e caracter literal simple, as que el unico s mbolo terminal que necesita ser declarado es NUM, el tipo de token para las constantes numricas. e

2.1.2 Reglas Gramaticales para rpcalc


Aqu estn las reglas gramaticales para una calculadora de notacin polaca inversa. a o input: ; line: ; exp: NUM { $$ | exp exp + { $$ | exp exp - { $$ | exp exp * { $$ | exp exp / { $$ /* Exponenciacin */ o | exp exp ^ { $$ /* Menos unario */ | exp n { $$ = = = = = $1; $1 + $1 $1 * $1 / } } } } } \n | exp \n { printf ("\t%.10g\n", $1); } /* vaco */ | input line

$2; $2; $2; $2;

= pow ($1, $2); } = -$1; }

; %% Las agrupaciones del lenguaje de rpcalc denidas aqu son la expresin (con el nombre exp), o la l nea de entrada (line), y la transcripcin completa de la entrada (input). Cada uno de estos o s mbolos no terminales tiene varias reglas alternativas, unidas por el puntuador | que se lee como o. Las siguientes secciones explican lo que signican estas reglas. La semntica del lenguaje se determina por las acciones que se toman cuando una agrupacin a o es reconocida. Las acciones son el cdigo C que aparecen entre llaves. Ver Seccion 3.5.3 [Acciones], o pgina 50. a Debe especicar estas acciones en C, pero Bison facilita la forma de pasar valores semnticos a entre las reglas. En cada accin, la pseudo-variable $$ representa el valor semntico para la agruo a pacin que la regla va a construir. El trabajo principal de la mayor de las acciones es la asignacin o a o de un valor para $$. Se accede al valor semntico de los componentes de la regla con $1, $2, y as a sucesivamente.

2.1.2.1 Explicacin para input o


Considere la denicin de input: o

Capitulo 2: Ejemplos

31

input: ;

/* vaco */ | input line

Esta denicin se interpreta as Una entrada completa es o una cadena vac o una entrada o : a, completa seguida por una l nea de entrada. Note que entrada completa se dene en sus propios trminos. Se dice que esta denicin es recursiva por la izquierda ya que input aparece siempre e o como el s mbolo ms a la izquierda en la secuencia. Ver Seccion 3.4 [Reglas Recursivas], pgina 49. a a La primera alternativa est vac porque no hay s a a mbolos entre los dos puntos y el primer |; esto signica que input puede corresponder con una cadena de entrada vac (sin tokens). Escribimos a estas reglas de esa manera porque es leg timo escribir Ctrl-d despus de arrancar la calculadora. e Es clsico poner una alternativa vac al principio y escribir en esta el comentario /* vaco */. a a La segunda alternativa de la regla (input line) maneja toda la entrada no trivial. Esta signica, Despus de leer cualquier n mero de l e u neas, leer una ms si es posible. La recursividad por la a izquierda convierte esta regla en un bucle. Ya que la primera alternativa concuerda con la entrada vac el bucle se puede ejecutar cero o ms veces. a, a La funcin yyparse del analizador contin a con el procesamiento de la entrada hasta que se o u encuentre con un error gramatical o el analizador diga que no hay ms tokens de entrada; convena dremos que esto ultimo suceder al nal del chero. a

2.1.2.2 Explicacin para line o


Ahora considere la denicin de line: o line: ; La primera alternativa es un token que es un caracter de nueva-l nea; esta quiere decir que rpcalc acepta un l nea en blanco (y la ignora, ya que no hay ninguna accin). La segunda alternativa es o una expresin seguida de una l o nea nueva. Esta es la alternativa que hace que rpcalc sea util. El valor semntico de la agrupacin exp es el valor de $1 porque la exp en cuestin es el primer a o o s mbolo en la alternativa. La accin imprime este valor, que es el resultado del clculo que solicit o a o el usuario. Esta accin es poco com n porque no asigna un valor a $$. Como consecuencia, el valor o u semntico asociado con line est sin inicializar (su valor ser impredecible). Se tratar de un a a a a error si ese valor se utilizara, pero nosotros no lo utilizaremos: una vez que rpcalc haya imprimido el valor de la l nea de entrada del usuario, ese valor no se necesitar ms. a a \n | exp \n

{ printf ("\t%.10g\n", $1); }

2.1.2.3 Explicacin para expr o


La agrupacin exp tiene varias reglas, una para cada tipo de expresin. La primera regla maneja o o la expresiones ms simples: aquellas que son solamente n meros. La segunda maneja una expresin a u o de adicin, que tiene el aspecto de dos expresiones seguidas de un signo ms. La tercera maneja la o a resta, y as sucesivamente.

32

Bison 1.27

exp:

NUM | exp exp + | exp exp - ... ;

{ $$ = $1 + $2; { $$ = $1 - $2;

} }

Hemos utilizado | para unir las tres reglas de exp, pero igualmente podr amos haberlas escrito por separado: exp: exp: exp: NUM ; exp exp + exp exp - ...

{ $$ = $1 + $2; { $$ = $1 - $2;

} ; } ;

La mayor de las reglas tienen acciones que computan el valor de la expresin en trminos del a o e valor de sus componentes. Por ejemplo, en la regla de la adicin, $1 hace referencia al primer o componenete exp y $2 hace referencia al segundo. El tercer componente, +, no tiene un valor semntico asociado con signicado, pero si tuviese alguno podr hacer referencia a este con $3. a a Cuando yyparse reconoce una expresin de suma usando esta regla, la suma de los valores de las o dos subexpresiones producen el valor de toda la expresin. Ver Seccion 3.5.3 [Acciones], pgina 50. o a Usted no tiene de dar una accin para cada regla. Cuando una regla no tenga accin, por defecto o o Bison copia el valor de $1 en $$. Esto es lo que sucede en la primera regla (la que usa NUM). El formato mostrado aqu es la convencin recomendada, pero Bison no lo requiere. Puede o a adir o cambiar todos los espacios en blanco que desee. Por ejemplo, esto: n exp : NUM | exp exp + {$$ = $1 + $2; } | . . .

expresa lo mismo que esto: exp: NUM | exp exp + | ...

{ $$ = $1 + $2; }

El ultimo, sin embargo, es mucho ms legible. a

2.1.3 El Analizador Lxico de rpcalc e


El trabajo del analizador lxico es el anlisis a bajo nivel: la conversin de los caracteres o e a o secuencia de caracteres en tokens. El analizador de Bison obtiene sus tokens llamando al analizador lxico. Ver Seccion 4.2 [La Funcin del Analizador Lxico yylex], pgina 61. e o e a Solamente se necesita un analizador lxico sencillo para la calculadora RPN. Este analizador e lxico ignora los espacios en blanco y los tabuladores, luego lee los n meros como double y los e u devuelve como tokens NUM. Cualquier otro caracter que no forme parte de un n mero es un token u por separado. Tenga en cuenta que el cdigo del token para un token de caracter simple es el propio o caracter.

Capitulo 2: Ejemplos

33

El valor de retorno de la funcin de anlisis lxico es un cdigo numrico que representa el tipo o a e o e de token. El mismo texto que se utiliz en las reglas de Bison para representar el tipo de token o tambin es una expresin en C con el valor numrico del tipo. Esto funciona de dos maneras. Si el e o e tipo de token es un caracter literal, entonces su cdigo numrico es el cdigo ASCII de ese caracter; o e o puede usar el mismo caracter literal en el analizador lxico para expresar el n mero. Si el tipo de e u token es un identicador, ese identicador lo dene Bison como una macro en C cuya denicin es o un n mero apropiado. En este ejemplo, por lo tanto, NUM se convierte en una macro para que la u use yylex. El valor semntico del token (si tiene alguno) se almacena en la variable global yylval, que es a donde el analizador de Bison lo buscar. (El tipo de datos de C para yylval es YYSTYPE, que se a deni al principio de la gramtica; ver Seccion 2.1.1 [Declaraciones para rpcalc], pgina 29.) o a a Se devuelve un cdigo de tipo de token igual a cero cuando se llega al nal del chero. (Bison o reconoce cualquier valor no positivo como indicador del nal del chero de entrada.) Aqu est el cdigo para el analizador lxico: a o e /* El analizador lxico devuelve un nmero en coma e u flotante (double) en la pila y el token NUM, o el caracter ASCII ledo si no es un nmero. Ignora u todos los espacios en blanco y tabuladores, devuelve 0 como EOF. */ #include <ctype.h> yylex () { int c; /* ignora los espacios en blanco */ while ((c = getchar ()) == || c == \t) ; /* procesa nmeros u */ if (c == . || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval); return NUM; } /* devuelve fin-de-fichero */ if (c == EOF) return 0; /* devuelve caracteres sencillos */ return c; }

2.1.4 La Funcin de Control o


Para continuar acordes a este ejemplo, la funcin de control se mantiene escueta al m o nimo. El unico requisito es que llame a yyparse para comenzar el proceso de anlisis. a

34

Bison 1.27

main () { yyparse (); }

2.1.5 La Rutina de Informe de Errores


Cundo yyparse detecta un error de sintaxis, realiza una llamada a la funcin de informe de o errores yyerror para que imprima un mensaje de error (normalmente pero no siempre un "parse error"). Es cosa del programador el proveer yyerror (ver Capitulo 4 [Interfaz con el Analizador en Lenguaje C], pgina 61), luego aqu est la denicin que utilizaremos: a a o #include <stdio.h> yyerror (s) /* Llamada por yyparse ante un error */ char *s; { printf ("%s\n", s); } Despus de que yyerror retorne, el analizador de Bison podr recuperarse del error y continuar e a analizando si la gramtica contiene una regla de error apropiada (ver Capitulo 6 [Recuperacion de a Errores], pgina 81). De otra manera, yyparse devolver un valor distinto de cero. No hemos a a escrito ninguna regla de error en este ejemplo, as que una entrada no vlida provocar que termine a a el programa de la calculadora. Este no es el comportamiento adecuado para una calculadora real, pero es adecuado en el primer ejemplo.

2.1.6 Ejecutando Bison para Hacer el Analizador


Antes de ejecutar Bison para producir un analizador, necesitamos decidir cmo ordenar todo en o cdigo fuente en uno o ms cheros fuente. Para un ejemplo tan sencillo, la manera ms fcil es o a a a poner todo en un archivo. Las deniciones de yylex, yyerror y main van al nal, en la seccin de o cdigo C adicional del chero. (ver Seccion 1.7 [El Formato Global de una gramtica de Bison], o a pgina 27). a Para un proyecto ms grande, probablemente tendr varios cheros fuente, y utilizar make a a a para ordenar la recompilacin de estos. o Con todo el fuente en un unico archivo, utilice el siguiente comando para convertirlo en el chero del analizador: bison nombre archivo.y En este ejemplo el archivo se llam rpcalc.y (de Reverse Polish CALCulator, Calculadora o Polaca Inversa). Bison produce un archivo llamado nombre archivo.tab.c, quitando el .y del nombre del chero original. El chero de salida de Bison contiene el cdigo fuente para yyparse. o Las funciones adicionales en el chero de entrada (yylex, yyerror y main) se copian literalmente a la salida.

Capitulo 2: Ejemplos

35

2.1.7 Compilando el Archivo del Analizador


Aqu est la forma de compilar y ejecutar el archivo del analizador: a # Lista los archivos en el directorio actual. % ls rpcalc.tab.c rpcalc.y # Compila el analizador de Bison. # -lm le dice al compilador que busque la librer math para pow. a % cc rpcalc.tab.c -lm -o rpcalc # Lista de nuevo los archivos. % ls rpcalc rpcalc.tab.c rpcalc.y El archivo rpcalc contiene ahora el cdigo ejecutable. He aqu una sesin de ejemplo utilizando o o rpcalc. % rpcalc 4 9 + 13 3 7 + 3 4 5 *+-13 3 7 + 3 4 5 * + - n 13 5 6 / 4 n + -3.166666667 3 4 ^ 81 ^D %

Note el menos unario, n

Exponenciacin o Indicador de Fin-de-chero

2.2 Calculadora de Notacin Inja: calc o


Ahora modicaremos rpcalc para que maneje operadores injos en lugar de postjos. La notacin o inja trae consigo el concepto de la precedencia de operadores y la necesidad de parntesis anidados e de profundidad arbitraria. Aqu est el cdigo de Bison para calc.y, una calculadora inja de a o escritorio. /* Calculadora de notacin infija--calc */ o %{ #define YYSTYPE double #include <math.h> %} /* Declaraciones de BISON */ %token NUM %left - +

36

Bison 1.27

%left * / %left NEG /* negacin--menos unario */ o %right ^ /* exponenciacin o */ /* A continuacin la gramtica */ o a %% input: /* cadena vaca */ | input line ; line: ; exp: | | | | | | | ; %% Las funciones yylex, yyerror y main pueden ser las mismas de antes. Hay dos propiedades nuevas importantes presentadas en este cdigo. o En la segunda seccin (declaraciones de Bison), %left declara tipos de tokens y dice que son o operadores asociativos por la izquierda. Las declaraciones %left y %right (asociatividad por la derecha) toma el lugar de %token que se utiliza para declarar un nombre de tipo de token sin asociatividad. (Estos tokens son caracteres literales simples, que de forma ordinaria no tienen que ser declarados. Los declaramos aqu para especicar la asociatividad.) La precedencia de operadores se determina por el orden de l nea de las declaraciones; cuanto ms alto sea el n mero de l a u nea de la declaracin (esta est ms baja en la pgina o en la pantalla), o e a a ms alta ser la precedencia. Por tanto, la exponenciacin tiene la precedencia ms alta, el menos a a o a unario (NEG) es el siguiente, seguido por * y /, y as sucesivamente. Ver Seccion 5.3 [Precedencia de Operadores], pgina 72. a La otra propiedad nueva importante es el %prec en la seccin de la gramtica para el operador o a menos unario. El %prec simplemente le dice a Bison que la regla | - exp tiene la misma precedencia que NEGen este caso la siguiente a la ms alta. Ver Seccion 5.4 [Precedencia Dependiende a del Contexto], pgina 73. a Aqu hay un ejemplo de la ejecucin de calc.y: o % calc 4 + 4.5 - (34/(8*3+-3)) 6.880952381 NUM exp exp exp exp - exp ( + - * / exp ^ exp { $$ exp { $$ exp { $$ exp { $$ exp { $$ %prec NEG { $$ exp { $$ ) { $$ = = = = = = = = $1; } $1 + $3; } $1 - $3; } $1 * $3; } $1 / $3; } -$2; } pow ($1, $3); } $2; } \n | exp \n { printf ("\t%.10g\n", $1); }

Capitulo 2: Ejemplos

37

-56 + 2 -54 3 ^ 2 9

2.3 Recuperacin de Errores Simple o


Hasta este punto, este manual no ha tratado el tema de la recuperacin de errorescmo o o continuar analizando despus de que el analizador detecte un error de sintaxis. Todo lo que hemos e manejado es el informe de errores con yyerror. Tenga presente que por defecto yyparse retorna despus de llamar a yyerror. Esto quiere decir que una l e nea de entrada errnea hace que el o programa de la calculadora nalice. Ahora mostraremos cmo recticar esta deciencia. o El lenguaje de Bison por s mismo incluye la palabra reservada error, que podr incluirse en a las reglas de la gramtica. En el siguiente ejemplo esta se ha a adido a una de las alternativas para a n line: line: ; Esta ampliacin a la gramtica permite una recuperacin de errores simple en caso de un error o a o de anlisis. Si se lee una expresin que no puede ser evaluada, el error ser reconocido por la tercera a o a regla de line, y el anlisis continuar. (La funcin yyerror a n se sigue llamando para imprimir a a o u su mensaje tambin.) La accin ejecuta la sentencia yyerrok, una macro denida automticamente e o a por Bison; su signicado es que la recuperacin de errores ha terminado (ver Capitulo 6 [Recupeo racion de Errores], pgina 81). Note la diferencia entre yyerrok y yyerror; no se trata de ninguna a errata. Esta forma de recuperacin de errores trata con errores sintcticos. Existe otro tipo de errores; o a por ejemplo, la divisin entre cero, que conlleva una se al de excepcin que normalmente es fatal. o n o Una calculadora real debe tratar esta se al y utilizar longjmp para retornar a main y reanudar el n anlisis de l a neas de entrada; tambin tendr que descartar el resto de la l e a nea de entrada actual. No discutiremos esta cuestin ms all porque no es espec o a a ca de los programas de Bison. \n | exp \n { printf ("\t%.10g\n", $1); } | error \n { yyerrok; }

2.4 Calculadora Multi-Funcin: mfcalc o


Ahora que se han explicado los conceptos bsicos de Bison, es tiempo de movernos a problemas a ms avanzados. Las calculadoras anteriores ofrec solamente cinco funciones, +, -, *, / y a an ^. Ser bueno tener una calculadora que dispusiera de otras funciones matemticas tales como a a sin, cos, etc. Es fcil a adir nuevos operadores a la calculadora inja siempre que estos sean unicamente a n caracteres literales simples. El analizador lxico yylex pasa todos lo caracteres no numricos como e e tokens, luego basta con nuevas reglas gramaticales para a adir un nuevo operador. Pero lo que n queremos es algo ms exible: funciones incorporadas cuya sintaxis tenga la siguiente forma: a

38

Bison 1.27

o nombre funcin (argumento) Al mismo tiempo, a adiremos memoria a la calculadora, permitindole crear variables con nombre, n e almacenar valores en ellas, y utilizarlas ms tarde. Aqu hay una sesin de ejemplo con la calculadora a o multi-funcin: o % mfcalc pi = 3.141592653589 3.1415926536 sin(pi) 0.0000000000 alpha = beta1 = 2.3 2.3000000000 alpha 2.3000000000 ln(alpha) 0.8329091229 exp(ln(beta1)) 2.3000000000 % Note que estn permitidas las asignaciones m ltiples y las funciones anidadas. a u

2.4.1 Declaraciones para mfcalc


Aqu estn las declaraciones de C y Bison para la calculadora multi-funcin. a o %{ #include <math.h> /* Para funciones matemticas, cos(), sin(), etc. a #include "calc.h" /* Contiene definicin de symrec o %} %union { double val; /* Para devolver nmeros u symrec *tptr; /* Para devolver punteros a la tabla de smbolos } %token <val> NUM %token <tptr> VAR FNCT %type <val> exp /* Nmero simple en doble precisin u o /* Variable y Funcin o

*/ */ */ */ */ */

%right = %left - + %left * / %left NEG /* Negacin--menos unario */ o %right ^ /* Exponenciacin o */ /* A continuacin la gramtica */ o a %%

Capitulo 2: Ejemplos

39

La gramtica anterior introduce unicamente dos nuevas propiedades del lenguaje de Bison. Estas a propiedades permiten que los valores semnticos tengan varios tipos de datos. (ver Seccion 3.5.2 a [Ms de Un Tipo de Valor], pgina 50). a a La declaracin %union especica la lista completa de tipos posibles; esta se encuentra en lugar o de la denicin de YYSTYPE. Los tipos permisibles son ahora double (para exp y NUM) y puntero a o entrada en la tabla de s mbolos. Ver Seccion 3.6.3 [La Coleccin de Tipos de Valores], pgina 57. o a Ya que ahora los valores pueden tener varios tipos, es necesario asociar un tipo con cada s mbolo gramatical cuyo valor semntico se utilice. Estos s a mbolos son NUM, VAR, FNCT, y exp. Sus declaraciones aumentan con la informacin a cerca de su tipo de dato (que se encuentra entre angulos). o La construccin de Bison %type se utiliza para la declaracin de s o o mbolos no terminales, al igual que %token se utiliza para declarar tipos de tokens. No hemos usado %type anteriormente porque los s mbolos no terminales se declaran impl citamente por las reglas que los denen. Pero exp debe ser declarado expl citamente para poder especicar el tipo de su valor. Ver Seccion 3.6.4 [S mbolos No Terminales], pgina 57. a

2.4.2 Reglas Gramaticales para mfcalc


Aqu estn las reglas gramaticales para la calculadora multi-funcin. La mayor de ellas han a o a sido copiadas directamente de calc; tres reglas, aquellas que mencionan a VAR o FNCT, son nuevas. input: ; line: \n | exp \n { printf ("\t%.10g\n", $1); } | error \n { yyerrok; } ; exp: | | | | | | | | | | NUM VAR VAR = exp FNCT ( exp ) exp + exp exp - exp exp * exp exp / exp - exp %prec NEG exp ^ exp ( exp ) { { { { { { { { { { { $$ $$ $$ $$ $$ $$ $$ $$ $$ $$ $$ = = = = = = = = = = = $1; $1->value.var; $3; $1->value.var = $3; (*($1->value.fnctptr))($3); $1 + $3; $1 - $3; $1 * $3; $1 / $3; -$2; pow ($1, $3); $2; } } } } } } } } } } } /* vaco */ | input line

; /* Fin de la gramtica */ a %%

40

Bison 1.27

2.4.3 La Tabla de S mbolos de mfcalc


La calculadora multi-funcin requiere una tabla de s o mbolos para seguir la pista de los nombres y signicado de las variables y funciones. Esto no afecta a las reglas gramaticales (excepto para las acciones) o las declaraciones de Bison, pero requiere algunas funciones de apoyo adicionales en C. La tabla de s mbolos de por s contiene un lista enlazada de registros. Su denicin, que est o a contenida en la cabecera calc.h, es la siguiente. Esta provee que, ya sean funciones o variables, sean colocadas en la tabla. /* Tipo de datos para enlaces en la cadena de smbolos. struct symrec { char *name; /* nombre del smbolo */ int type; /* tipo del smbolo: bien VAR o FNCT */ union { double var; /* valor de una VAR */ double (*fnctptr)(); /* valor de una FNCT */ } value; struct symrec *next; /* campo de enlace */ }; typedef struct symrec symrec; /* La tabla de smbolos: una cadena de struct symrec. extern symrec *sym_table; symrec *putsym (); symrec *getsym (); La nueva versin de main incluye una llamada a init_table, una funcin que inicializa la tabla o o de s mbolos. Aqu est esta, y tambin init_table: a e #include <stdio.h> main () { init_table (); yyparse (); } yyerror (s) /* Llamada por yyparse ante un error */ char *s; { printf ("%s\n", s); } struct init { char *fname; double (*fnct)(); }; */ */

Capitulo 2: Ejemplos

41

struct init arith_fncts[] = { "sin", sin, "cos", cos, "atan", atan, "ln", log, "exp", exp, "sqrt", sqrt, 0, 0 }; /* La tabla de smbolos: una cadena de struct symrec. symrec *sym_table = (symrec *)0; */

init_table () /* pone las funciones aritmticas en una tabla. */ e { int i; symrec *ptr; for (i = 0; arith_fncts[i].fname != 0; i++) { ptr = putsym (arith_fncts[i].fname, FNCT); ptr->value.fnctptr = arith_fncts[i].fnct; } } Mediante la simple edicin de la lista de inicializacin y a adiendo los archivos de inclusin o o n o necesarios, puede a adir funciones adicionales a la calculadora. n Dos funciones importantes permiten la localizacin e insercin de s o o mbolos en la tabla de s mbolos. A la funcin putsym se le pasa un nombre y el tipo (VAR o FNCT) del objeto a insero tar. El objeto se enlaza por la cabeza de la lista, y devuelve un puntero al objeto. A la funcin o getsym se le pasa el nombre del s mbolo a localizar. Si se encuentra, se devuelve un punteo a ese s mbolo; en caso contrario se devuelve un cero. symrec * putsym (sym_name,sym_type) char *sym_name; int sym_type; { ptr = (symrec *) malloc (sizeof (symrec)); ptr->name = (char *) malloc (strlen (sym_name) + 1); strcpy (ptr->name,sym_name); ptr->type = sym_type; ptr->value.var = 0; /* pone valor a 0 incluso si es fctn. ptr->next = (struct symrec *)sym_table; sym_table = ptr; return ptr; } symrec * getsym (sym_name)

*/

42

Bison 1.27

char *sym_name; { symrec *ptr; for (ptr = sym_table; ptr != (symrec *) 0; ptr = (symrec *)ptr->next) if (strcmp (ptr->name,sym_name) == 0) return ptr; return 0; }

La funcin yylex debe reconocer ahora variables, valores numricos, y los operadores aritmticos o e e de caracter simple. Las cadenas de caracteres alfanumricas que no comiencen con un d e gito son reconocidas como variables o funciones dependiendo de lo que la tabla de s mbolos diga de ellas.

La cadena de caracteres se le pasa a getsym para que la localice en la tabla de s mbolos. Si el nombre aparece en la tabla, se devuelve a yyparse un puntero a su localizacin y su tipo (VAR o o FNCT). Si no est ya en la tabla, entonces se inserta como VAR utilizando putsym. De nuevo, se a devuelve a yyparse un puntero y su tipo (que deber ser VAR). a

No se necesita ning n cambio en yylex para manejar los valores numricos y los operadores u e aritmticos. e

#include <ctype.h> yylex () { int c; /* Ignora espacios en blanco, obtiene el primer caracter */ while ((c = getchar ()) == || c == \t); if (c == EOF) return 0; /* Comienza un nmero => analiza el nmero. u u if (c == . || isdigit (c)) { ungetc (c, stdin); scanf ("%lf", &yylval.val); return NUM; } */

/* Comienza un identificador => lee el nombre. */ if (isalpha (c)) { symrec *s; static char *symbuf = 0; static int length = 0; int i;

Capitulo 2: Ejemplos

43

/* Inicialmente hace el buffer lo suficientemente largo para un nombre de smbolo de 40 caracteres. */ if (length == 0) length = 40, symbuf = (char *)malloc (length + 1); i = 0; do { /* Si el buffer esta lleno, hacerlo mayor. */ if (i == length) { length *= 2; symbuf = (char *)realloc (symbuf, length + 1); } /* A~adir este caracter al buffer. n */ symbuf[i++] = c; /* Obtiene otro caracter. */ c = getchar (); } while (c != EOF && isalnum (c)); ungetc (c, stdin); symbuf[i] = \0; s = getsym (symbuf); if (s == 0) s = putsym (symbuf, VAR); yylval.tptr = s; return s->type; } /* Cualquier otro caracter es un token por s mismo. */ return c; } Este programa es por ambos lados potente y exible. Usted podr fcilmente a adir nuevas funa a n ciones, y es un trabajo sencillo modicar este cdigo para introducir tambin variables predenidas o e tales como pi o e.

2.5 Ejercicios
1. A ada algunas nuevas funciones de math.h a la lista de inicializacin. n o 2. A ada otro array que contenga constantes y sus valores. Entonces modique init_table para n a adir estas constantes a la tabla de s n mbolos. Ser mucha ms fcil darle a las constantes el a a a tipo VAR. 3. Hacer que el programa muestre un error si el usuario hace referencia a una variable sin inicializar de cualquier manera excepto al almacenar un valor en ella.

44

Bison 1.27

Capitulo 3: Archivos de Gramtica de Bison a

45

3 Archivos de Gramtica de Bison a


Bison toma como entrada la especicacin de una gramtica independiente del contexto y proo a duce una funcin en lenguaje C que reconoce las instancias correctas de la gramtica. o a El archivo de entrada de la gramtica de Bison tiene un nombre que naliza por convencin en a o .y.

3.1 Resumen de una Gramtica de Bison a


Un archivo de gramtica de Bison tiene cuatro secciones principales, mostradas aqu con los a delimitadores apropiados: %{ Declaraciones en C %} Declaraciones en Bison %% Reglas Gramaticales %% Cdigo C adicional o Los comentarios encerrados entre /* . . . */ pueden aparecer en cualquiera de las secciones.

3.1.1 La Seccin de Declaraciones en C o


La seccin de declaraciones en C contiene deniciones de macros y declaraciones de funciones y o variables que se utilizan en las acciones en las reglas de la gramtica. Estas se copian al principio del a archivo del analizador de manera que precedan la denicin de yyparse. Puede utlilizar #include o para obtener las declaraciones de un archivo de cabecera. Si no necesita ninguna declaracin en C, o puede omitir los delimitadores %{ y %} que delimitan esta seccin. o

3.1.2 La Seccin de Declaraciones de Bison o


La seccin de declaraciones de Bison contiene declaraciones que denen s o mbolos terminales y no terminales, especica la precedencia, etc. En algunas gramticas simples puede que no necesite a ninguna de las declaraciones. Ver Seccion 3.6 [Declaraciones de Bison], pgina 55. a

3.1.3 La Seccin de Reglas Gramaticales o


La seccin de las reglas gramaticales contiene una o ms reglas gramaticales, y nada ms. Ver o a a Seccion 3.3 [Sintaxis de las Reglas Gramaticales], pgina 48. a

46

Bison 1.27

Debe haber siempre al menos una regla gramatical, y el primer %% (que precede a las reglas gramaticales) no puede ser omitido nunca incluso si es la primera cosa en el chero.

3.1.4 La Seccin de Cdigo C Adicional o o


La seccin de cdigo C adicional se copia al pie de la letra a la salida del chero del analizador, al o o igual que la seccin de declaraciones en C que se copia al principio. Este es el lugar ms conveniente o a para poner cualquier cosa que quiera tener en el archivo del analizador pero que no deba venir antes que la denicin de yyparse. Por ejemplo, las deniciones de yylex e yyerror a menudo van ah o . Ver Capitulo 4 [Interfaz con el Analizador en Lenguaje C], pgina 61. a Si la ultima seccin est vac puede omitir el %% que los separa de las reglas gramaticales. o a a, El analizador de Bison en s contiene muchas variables estticas cuyos nombres comienzan con a yy y muchas macros cuyos nombres comienzan con YY. Es una buena idea evitar el uso de cualquiera de estos nombres (excepto aquellos documentados en este menual) en la seccin de o cdigo C adicional del archivo de la gramtica. o a

3.2 S mbolos, Terminales y No Terminales


Los s mbolos en las gramticas de Bison representan las clasicaciones gramaticales del lenguaje. a Un s mbolo terminal (tambin conocido como un tipo de token) representa una clase de tokens e equivalentes sintcticamente. Usted utiliza el s a mbolo en las reglas de la gramtica para indicar a que est permitido un token en esa clase. El s a mbolo se representa en el analizador de Bison por un cdigo numrico, y la funcin yylex devuelve un cdigo de tipo de token para indicar qu tipo de o e o o e token se ha le do. Usted no necesita conocer cual es el valor del cdigo; puede utilizar el s o mbolo para representarlo. Un s mbolo no terminal representa una clase de agrupaciones sintcticamente equivalentes. El a nombre del s mbolo se utiliza para escribir las reglas gramaticales. Por convencin, todos deber o an escribirse en min sculas. u Los nombres de los s mbolos pueden contener letras, d gitos (no al principio), subrayados y puntos. Los puntos tienen sentido unicamente en no-terminales. Hay tres maneras de escribir s mbolos terminales en la gramtica: a Un tipo de token designado se escribe con un identiacador, de la misma manera que un identicador en C. Por convencin, deber estar todo en may sculas. Cada uno de estos o a u nombres debe denirse con una declaracin de Bison tal como %token. Ver Seccion 3.6.1 o [Nombres de Tipo de Token], pgina 55. a Un tipo de token de caracter (o token de caracter literal) se escribe en la gramtica utilizando a la misma sintaxis usada en C para las constantes de un caracter; por ejemplo, + es un tipo de token de caracter. Un tipo de token de caracter no necesita ser declarado a menos que necesite especicar el tipo de datos de su valor semntico (ver Seccion 3.5.1 [Tipo de Datos de a Valores Semnticos], pgina 50), asociatividad, o precedencia (ver Seccion 5.3 [Precedencia de a a Operadores], pgina 72). a

Capitulo 3: Archivos de Gramtica de Bison a

47

Por convencin, un tipo de token de caracter se utiliza unicamente para representar un token o que consista de ese caracter en particular. De este modo, el tipo de token + se utiliza para representar el caracter + como un token. No hay nada que obligue a seguir esta convencin, o pero si no lo hace, su programa ser confuso para otros lectores. a Todas las secuencias usuales de escape que se utilizan en caracteres literales en C pueden ser utilizadas igualmente en Bison, pero no debe usar el caracter nulo como un caracter literal porque su codigo ASCII, el cero, es el cdigo que yylex devuelve para el nal de la entrada o (ver Seccion 4.2.1 [Convecin de Llamada para yylex], pgina 61). o a Un token de cadena literal se escribe como un string constante de C; por ejemplo, "<=" es un token de cadena literal. Un token de cadena literal no necesita ser declarado a menos que desee especicar el tipo de dato de su valor semntico (ver Seccion 3.5.1 [Tipo de Valor], pgina 50), a a asociatividad, precedencia (ver Seccion 5.3 [Precedencia], pgina 72). a Puede asociar el token de cadena literal con un nombre simblico como un alias, utilizando la o declaracin %token (ver Seccion 3.6.1 [Declaraciones de Tokens], pgina 55). Si no lo hace, el o a analizador lxico debe recuperar el n mero del token para el token de cadena literal desde la e u tabla yytname (ver Seccion 4.2.1 [Convenciones de Llamada], pgina 61). a ADVERTENCIA: los tokens de cadena literal no funcionan en YACC. Por convencin, un token de cadena literal se utiliza unicamente para representar un token o que consiste en esa cadena en particular. As deber utilizar el tipo de token "<=" para , a representar la cadena <= como un token. Bison no impone esta convencin, pero si se aparta o de ella, la gente que lea su programa se ver confusa. a Todas las secuencias de escape utilizadas en las cadenas de literales de C pueden usarse igualmente en Bison. Un token de cadena literal debe contener dos o ms caracteres; para un token a que contenga un solo caracter, utilice un token de caracter (ver lo anterior).

El cmo se escoge la manera de escribir un s o mbolo no tiene efecto en su signicado gramatical. Esto depende unicamente de dnde aparece en las reglas y cundo la funcin de anlisis sintctico o a o a a devuelve ese s mbolo. El valor devuelto por yylex es siempre uno de los s mbolos terminlaes ( 0 para el n de la o entrada). Sea cual sea la manera en la que escriba el tipo de token en las reglas gramaticales, escr bala de la misma manera en la denicin de yylex. El cdigo numrico para un tipo de o o e token de caracter es simplemente el codigo ASCII para el caracter, as que yylex puede utilizar la constante idntica del caracter para generar el cdigo requerido. Cada tipo de token denominado e o se convierte en una macro en C en el chero del analizador, de manera que yylex puede utilizar el nombre para hacer referencia al cdigo. (Esta es la razn por la que los puntos no tienen sentido o o en los s mbolos terminales.) Ver Seccion 4.2.1 [Convencin de Llamada para yylex], pgina 61. o a Si se dene yylex en un archivo aparte, debe prepararlo para que las deniciones de las macros de los tipos de tokens estn disponibles all Utilice la opcin -d cuando ejecute Bison, de esta forma se e . o escribirn estas deniciones de las macros en un archivo de cabecera por separado nombre.tab.h a que puede incluir en los otros archivos fuente que lo necesite. Ver Capitulo 9 [Invocando a Bison], pgina 89. a El s mbolo error es un s mbolo terminal reservado para la recuperacin de errores (ver Capitulo 6 o [Recuperacion de Errores], pgina 81); no deber utilizarlo para cualquier otro propsito. En a a o particular, yylex nunca deber devolver este valor. a

48

Bison 1.27

3.3 Sintaxis de las Reglas Gramaticales


Una regla gramatical de Bison tiene la siguiente forma general: resultado: componentes. . . ; donde resultado es el s mbolo no terminal que describe esta regla y componentes son los diversos s mbolos terminales y no terminales que estn reunidos por esta regla (ver Seccion 3.2 [Simbolos], a pgina 46). a Por ejemplo, exp: ; dice que dos agrupaciones de tipo exp, con un token + en medio, puede combinarse en una agrupacin mayor de tipo exp. o Los espacios en blanco en las reglas son signicativos unicamente para separar s mbolos. Puede a adir tantos espacios en blanco extra como desee. n Distrubu dos en medio de los componentes pueden haber acciones que determinan la semntica a de la regla. Una accin tiene el siguiente aspecto: o {sentencias en C} Normalmente hay una unica accin que sigue a los componentes. Ver Seccion 3.5.3 [Acciones], o pgina 50. a Se pueden escribir por separado varias reglas para el mismo resultado o pueden unirse con el caracter de barra vertical | as : resultado: compoenentes-regla1. . . | componentes-regla2. . . ... ; Estas a n se consideran reglas distintas incluso cuando se unen de esa manera. Si los componentes u en una regla estn vac signica que resultado puede concordar con la cadena vac Por ejemplo, a os, a. aqu aparece cmo denir una secuencia separada por comas de cero o ms agrupaciones exp: o a expseq: /* vaco */ | expseq1 ; exp + exp

expseq1: exp | expseq1 , exp ;

Capitulo 3: Archivos de Gramtica de Bison a

49

Es habitual escribir el comentario /* vaco */ en cada regla sin componentes.

3.4 Reglas Recursivas


Una regla se dice recursiva cuando su no-terminal resultado aparezca tambin en su lado derecho. e Casi todas las gramticas de Bison hacen uso de la recursin, ya que es la unica manera de denir a o una secuencia de cualquier n mero de cosas. Considere esta denicin recursiva de una secuencia u o de una o ms expresiones: a expseq1: exp | expseq1 , exp ; Puesto que en el uso recursivo de expseq1 este es el s mbolo situado ms a la izquierda del lado a derecho, llamaremos a esto recursin por la izquierda. Por contraste, aqu se dene la misma o construccin utilizando recusin por la derecha: o o expseq1: exp | exp , expseq1 ; Cualquier tipo de secuencia se puede denir utilizando ya sea la recursin por la izquierda o recursin o o por la derecha, pero deber utilizar siempre recursin por la izquierda, porque puede analizar una a o secuencia de elementos sin ocupar espacio de pila. La recursin por la derecha utiliza espacio en o la pila de Bison en proporcin al n mero de elementos en la secuencia, porque todos los elementos o u deben ser desplazados en la pila antes de que la regla pueda aplicarse incluso una unica vez. Ver Capitulo 5 [El Algoritmo del Analizador de Bison], pgina 69, para una explicacin adicional a a o cerca de esto. La recursin indirecta o mutua sucede cuando el resultado de la regla no aparece directamente o en su lado derecho, pero aparece en las reglas de otros no terminales que aparecen en su lado derecho. Por ejemplo: expr: primario | primario + primario ;

primario: constante | ( expr ) ; dene dos no-terminales recursivos mutuamente, ya que cada uno hace referencia al otro.

50

Bison 1.27

3.5 Deniendo la Semntica del Lenguaje a


Las reglas gramaticales para un lenguaje determinan unicamente la sintaxis. La semntica a viene determinada por los valores semnticos asociados con varios tokens y agrupaciones, y por las a acciones tomadas cuando varias agrupaciones son reconocidas. Por ejemplo, la calculadora calcula bien porque el valor asociado con cada expresin es el n mero o u apropiado; sta suma correctamente porque la accin para la agrupacin x + y es sumar los e o o n meros asociados con x e y. u

3.5.1 Tipos de Datos para Valores Semnticos a


En un programa sencillo podr ser suciente con utilizar el mismo tipo de datos para los valores a semnticos de todas las construcciones del lenguaje. Esto fue cierto en los ejemplos de calculadora a RPN e inja (ver Seccion 2.1 [Calculadora de Notacin Polaca Inversa], pgina 29). o a Por defecto Bison utiliza el tipo int para todos los valores semnticos. Para especicar alg n a u otro tipo, dena YYSTYPE como una macro, de esta manera: #define YYSTYPE double Esta denicin de la macro debe ir en la seccin de declaraciones en C del chero de la gramtica o o a (ver Seccion 3.1 [Resumen de una Gramtica de Bison], pgina 45). a a

3.5.2 Ms de Un Tipo de Valor a


En la mayor de los programas, necesitar diferentes tipos de datos para diferentes clases de a a tokens y agrupaciones. Por ejemplo, una constante numrica podr necesitar el tipo int o long, e a mientras que una cadena constante necesita el tipo char *, y un identicador podr necesitar un a puntero a la tabla de s mbolos. Para utilizar ms de un tipo de datos para los valores semnticos en un analizador, Bison le a a pide dos cosas: Especicar la coleccin completa de tipos de datos posibles, con la declaracin de Bison %union o o (ver Seccion 3.6.3 [La Coleccin de Tipos de Valores], pgina 57). o a Elegir uno de estos tipos para cada s mbolo (terminal o no terminal) para los valores semnticos a que se utilicen. Esto se hace para los tokens con la declaracin de Bison %token (ver Seco cion 3.6.1 [Nombres de Tipo de Token], pgina 55) y para las agrupaciones con la declaracin a o de Bison %type (ver Seccion 3.6.4 [S mbolos No Terminales], pgina 57). a

3.5.3 Acciones
Una accin acompa a a una regla sintctica y contiene cdigo C a ser ejecutado cada vez que o n a o se reconoce una instancia de esa regla. La tarea de la mayor de las acciones es computar el valor a semntico para la agrupacin construida por la regla a partir de los valores semnticos asociados a a o a los tokens o agrupaciones ms peque as. a n

Capitulo 3: Archivos de Gramtica de Bison a

51

Una accin consiste en sentencias de C rodeadas por llaves, muy parecido a las sentencias o compuestas en C. Se pueden situar en cualquier posicin dentro de la regla; esta se ejecuta en esa o posicin. La mayor de las reglas tienen slo una accin al nal de la regla, a continuacin de o a o o o todos los componentes. Las acciones en medio de una regla son dif ciles y se utilizan unicamente para propsitos especiales (ver Seccion 3.5.5 [Acciones a Media Regla], pgina 52). o a El cdigo C en una accin puede hacer referencia a los valores semnticos de los componentes o o a reconocidos por la regla con la construccin $n, que hace referencia al valor de la componente o n-sima. El valor semntico para la agrupacin que se est construyendo es $$. (Bison traduce e a o a ambas construcciones en referencias a elementos de un array cuando copia las acciones en el chero del analizador.) Aqu hay un ejemplo t pico: exp:

... | exp + exp { $$ = $1 + $3; }

Esta regla contruye una exp de dos agrupaciones exp ms peque as conectadas por un token de a n signo ms. En la accin, $1 y $3 hacen referencia a los valores semnticos de las dos agrupaciones a o a exp componentes, que son el primer y tercer s mbolo en el lado derecho de la regla. La suma se almacena en $$ de manera que se convierte en el valor semntico de la expresin de adicin a o o reconocida por la regla. Si hubiese un valor semntico util asociado con el token +, deber a a hacerse referencia con $2. Si no especica una accin para una regla, Bison suministra una por defecto: $$ = $1. De este o modo, el valor del primer s mbolo en la regla se convierte en el valor de la regla entera. Por supuesto, la regla por defecto solo es vlida si concuerdan los dos tipos de datos. No hay una regla a por defecto con signicado para la regla vac toda regla vac debe tener una accin expl a; a o cita a menos que el valor de la regla no importe. $n con n cero o negativo se admite para hacer referencia a tokens o agrupaciones sobre la pila antes de aquellas que empareja la regla actual. Esta es una prctica muy arriesgada, y para a utilizarla de forma able debe estar seguro del contexto en el que se aplica la regla. Aqu hay un donde puede utilizar esto de forma able: foo: expr bar + expr | expr bar - expr ; { ... } { ... }

bar:

/* vaco */ { previous_expr = $0; } ;

Siempre que bar se utilice solamente de la manera mostrada aqu $0 siempre hace referencia a , la exp que precede a bar en la denicin de foo. o

52

Bison 1.27

3.5.4 Tipos de Datos de Valores en Acciones


Si ha elegido un tipo de datos unico para los valores semnticos, las construcciones $$ y $n a siempre tienen ese tipo de datos. Si ha utilizado %union para especicar una variedad de tipos de datos, entonces debe declarar la eleccin de entre esos tipos para cada s o mbolo terminal y no terminal que puede tener un valor semntico. Entonces cada vez que utilice $$ o $n, su tipo de datos se determina por el s a mbolo al que hace referencia en la regla. En este ejemplo, exp: ... | exp + exp { $$ = $1 + $3; }

$1 y $3 hacen referencia a instancias de exp, de manera que todos ellos tienen el tipo de datos declarado para el s mbolo no terminal exp. Si se utilizase $2, tendr el tipo de datos declarado a para el s mbolo terminal +, cualquiera que pudiese ser. De forma alternativa, puede especicar el tipo de datos cuando se hace referencia al valor, insertando <tipo> despus del $ al comienzo de la referencia. Por ejemplo, si ha denido los e tipos como se muestra aqu : %union { int tipoi; double tipod; } entonces puede escribir $<tipoi>1 para hacer referencia a la primera subunidad de la regla como un entero, o $<tipod>1 para referirse a este como un double.

3.5.5 Acciones a Media Regla


Ocasionalmente es de utilidad poner una accin en medio de una regla. Estas acciones se escriben o como las acciones al nal de la regla, pero se ejecutan antes de que el analizador llegue a reconocer los componentes que siguen. Una accin en mitad de una regla puede hacer referencia a los componentes que la preceden o utilizando $n, pero no puede hacer referencia a los componentes subsecuentes porque esta se ejecuta antes de que sean analizados. Las acciones en mitad de una regla por s mismas cuentan como uno de los componentes de la regla. Esto produce una diferencia cuando hay otra accin ms tarde en la misma regla (y o a normalmente hay otra al nal): debe contar las acciones junto con los s mbolos cuando quiera saber qu n mero n debe utilizar en $n. e u La accin en la mitad de una regla puede tambin tener un valor semntico. La accin puede o e a o establecer su valor con una asignacin a $$, y las acciones posteriores en la regla pueden hacer o referencia al valor utilizando $n. Ya que no hay un s mbolo que identique la accin, no hay manera o

Capitulo 3: Archivos de Gramtica de Bison a

53

de declarar por adelantado un tipo de datos para el valor, luego debe utilizar la construccin $<. . .> o para especicar un tipo de datos cada vez que haga referencia a este valor. No hay forma de establecer el valor de toda la regla con una accin en medio de la regla, porque o las asignaciones a $$ no tienen ese efecto. La unica forma de establecer el valor para toda la regla es con una accin corriente al nal de la regla. o Aqu hay un ejemplo tomado de un compilador hipottico, manejando una sentencia let de e la forma let (variable) sentencia y sirve para crear una variable denominada variable temporalmente durante la duracin de la sentencia. Para analizar esta construccin, debemos poner variable o o dentro de la tabla de s mbolos mientras se analiza sentencia, entonces se quita despus. Aqu est e a cmo se hace: o stmt: LET ( var ) { $<contexto>$ = push_contexto (); declara_variable ($3); } stmt { $$ = $6; pop_contexto ($<contexto>5); }

Tan pronto como let (variable) se haya reconocido, se ejecuta la primera accin. Esta guarda o una copia del contexto semntico actual (la lista de variables accesibles) como su valor semntico, a a utilizando la alternativa contexto de la union de tipos de datos. Entonces llama a declara_ variable para a adir una nueva variable a la lista. Una vez que nalice la primera accin, la n o sentencia inmersa en stmt puede ser analizada. Note que la accin en mitad de la regla es la o componente n mero 5, as que stmt es la componente n mero 6. u u Despus de que la sentencia inmersa se analice, su valor semntico se convierte en el valor de toda e a la sentencia let. Entonces el valor semntico de la accin del principio se utiliza para recuperar la a o lista anterior de variables. Esto hace quitar la variable temporal del let de la lista de manera que esta no parecer que exista mientras el resto del programa se analiza. a Tomar una accin antes de que la regla sea reconocida completamente a veces induce a conictos o ya que el analizador debe llegar a un anlisis para poder ejecutar la accin. Por ejemplo, las dos a o reglas siguientes, sin acciones en medio de ellas, pueden coexistir en un analizador funcional porque el analizador puede desplazar el token de llave-abrir y ver qu sigue antes de decidir si hay o no e una declaracin: o compuesta: { declaracion sentencias } | { sentencias } ; Pero cuando a adimos una accin en medio de una regla como a continuacin, la regla se vuelve n o o no funcional: compuesta: { prepararse_para_variables_locales (); } { declaraciones sentencias } | { sentencias } ;

54

Bison 1.27

Ahora el analizador se ve forzado a decidir si ejecuta la accin en medio de la regla cuando no o ha le ms alla de la llave-abrir. En otras palabras, debe decidir si utilia una regla u otra, sin do a informacin suciente para hacerlo correctamente. (El token llave-abrir es lo que se llama el token o de preanlisis en este momento, ya que el analizador est decidiendo a n qu hacer con l. Ver a a u e e Seccion 5.1 [Tokens de Preanlisis], pgina 69.) a a Podr pensar que puede corregir el problema poniendo acciones idnticas en las dos reglas, as a e : compuesta: { prepararse_para_variables_locales (); } { declaraciones sentencias } | { prepararse_para_variables_locales (); } { sentencias } ; Pero esto no ayuda, porque Bison no se da cuenta de que las dos acciones son idnticas. (Bison e nunca intenta comprender el cdigo C de una accin.) o o Si la gramtica es tal que una declaracin puede ser distinguida de una sentencia por el primer a o token (lo que es cierto en C), entonces una solucin que funciona es poner la accin despus de la o o e llave-abrir, as : compuesta: { { prepararse_para_variables_locales (); } declaraciones sentencias } | { sentencias } ; Ahora el primer token de la siguiente declaracin o sentencia, que en cualquier caso dir a Bison o a la regla a utilizar, puede hacerlo a n. u Otra solucin es introducir la accin dentro de un s o o mbolo no terminal que sirva como una subrutina: subrutina: /* vaco */ { prepararse_para_variables_locales (); } ; compuesta: subrutina { declaraciones sentencias } | subrutina { sentencias } ; Ahora Bison puede ejecutar la accin en la regla para subrutina sin decidir qu regla utilzar o e a nalmente para compuesta. Note que la accin est ahora al nal de su regla. Cualquier accin en o a o medio de una regla puede convertirse en una accin al nal de la regla de esta manera, y esto es lo o que Bison realmente hace para implementar acciones en mitad de una regla.

Capitulo 3: Archivos de Gramtica de Bison a

55

3.6 Declaraciones de Bison


La seccin de declaraciones de Bison de una gramtica de Bison dene los s o a mbolos utilizados en la formulacin de la gramtica y los tipos de datos de los valores semnticos. Ver Seccion 3.2 o a a [Simbolos], pgina 46. a Todos los nombres de tipos de tokens (pero no los tokens de caracter literal simple tal como + y *) se deben declarar. Los s mbolos no terminales deben ser declarados si necesita especicar el tipo de dato a utilizar para los valores semnticos (ver Seccion 3.5.2 [Ms de Un Tipo de Valor], a a pgina 50). a La primera regla en el chero tambin especica el s e mbolo de arranque, por defecto. Si desea que otro s mbolo sea el s mbolo de arranque, lo debe declarar expl citamente (ver Seccion 1.1 [Lenguajes y Gramticas Independientes del Contexto], pgina 23). a a

3.6.1 Nombres de Tipo de Token


La forma bsica de declarar un nombre de tipo de token (s a mbolo terminal) es como sigue: %token nombre Bison convertir esto es una directiva #define en el analizador, as que la funcin yylex (si est a o a en este chero) puede utilizar el nombre nombre para representar el cdigo de este tipo de token. o De forma alternativa, puede utilizar %left, %right, o %nonassoc en lugar de %token, si desea especicar la precedencia. Ver Seccion 3.6.2 [Precedencia de Operadores], pgina 56. a Puede especicar expl citamente el cdigo numrico para un token a adiendo un valor entero o e n en el campo que sigue inmediatamente al nombre del token: %token NUM 300 Es generalmente lo mejor, sin embargo, permitir a Bison elegir los cdigos numricos para todos o e los tipos de tokens. Bison automticamente seleccionar los cdigos que no provoquen conictos a a o unos con otros o con caracteres ASCII. En el caso de que el tipo de la pila sea una union, debe aumentar %token u otra declaracin de o tokens para incluir la opcin de tipo de datos delimitado por angulos (ver Seccion 3.5.2 [Ms de o a Un Tipo de Valor], pgina 50). a Por ejemplo: %union { double val; symrec *tptr; } %token <val> NUM /* define el tipo de la pila */

/* define el token NUM y su tipo */

56

Bison 1.27

Puede asociar un token de cadena literal con un nombre de tipo de token escribiendo la cadena literal al nal de la declaracin %type que declare el nombre. Por ejemplo: o %token arrow "=>" Por ejemplo, una gramtica para el lenguaje C podr especicar estos nombres con los tokens de a a cadena literal equivalente: %token <operator> %token <operator> %left OR "<=" OR LE 134 "||" "<="

Una vez que iguale la cadena literal y el nombre del token, puede utilizarlo indistintamente en ulteriores declaraciones en reglas gramaticales. La funcin yylex puede utilizar el nombre del o token o la cadena literal para obtener el n mero de cdigo del tipo de token (ver Seccion 4.2.1 u o [Convenciones de Llamada], pgina 61). a

3.6.2 Precedencia de Operadores


Use las declaraciones %left, %right o %nonassoc para declarar un token y especicar su precedencia y asociatividad, todo a la vez. Estas se llaman declaraciones de precedencia. Ver Seccion 5.3 [Precedencia de Operadores], pgina 72, para informacin general a cerca de la precedencia de opea o radores. La sintaxis de una declaracin de precedencia es la misma que la de %token: bien o %left s mbolos. . . o %left <tipo> s mbolos. . . Y realmente cualquiera de estas declaraciones sirve para los mismos propsitos que %token. o Pero adems, estos especican la asociatividad y precedencia relativa para todos los s a mbolos: La asociatividad de un operador op determina cmo se anidan los repetidos usos de un opeo rador: si x op y op z se analiza agrupando x con y primero o agrupando y con z primero. %left especica asociatividad por la izquierda (agrupando x con y primero) y %right especica asociatividad por la derecha (agrupando y con z primero). %nonassoc especica no asociatividad, que signica que x op y op z se considera como un error de sintaxis. La precedencia de un operador determina cmo se anida con otros operadores. Todos los o tokens declarados en una sola declaracin de precedencia tienen la misma precedencia y se o anidan conjuntamente de acuerdo a su asociatividad. Cuando dos tokens declarados asocian declaraciones de diferente precedencia, la ultima en ser declarada tiene la mayor precedencia y es agrupada en primer lugar.

Capitulo 3: Archivos de Gramtica de Bison a

57

3.6.3 La Coleccin de Tipos de Valores o


La declaracin %union especica la coleccin completa de posibles tipos de datos para los valores o o semnticos. La palabra clave %union viene seguida de un par de llaves conteniendo lo mismo que a va dentro de una union en C. Por ejemplo: %union { double val; symrec *tptr; } Esto dice que los dos tipos de alternativas son double y symrec *. Se les ha dado los nombres val y tptr; estos nombres se utilizan en las declaraciones de %token y %type para tomar uno de estos tipos para un s mbolo terminal o no terminal (ver Seccion 3.6.4 [S mbolos No Terminales], pgina 57). a Note que, a diferencia de hacer una declaracin de una union en C, no se escribe un punto y o coma despus de la llave que cierra. e

3.6.4 S mbolos No Terminales


Cuando utilice %union para especicar varios tipos de valores, debe declarar el tipo de valor de cada s mbolo no terminal para los valores que se utilicen. Esto se hace con una declaracin %type, o como esta: %type <tipo> noterminal. . . Aqu noterminal es el nombre de un s mbolo no terminal, y tipo es el nombre dado en la %union a la alternativa que desee (ver Seccion 3.6.3 [La Coleccin de Tipos de Valor], pgina 57). Puede o a dar cualquier n mero de s u mbolos no terminales en la misma declaracin %type, si tienen el mismo o tipo de valor. Utilice espacios para separar los nombres de los s mbolos. Puede tambin declarar el tipo de valor de un s e mbolo terminal. Para hacer esto, utilice la misma construccin <tipo> en una declaracin para el s o o mbolo terminal. Todos las clases de declaraciones de tipos permiten <tipo>.

3.6.5 Suprimiendo Advertencias de Conictos


Bison normalmente avisa si hay alg n conicto en la gramtica (ver Seccion 5.2 [Conictos u a Desplazamiento/Reduccin], pgina 70), pero la mayor de las gramticas reales tienen conctos o a a a desplazamiento/reduccin inofensivos que se resuelven de una manera predecible y ser muy o an dif ciles de eliminar. Es deseable suprimir los avisos a cerca de estos conictos a menos que el n mero de conictos cambie. Puede hacer esto con la declaracin %expect. u o La declaracin tiene este aspecto: o

58

Bison 1.27

%expect n Aqu n es un entero decimal. La declaracin dice que no deben haber avisos si hay n conictos o de desplazamiento/reduccin y ning n conicto reduccin/reduccin. Los avisos usuales se dan si o u o o hay ms o menos conictos, o si hay alg n conicto reduccin/reduccin. a u o o En general, el uso de %expect implica estos pasos: Compilar su gramtica sin %expect. Utilice la opcin -v para obtener una lista amplia de a o dnde ocurrieron los conictos. Bison tambin imprimir el n mero de conictos. o e a u Comprobar cada uno de los conictos para estar seguro de que la resolucin por defecto de o Bison es lo que realmente quiere. Si no, reescriba la gramtica y vuelva al principio. a A ada una declaracin %expect, copiando el n mero n a partir del n mero que imprime Bison. n o u u Ahora Bison dejar de molestarle con los conictos que ha comprobado, pero le avisar de nuevo a a si cambia el resultado de la gramtica con conictos adicionales. a

3.6.6 El S mbolo de Arranque


Bison asume por defecto que el s mbolo de arranque para la gramtica es el primer no terminal a que se encuentra en la seccin de especicacin de la gramtica. El programador podr anular o o a a esta restriccin con la declaracin %start as o o : %start s mbolo

3.6.7 Un Analizador Puro (Reentrante)


Un programa reentrante es aquel que no cambia en el curso de la ejecucin; en otras palabras, o consiste enteramente de cdigo puro (de slo lectura). La reentrancia es importante siempre que o o la ejecucin as o ncrona sea posible; por ejemplo, un programa no reentrante podr no ser seguro al a ser llamado desde un gestor de se ales. En sistemas con m ltiples hilos de control, un programa n u no reentrante debe ser llamado unicamente dentro de interbloqueos. Normalmente, Bison genera un analizador que no es reentrante. Esto es apropiado para la mayoria de los casos, y permite la compatibilidad con YACC. (Los interfaces estandares de YACC son inherentemente no reentrantes, porque utilizan variables asignadas estticamente para la comunia cacin con yylex, incluyendo yylval y yylloc.) o Por otra parte, puede generar un analizador puro, reentrante. La declaracin de Bison %pure_ o parser dice que desea que el analizador sea reentrante. Esta aparece as : %pure_parser El resultado es que las variables de comunicacin yylval y yylloc se convierten en variables o locales en yyparse, y se utiliza una convencin de llamada diferente para la funcin del analizador o o lxico yylex. Ver Seccion 4.2.4 [Convenciones de Llamada para Analizadores Puros], pgina 64, e a para los detalles a cerca de esto. La variable yynerrs tambin se convierte en local en yyparse (ver e

Capitulo 3: Archivos de Gramtica de Bison a

59

Seccion 4.3 [La Funcin de Informe de Errores yyerror], pgina 65). La convencin para llamar a o a o yyparse no cambia. Que el analizador sea o no puro no depende de las reglas gramaticales. Puede generar indistintamente un analizador puro o un analizador no reentrante a partir de cualquier gramtica vlida. a a

3.6.8 Sumario de Declaraciones de Bison


Aqu hay un sumario de todas las declaraciones de Bison: %union %token %right %left %nonassoc Declara un s mbolo terminal (nombre de tipo de token) que es no asociativo (utilizndolo de una forma que ser asociativo es un error de sintaxis) (ver Seccion 3.6.2 a a [Precedencia de Operadores], pgina 56). a %type %start %expect Declara el tipo de valor semntico para un s a mbolo no terminal. (ver Seccion 3.6.4 [S mbolos No Terminales], pgina 57). a Especica el s mbolo de arranque de la gramtica (ver Seccion 3.6.6 [El S a mbolo de Arranque], pgina 58). a Declara el n mero esperado de conictos desplazamiento-reduccin (ver Seccion 3.6.5 u o [Suprimiendo Advertencias de Conictos], pgina 57). a Declara la coleccin de tipos de datos que los valores semnticos pueden poseer (ver o a Seccion 3.6.3 [La Coleccin de Tipos de Valores], pgina 57). o a Declara un s mbolo terminal (nombre de tipo de token) sin precedencia o asociatividad especicada (ver Seccion 3.6.1 [Nombres de Tipo de Token], pgina 55). a Declara un s mbolo terminal (nombre de tipo de token) que es asociativo por la derecha (ver Seccion 3.6.2 [Precedencia de Operadores], pgina 56). a Declara un s mbolo terminal (nombre de tipo de token) que es asociativo por la izquierda. (ver Seccion 3.6.2 [Precedencia de Operadores], pgina 56). a

%pure_parser Solicita un programa de anlisis puro (reentrante) (ver Seccion 3.6.7 [Un Analizador a Puro (Reentrante)], pgina 58). a %no_lines No genera ning n comando #line del proprocesador en el chero del analizador. Noru malmente Bison escribe estos comandos en el archivo del analizador de manera que el compilador de C y los depuradores asociarn los errores y el cdigo objeto con su a o archivo fuente (el archivo de la gramtica). Esta directiva provoca que asocien los a errores con el archivo del analizador, tratndolo como un archivo fuente independiente a por derecho propio. %raw El archivo de salida nombre.h normalmente dene los tokens con los n meros de token u compatible con Yacc. Si se especica esta opcin, se utilizarn los n meros internos de o a u Bison en su lugar. (Los n meros compatibles con Yacc comienzan en 257 excepto para u los tokens de caracter simple; Bison asigna n meros de token secuencialmente para u todos los tokens comenzando por 3.)

%token_table Genera un array de nombres de tokens en el archivo del analizador. El nombre del array es yytname; yytname[i] es el nombre del token cuyo n mero de cdigo de tou o ken interno de Bison es i. Los primeros tres elementos de yytname son siempre "$",

60

Bison 1.27

"error", e "$illegal"; despus de estos vienen los s e mbolos denidos en el archivo de la gramtica. a Para tokens de caracter literal y tokens de cadena literal, el nombre en la tabla incluye los caracteres entre comillas simples o dobles: por ejemplo, "+" es un literal de caracter simple y "\"<=\"" es un token de cadena literal. Todos los caracteres del token de cadena literal aparecen textualmente en la cadena encontrada en la tabla; incluso los caracteres de comillas-dobles no son traducidos. Por ejemplo, si el token consiste de tres caracteres *"*, su cadena en yytname contiene "*"*". (En C, eso se escribir como "\"*\"*\""). a Cuando especique %token_table, Bison tambin generar deniciones para las macros e a YYNTOKENS, YYNNTS, y YYNRULES y YYNSTATES; YYNTOKENS El n mero de token ms alto, ms uno. u a a YYNNTS YYNRULES YYNSTATES El n mero de estados del analizador (ver Seccion 5.5 [Estados del Analizau dor], pgina 74). a El n mero de s u mbolos no terminales. El n mero de reglas gramaticales, u

3.7 M ltiples Analizadores en el Mismo Programa u


La mayor de los programa que usan Bison analizan slo un lenguaje y por lo tanto contiea o nen slo un analizador de Bison. Pero , qu pasa si desea analizar ms de un lenguaje con el o e a mismo programa? Entonces necesita evitar un conicto de nombres entre diferentes deniciones de yyparse, yylval, etc. La manera ms fcil de hacer esto es utilizar la opcin -p prejo (ver Capitulo 9 [Invocando a a o a Bison], pgina 89). Esta renombra las funciones de interfaz y variables del analizador de Bison a para comenzar con prejo en lugar de yy. Puede utilizarlo para darle a cada analizador nombres diferentes que no provoquen conicto. La lista precisa de s mbolos renombrados es yyparse, yylex, yyerror, yynerrs, yylval, yychar e yydebug. Por ejemplo, si utiliza -p c, los nombres se convierten em cparse, clex, etc. El resto de las variables y macros asociadas con Bison no se renombran. Estas otras no son globales. Por ejemplo, YYSTYPE no se renombra, pero denirla de diferente forma en analizadores diferentes no provoca confusin (ver Seccion 3.5.1 [Tipos de Datos para Valores Semnticos], o a pgina 50). a La opcin -p funciona a adiendo deniciones de macros al comienzo del archivo fuente del o n analizador, deniendo yyparse como prejoparse, etc. Esto sustituye efectivamente un nombre por el otro en todo el chero del analizador.

Capitulo 4: Interfaz del Analizador en Lenguaje C

61

4 Interfaz del Analizador en Lenguaje C


El analizador de Bison es en realidad una funcin en C llamada yyparse. Aqu describimos las o convenciones de interfaz de yyparse y las otras funciones que ste necesita usar. e Tenga en cuenta que el analizador utiliza muchos identicadores en C comenzando con yy e YY para propsito interno. Si utiliza tales identicadores (a parte de aquellos en este manual) en o una accin o en codigo C adicional en el archivo de la gramtica, es probable que se encuentre con o a problemas.

4.1 La Funcin del Analizador yyparse o


Se llama a la funcin yyparse para hacer que el anlisis comience. Esta funcin lee tokens, o a o ejecuta acciones, y por ultimo retorna cuando se encuentre con el nal del chero o un error de sintaxis del que no puede recuperarse. Usted puede tambin escribir acciones que ordenen a yyparse e retornar inmediatamente sin leer ms all. a a El valor devuelto por yyparse es 0 si el anlisis tuvo xito (el retorno se debe al nal del chero). a e El valor es 1 si el anlisis fall (el retorno es debido a un error de sintaxis). a o En una accin, puede provocar el retorno inmediato de yyparse utilizando estas macros: o YYACCEPT YYABORT Retorna inmediatamente con el valor 0 (para indicar xito). e Retorna inmediatamente con el valor 1 (para indicar fallo).

4.2 La Funcion del Analizador Lxico yylex e


La funcin del analizador lxico, yylex, reconoce tokens desde el ujo de entrada y se los devuelve o e al analizador. Bison no crea esta funcin automticamente; usted debe escribirla de manera que o a yyparse pueda llamarla. A veces se hace referencia a la funcin como el scanner lxico. o e En programas simples, yylex se dene a menudo al nal del archivo de la gramtica de Bison. a Si yylex se dene en un archivo fuente por separado, necesitar que las deniciones de las macros a de tipos de tokens estn disponibles ah Para hecer esto, utilice la opcin -d cuando ejecute e . o Bison, de manera que ste escribir esas deniciones de macros en un archivo de cabecera por e a separado nombre.tab.h que puede incluir en otros cheros fuente que lo necesiten. Ver Capitulo 9 [Invocando a Bison], pgina 89. a

4.2.1 Convencin de Llamada para yylex o


El valor que yylex devuelve debe ser un cdigo numrico para el tipo de token que se ha o e encontrado, o 0 para el nal de la entrada. Cuando se hace referencia a un token en las reglas gramaticales con un nombre, ese nombre en el archivo del analizador se convierte en una macro de C cuya denicin es el valor numrico o e

62

Bison 1.27

apropiado para ese tipo de token. De esta manera yylex puede utilizar el nombre para indicar ese tipo. Ver Seccion 3.2 [Simbolos], pgina 46. a Cuando se hace referencia a un token en las reglas gramaticales por un caracter literal, el cdigo o numrico para ese caracter tambin es el cdigo para el tipo de token. As yylex puede simplemente e e o devolver ese cdigo de caracer. El caracter nulo no debe utilizarse de esta manera, porque su cdigo o o es el cero y eso es lo que simboliza el nal de la entrada. Aqu hay un ejemplo mostrando estas cosas: yylex () { ... if (c == EOF) /* Detecta el fin de fichero. */ return 0; ... if (c == + || c == -) return c; /* Asume que el tipo de token para + es +. */ ... return INT; /* Devuelve el tipo del token. */ ... } Este interfaz se ha dise ado para que la salida de la utilidad lex pueda utilizarse sin cambios como n denicin de yylex. o Si la gramtica utiliza tokens de cadena literal, hay dos maneras por las que yylex puede a determianr los cdigos de tipo de token para estos: o Si la gramtica dene nombres de token simblicos como alias para los tokens de cadena literal, a o yylex puede utilizar estos nombres simblicos como los dems. En este caso, el uso de tokens o a de cadena literal en el archivo de la gramtica no tiene efecto sobre yylex. a yylex puede encontrar el token multi-caracter en la tabla yytname. El ndice del token en la tabla es el cdigo del tipo de token. El nombre de un token multi-caracter se almacena en o yytname con una comilla doble, los caracteres del token, y otra comilla doble. Los caracteres del token no son traducidos de ninguna forma; ellos aparecen textualmente en el contenido de la cadena dentro de la tabla. Aqu est el cdigo para localizar un token en yytname, asumiendo que los caracteres del token a o se almacenan en token_buffer. for (i = 0; i < YYNTOKENS; i++) { if (yytname[i] != 0 && yytname[i][0] == " && strncmp (yytname[i] + 1, token_buffer, strlen (token_buffer)) && yytname[i][strlen (token_buffer) + 1] == " && yytname[i][strlen (token_buffer) + 2] == 0) break; }

Capitulo 4: Interfaz del Analizador en Lenguaje C

63

La tabla yytname se genera slo si se utiliza la declaracin %token_table. Ver Seccion 3.6.8 o o [Sumario de Decls.], pgina 59. a

4.2.2 Valores Semnticos de los Tokens a


En un analizador ordinario (no reentrante), los valores semnticos del token deben almacenarse a en la variable global yylval. Cuando est usando un solo tipo de valores semnticos, yylval tiene e a ese tipo. As si el tipo es int (por defecto), podr escribir esto en yylex: , a ... yylval = valor; return INT; ...

/* Pone valor en la pila de Bison. */ /* Devuelve el tipo del token. */

Cuando est utilizando varios tipos de datos, el tipo de yylval es una union compuesta a e partir de la declaracin %union (ver Seccion 3.6.3 [La Coleccion de Tipos de Valores], pgina 57). o a As cuando almacene un valor de token, debe utilizar el miembro apropiado de la union. Si la declaracin %union tiene el siguiente aspecto: o %union { int intval; double val; symrec *tptr; } entonces el cdigo en yylex podr ser as o a : ... yylval.intval = valor; /* Pone el valor en la pila de Bison. */ return INT; /* Devuelve el tipo del token. */ ...

4.2.3 Posiciones en el Texto de los Tokens


Si est usando la propiedad @n (ver Seccion 4.4 [Propiedades Especiales para su Uso en Aca ciones], pgina 66) en acciones para seguir la pista de las posiciones en el texto de los tokens y a agrupaciones, entonces debe proveer esta informacin en yylex. La funcin yyparse espera encono o trar la posicin en el texto de un token que se acaba de analizar en la variable global yylloc. Por o ello yylex debe almacenar el dato apropiado en esa variable. El valor de yylloc es una estructura y solo tiene que inicializar los miembros que vayan a ser utilizados por las acciones. Los cuatro miembros se denominan first_line, first_column, last_line y last_column 1. Note que el uso de estas caracter sticas hacen al analizador notablemente ms lento. a El tipo de dato de yylloc tiene el nombre YYLTYPE.
1

primera l nea, primera columna, ultima l nea y ultima columna respectivamente

64

Bison 1.27

4.2.4 Convenciones de Llamada para Analizadores Puros


Cuando utilice la declaracin %pure_parser para solicitar un analizador puro, reentrante, las o variables globales de comunicacin yylval y yylloc no pueden usarse. (Ver Seccion 3.6.7 [Un o Analizador Puro (Reentrante)], pgina 58.) En tales analizadores las dos variables globales se a reemplazan por punteros pasados como parmetros a yylex. Debe declararlos como se muestra a aqu y pasar la informacin de nuevo almacenndola a travs de esos punteros. , o a e yylex (lvalp, llocp) YYSTYPE *lvalp; YYLTYPE *llocp; { ... *lvalp = valor; /* Pone el valor en la pila de Bison. return INT; /* Devolver el tipo del token. */ ... }

*/

Si el archivo de la gramtica no utiliza la construccin @ para hacer referencia a las posiciones a o del texto, entonces el tipo YYLTYPE no ser denido. En este caso, omitir el segundo argumento; a yylex ser llamado con solo un argumento. a Si utiliza un analizador reentrante, puede opcionalmente pasar informacin de parmetros adio a cional de forma reentrante. Para hacerlo, dena la macro YYPARSE_PARAM como un nombre de variable. Esto modica la funcin yyparse para que acepte un argumento, de tipo void *, con ese o nombre. Cuando llame a yyparse, pase la direccin de un objeto, haciendo una conversin de tipos de o o la direccin a void *. Las acciones gramaticales pueden hacer referencia al contenido del objeto o haciendo una conversin del valor del puntero a su tipo apropiado y entonces derreferencindolo. o a Aqu hay un ejemplo. Escriba esto en el analizador: %{ struct parser_control { int nastiness; int randomness; }; #define YYPARSE_PARAM parm %} Entonces llame al analizador de esta manera: struct parser_control { int nastiness; int randomness; };

Capitulo 4: Interfaz del Analizador en Lenguaje C

65

... { struct parser_control foo; . . . /* Almacena los datos apropiados en foo. value = yyparse ((void *) &foo); ... } En las acciones gramaticales, utilice expresiones como sta para hacer referencia a los datos: e ((struct parser_control *) parm)->randomness Si desea pasar los datos de parmetros adicionales a yylex, dena la macro YYLEX_PARAM como a YYPARSE_PARAM, tal como se muestra aqu : %{ struct parser_control { int nastiness; int randomness; }; #define YYPARSE_PARAM parm #define YYLEX_PARAM parm %} Deber entonces denir yylex para que acepte un argumento adicionalel valor de parm. (Este a hace uno o tres argumentos en total, dependiendo de si se le pasa un argumento de tipo YYLTYPE.) Puede declarar el argumento como un puntero al tipo de objeto apropiado, o puede declararlo como void * y acceder al contenido como se mostr antes. o Puede utilizar %pure_parser para solicitar un analizador reentrante sin usar tambin YYPARSE_ e PARAM. Entonces deber llamar a yyparse sin argumentos, como es usual. a */

4.3 La Funcin de Informe de Errores yyerror o


El analizador de Bison detecta un error de anlisis o error de sintaxis siempre que lea un toa ken que no puede satisfacer ninguna regla sintctica. Una accin en la gramtica puede tambin a o a e expl citamente declarar un error, utilizando la macro YYERROR (ver Seccion 4.4 [Propiedades Especiales para su Uso en Acciones], pgina 66). a El analizador de Bison espera advertir del error llamando a una funcin de informe de errores o denominada yyerror, que se debe proveer. Esta es llamada por yyparse siempre que encuentre un error sintctico, y sta recibe un argumento. Para un error de anlisis, la cadena normalmente a e a es "parse error". Si dene la macro YYERROR_VERBOSE en la seccin de declaraciones de Bison (ver Seccion 3.1.2 o [La Seccin de Declaraciones de Bison], pgina 45), entonces Bison facilita una cadena de mensaje o a

66

Bison 1.27

de error mas locuaz y espec ca que el simple "parse error". No importa qu deniciones utilice e para YYERROR_VERBOSE, si ya lo dene. El analizador puede detectar otro tipo de error: desbordamiento de pila. Esto sucede cuando la entrada contiene construcciones que son profundamente anidadas. No parece que vaya a encontrarse con esto, ya que el analizador de Bison extiende su pila automticamente hasta un l a mite muy largo. Pero si el desbordamiento sucede, yyparse llama a yyerror de la manera usual, excepto que la cadena del argumento es "parser stack overflow". La siguiente denicin es suciente para programas simples: o yyerror (s) char *s; { fprintf (stderr, "%s\n", s); } Despus yyerror retorna a yyparse, este ultimo intentar la recuperacin de errores si ha e a o escrito reglas gramaticales de recuperacin de errores apropiadas (ver Capitulo 6 [Recuperacion de o Errores], pgina 81). Si la recuperacin es imposible, yyparse devolver inmediatamente un 1. a o a La variable yynerrs contiene el n mero de errores sintcticos hasta ahora. Normalmente esta u a variable es global; pero si solicita un analizador puro (ver Seccion 3.6.7 [Un Analizador Puro (Reentrante)], pgina 58) entonces es una variable local a la que slo las acciones pueden acceder. a o

4.4 Propiedades Especiales para su Uso en Acciones


Aqu hay una tabla de construcciones, variables y macros que son utiles en las acciones. $$ $n Act a como una variable que contiene el valor semntico para la agrupacin construida u a o por la regla actual. Ver Seccion 3.5.3 [Acciones], pgina 50. a Act a como una variable que contiene el valor semntico para la componente n-sima u a e de la regla actual. Ver Seccion 3.5.3 [Acciones], pgina 50. a

$<alttipo>$ Como $$ pero especica la alternativa alttipo en la union especicada por la declaracin o %union. Ver Seccion 3.5.4 [Tipos de Datos de los Valores en Acciones], pgina 52. a $<alttipo>n Como $n pero especica la alternativa alttipo en la union especicada por la declaracin o %union. Ver Seccion 3.5.4 [Tipos de Datos de Valores en Acciones], pgina 52. a YYABORT; Retorna inmediatamente desde yyparse, indicando fallo. Ver Seccion 4.1 [La Funcin o del Analizador yyparse], pgina 61. a YYACCEPT; Retorna inmediatamente desde yyparse, indicando xito. Ver Seccion 4.1 [La Funcin e o del Analizador yyparse], pgina 61. a YYBACKUP (token, valor); Deshace el desplazamiento de un token. Esta macro se permite unicamente para reglas que reducen un valor sencillo, y slo donde no hay un token de preanlisis. Esta inserta o a

Capitulo 4: Interfaz del Analizador en Lenguaje C

67

un token de preanlisis con un tipo de token token y valor semntico valor; entonces a a se descarta el valor que iba a ser reducido por esta regla. Si la macro se utiliza cuando no es vlida, tal como cuando ya hay un token de a preanlisis, entonces se produce un error de sintaxis con el mensaje cannot back up a y realiza la recuperacin de errores ordinaria. o En cualquier caso, el resto de la accin no se ejecuta. o YYEMPTY YYERROR; Produce un error de sintaxis inmediatamente. Esta sentencia inicia la recuperacin o de errores como si el analizador hubiese detectado un error; sin embargo, no se llama a yyerror, y no imprime ning n mensaje. Si quiere que imprima un mensaje de u error, llame a yyerror expl citamente antes de la sentencia YYERROR. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a YYRECOVERING Esta macro representa una expresin que tiene el valor 1 cuando el analizador se est o a recuperando de un error de sintaxis, y 0 durante el resto del tiempo. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a yychar Variable que contiene el token actual de preanlisis. (En un analizador puro, esto a es realmente una variable local dentro de yyparse.) Cuando no hay un token de preanlisis, el valor de YYEMPTY se almacena en la variable. Ver Seccion 5.1 [Tokens de a Preanlisis], pgina 69. a a El valor almacenado en yychar cuando no hay un token de preanlisis. a

yyclearin; Descarta el token actual de preanlisis. Esto es util principalmente en las reglas de a error. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a yyerrok; Deja de generar mensajes de error inmediatamente para los errores de sintaxis subsecuentes. Esto es util principalmente en las reglas de error. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a @n Act a como una variable estructurada conteniendo informacin de los n meros de l u o u nea y columna de la componente n-sima de la regla actual. La estructura tiene cuatro e miembros, as : struct { int first_line, last_line; int first_column, last_column; }; De esta manera, para obtener el n mero de l u nea de comienzo del tercer componente, utilizar @3.first_line. a Para que los miembros de esta estructura contengan informacin vlida, debe hacer que o a yylex facilite esta informacin para cada token. Si solo necesita de ciertos miembros, o entonces yylex necesita unicamente rellenar esos miembros. El uso de esta caracter stica hace al analizador notablemente ms lento. a

68

Bison 1.27

Capitulo 5: El Algoritmo del Analizador de Bison

69

5 El Algoritmo del Analizador de Bison


A medida que Bison lee tokens, los va insertando en una pila junto con su valor semntico. La pila a se denomina pila del analizador. El insertar un token tradicionalmente se denomina desplazamiento. Por ejemplo, suponga que la calculadora inja ha le 1 + 5 *, con un 3 por venir. La pila do contendr cuatro elementos, uno para cada token que fue desplazado. a Pero la pila no siempre contiene un elemento para cada token le do. Cuando los ultimos n tokens y agrupaciones desplazadas concuerden con los componentes de una regla gramatical, estos pueden combinarse de acuerdo a esa regla. A esto se le denomina reduccin. Esos tokens y agrupaciones o se reemplazan en la pila por una sola agrupacin cuyo s o mbolo es el resultado (lado izquierdo) de esa regla. La ejecucin de la accin de la regla es parte del proceso de reduccin, porque sta es la o o o e que computa el valor semntico de la agrupacin resultante. a o Por ejemplo, si el analizador de la calculadora inja contiene esto: 1 + 5 * 3 y el siguiente token de entrada es un caracter de nueva l nea, entonces los tres ultimos elementos pueden reducirse a 15 mediante la regla: expr: expr * expr; Entonces la pila contiene exactamente estos tres elementos: 1 + 15 En este punto, se puede realizar otra reduccin, resultando en el valor 16. Entonces el token de o nueva l nea se puede desplazar. El analizador intenta, mediante desplazamientos y reducciones, reducir la entrada completa a una sola agrupacin cuyo s o mbolo es el s mbolo de arranque de la gramtica (ver Seccion 1.1 a [Lenguajes y Gramticas Independientes del Contexto], pgina 23). a a Este tipo de analizador se conoce en la literatura como analizador ascendente.

5.1 Tokens de Preanlisis a


El analizador de Bison no siempre reduce inmediatamente tan pronto como los ultimos n tokens y agrupaciones se correspondan con una regla. Esto es debido a que es inadecuada una estrategia tan simple para manejar la mayor de los lenguajes. En su lugar, cuando es posible una reduccin, a o el analizador algunas veces mira hacia delante al prximo token para decidir qu hacer. o e Cuando se lee un token, este no se desplaza inmediatamente; primero se convierte en el token de preanlisis, que no se pone sobre la pila. Ahora el analizador puede realizar una o ms reducciones a a de tokens y agrupaciones sobre la pila, mientras que el token de preanlisis se mantiene fuera a un a

70

Bison 1.27

lado. Esto no signica que se han realizado todas las posibles reducciones; dependiendo del tipo de token del token de preanlisis, algunas reglas podr escoger retrasar su aplicacin. a an o Aqu hay un caso simple donde se necesita el token de preanlisis. Estas tres reglas denen a expresiones que contienen operadores de suma binaria y operaciones factoriales unarios postjos (!), y se permiten los parntesis para agrupar. e expr: term + expr | term ; ( expr ) | term ! | NUMBER ;

term:

Suponga que se ha le el token 1 + 2 y ha sido desplazado; qu deber hacerse? Si el do e a prximo token es ), entonces los primeros tres tokens deber reducirse para formar una expr. o an Este es el unico camino vlido, porque el desplazamiento de ) producir una secuencia de s a a mbolos term ), y ninguna regla lo permite. Si el siguiente token es !, entonces debe ser desplazado inmediatamente de manera que 2 ! se pueda reducir para hacer un term. Si en su lugar el analizador fuera a reducir antes de desplazar, 1 + 2 se convertir en una expr. Ser entonces imposible desplazar el ! porque hacindolo a a e producir en la pila la secuencia de s a mbolos expr !. Ninguna regla permite esa secuencia. El token de preanlisi actual se almacena en la variable yychar. Ver Seccion 4.4 [Propiedades a Especiales para su Uso en Acciones], pgina 66. a

5.2 Conictos de Desplazamiento/Reduccin o


Suponga que estamos analizando un lenguaje que tiene las sentencias if-then y if-then-else, con un par de reglas como estas: if_stmt: IF expr THEN stmt | IF expr THEN stmt ELSE stmt ; Aqu asumimos que IF, THEN y ELSE son s mbolos terminales de tokens para palabras clave espec cas. Cuando se lea el token ELSE y se convierta en el token de preanlisis, el contenido de la pila a (asumiendo que la entrada es vlida) est listo para una reduccin por la primera regla. Pero a a o tambin es leg e timo desplazar el ELSE, porque eso conllevar a una reducin provisional por la a o segunda regla. Esta situacin, donde ser vlido un desplazamiento o una reduccin, se denomina un conicto o a a o desplazamiento/reduccin. Bison est dise ado para resolver estos conictos eligiendo el desplazao a n

Capitulo 5: El Algoritmo del Analizador de Bison

71

miento, a menos que se le dirija con declaraciones de precedencia de operadores. Para ver la razn o de esto, vamos a contrastarlo con la otra alternativa. Ya que el analizador preere desplazar el ELSE, el resultado ser ligar la clusula else con la a a sentencia if ms interior, haciendo que estas dos entradas sean equivalentes: a if x then if y then gana (); else pierde; if x then do; if y then gana (); else pierde; end; Pero si el analizador escoge la reduccin cuando es posible en lugar de desplazar, el resultado o ser ligar la clusula else a la sentencia if ms exterior, haciendo que estas dos entradas sean a a a equivalentes: if x then if y then gana (); else pierde; if x then do; if y then gana (); end; else pierde; El conicto existe porque la gramtica escrita es ambigua: en todo caso el anlisis de la sentencia a a if simple anidada es leg tima. La convencin es que estas ambig edades se resuelvan emparejando la o u clusula else a la sentencia if ms interior; esto es lo que Bison consigue eligiendo el desplazamiento a a en vez de la reduccin. (Idealmente ser ms adecuado escribir una gramtica no ambigua, pero o a a a eso es muy duro de hacer en este caso.) Esta ambig edad en particular se encontr en primer lugar u o en la especicacin de Algol 60 y se denomin la ambiguedad del balanceado del else. o o Para evitar advertencias de Bison a cerca de los predecibles, leg timos conictos de desplazamiento/reduccin, utilice la declaracin %expect n. No se producirn avisos mientras el n mero de o o a u conictos de desplazamiento/reduccin sea exactamente n. Ver Seccion 3.6.5 [Suprimiendo Advero tencias de Conctos], pgina 57. a La denicin de if_stmt anterior es la unica que se va a quejar del conicto, pero el conicto o no aparecer en realidad sin reglas adicionales. Aqu hay un chero de entrada de Bison completo a que manesta realmente el conicto: %token IF THEN ELSE variable %% stmt: expr | if_stmt ; if_stmt: IF expr THEN stmt | IF expr THEN stmt ELSE stmt ; expr: ; variable

72

Bison 1.27

5.3 Precedencia de Operadores


Otra situacin en donde pararecen los conictos desplazamiento/reduccin es en las expresiones o o aritmticas. Aqu el desplazamiento no siempre es la resolucin preferible; las declaraciones de e o Bison para la precedencia de operadores le permite especicar cundo desplazar y cuando reducir. a

5.3.1 Cundo se Necesita la Precedencia a


Considere el siguiente fragmento de gramtica ambigua (ambigua porque la entrada 1 - 2 * 3 a puede analizarse de dos maneras): expr: expr - | expr * | expr < | ( expr ... ; expr expr expr )

Suponga que el analizador ha visto los tokens 1, - y 2; deber reducirlos por la regla del a operador de adicin? Esto depende del prximo token. Por supuesto, si el siguiente token es un ), o o debemos reducir; el desplazamiento no es vlido porque ninguna regla puede reducir la secuencia a de tokens - 2 ) o cualquier cosa que comience con eso. Pero si el prximo token es * o <, o tenemos que elegir: ya sea el desplazamiento o la reduccin permitir al analizador terminar, pero o a con resultados diferentes. Para decidir qu deber hacer Bison, debemos considerar los resultados. Si el siguiente token de e a operador op se desplaza, entonces este debe ser reducido primero para permitir otra oportunidad para reducir la suma. El resultado es (en efecto) 1 - (2 op 3). Por otro lado, si se reduce la resta antes del desplazamiento de op, el resultado es (1 - 2) op 3. Claramente, entonces, la eleccin o de desplazar o reducir depender de la precedencia relativa de los operadores - y op: * deber a a desplazarse primero, pero no <. Qu hay de una entrada tal como 1 - 2 - 5; deber ser esta (1 - 2) - 5 o deber ser e a a 1 - (2 - 5)? Para la mayor de los operadores preferimos la primera, que se denomina asociacin a o por la izquierda. La ultima alternativa, asociacin por la derecha, es deseable para operadores de o asignacin. La eleccin de la asociacin por la izquierda o la derecha es una cuestin de qu es lo o o o o e que el analizador elige si desplazar o reducir cuando la pila contenga 1 - 2 y el token de preanlisis a sea -: el desplazamiento produce asociatividad por la derecha.

5.3.2 Especicando Precedencia de Operadores


Bison le permite especicar estas opciones con las declaraciones de precedencia de operadores %left y %right. Cada una de tales declaraciones contiene una lista de tokens, que son los operadores cuya precedencia y asociatividad se est declarando. La declaracin %left hace que todos a o esos operadores sean asociativos por la izquierda y la declaracin %right los hace asociativos por o la derecha. Una tercera alternativa es %nonassoc, que declara que es un error de sintaxis encontrar el mismo operador dos veces en un la.

Capitulo 5: El Algoritmo del Analizador de Bison

73

La precedencia relativa de operadores diferentes se controla por el orden en el que son declarados. La primera declaracin %left o %right en el chero declara los operadores cuya precedencia es la o menor, la siguiente de tales declaraciones declara los operadores cuya precedencia es un poco ms a alta, etc.

5.3.3 Ejemplos de Precedencia


En nuestro ejemplo, quer amos las siguientes declaraciones: %left < %left - %left * En un ejemplo ms completo, que permita otros operadores tambin, los declarar a e amos en grupos de igual precedencia. Por ejemplo, + se declara junto con -: %left < > = NE LE GE %left + - %left * / (Aqu NE y el resto representan los operadores para distinto, etc. Asumimos que estos tokens son de ms de un caracter de largo y por lo tanto son representados por nombres, no por caracteres a literales.)

5.3.4 Cmo Funciona la Precedencia o


El primer efecto de las declaraciones de precedencia es la asignacin de niveles de precedencia o a los s mbolos terminales declarados. El segundo efecto es la asignacin de niveles de precedencia o a ciertas reglas: cada regla obtiene su precedencia del ultimo simbolo terminal mencionado en las componentes. (Tambin puede especicar expl e citamente la precedencia de una regla. Ver Seccion 5.4 [Precedencia Dependiente del Contexto], pgina 73.) a Finalmente, la resolucin de conictos funciona comparando la precendecia de la regla que est o a siendo considerada con la del token de preanlisis. Si la precedencia del token es ms alta, la a a eleccin es desplazar. Si la precedencia de la regla es ms alta, la eleccin es reducir. Si tienen la o a o misma precedencia, la eleccin se hace en base a la asociatividad de ese nivel de precedencia. El o archivo de salida amplia producido por -v (ver Capitulo 9 [Invocando a Bison], pgina 89) dice a cmo fue resuelto cada conicto. o No todas las reglas y no todos los tokens tienen precedencia. Si bien la regla o el token de preanlisis no tienen precedencia, entonces por defecto de desplaza. a

5.4 Precedencia Dependiente del Contexto


A menudo la precedencia de un operador depende del contexto. Esto suena raro al principio, pero realmente es muy com n. Por ejemplo, un signo menos t u picamente tiene una precedencia

74

Bison 1.27

muy alta como operador unario, y una precedencia algo menor (menor que la multiplicacin) como o operador binario. Las declaraciones de precedencia de Bison, %left, %right y %nonassoc, puede utilizarse unicamente para un token dado; de manera que un token tiene slo una precedencia declarada o de esta manera. Para la precedencia dependiente del contexto, necesita utilizar un mecanismo adicional: el modidor %prec para las reglas. El modicador %prec declara la precedencia de una regla en particular especicando un s mbolo terminal cuya precedencia debe utilizarse para esa regla. No es necesario por otro lado que ese s mbolo aparezca en la regla. La sintaxis del modicador es: %prec s mbolo-terminal y se escribe desp es de los componentes de la regla. Su efecto es asignar a la regla la precedencia u de s mbolo-terminal, imponindose a la precedencia que se deducir de forma ordinaria. La precee a dencia de la regla alterada afecta enconces a cmo se resuelven los conictos relacionados con esa o regla (ver Seccion 5.3 [Precedencia de Operadores], pgina 72). a Aqu est cmo %prec resuelve el problema del menos unario. Primero, declara una precedencia a o para un s mbolo terminal cticio llamada UMINUS. Aqu no hay tokens de este tipo, pero el s mbolo sirve para representar su precedencia: ... %left + - %left * %left UMINUS Ahora la precedencia de UMINUS se puede utilizar en reglas espec cas: exp: ... | exp - exp ... | - exp %prec UMINUS

5.5 Estados del Analizador


La funcin yyparse se implementa usando una mquina de estado nito. Los valores insertados o a sobre la pila no son unicamente cdigos de tipos de tokens; estos representan toda la secuencia de o s mbolos terminales y no terminales en o cerca del tope de la pila. El estado actual colecciona toda esta informacin sobre la entrada anterior que es relevante para decidir qu hacer a continuacin. o e o Cada vez que se lee un token de preanlisis, el estado actual del analizador junto con el tipo de a token de preanlisis se localizan en una tabla. Esta entrada en la tabla puede decir, Desplace el a token de preanlisis. En este caso, tambin especica el nuevo estado del analizador, que se pone a e sobre el tope de la pila del analizador. O puede decir, Reduzca utilizando la regla n mero n. Esto u quiere decir que un cierto n mero de tokens o agrupaciones se sacan de la pila, y se reemplazan u por una agrupacin. En otras palabras, se extrae ese n mero de estados de la pila, y se empuja un o u nuevo estado.

Capitulo 5: El Algoritmo del Analizador de Bison

75

Hay otra alternativa: la tabla puede decir que el token de preanlisis es errneo en el estado a o actual. Esto provoca que comience el procesamiento de errores (ver Capitulo 6 [Recuperacion de Errores], pgina 81). a

5.6 Conictos de Reduccin/Reduccin o o


Se produce un conicto de reduccin/reduccin si hay dos o ms reglas que pueden aplicarse a o o a la misma secuencia de entrada. Esto suele indicar un error serio en la gramtica. a Por ejemplo, aqu hay un intento fallido de denir una secuencia de cero o ms agrupaciones de a palabra. secuencia: /* vaco */ { printf ("secuencia vaca\n"); } | posiblepalabra | secuencia palabra { printf ("palabra a~adida %s\n", $2); } n ; posiblepalabra: /* vaco */ { printf ("posiblepalabra vaco\n"); } | palabra { printf ("palabra sencilla %s\n", $1); } ; El error es una ambig edad: hay ms de una manera de analizar una palabra sencilla en una u a secuencia. Esta podr reducirse a una posiblepalabra y entonces en una secuencia mediante la a segunda regla. Alternativamente, la cadena vac se prodr reducir en una secuencia mediante la a a primera regla, y esto prodr combinarse con la palabra utilizando la tercera regla para secuencia. a Existe tambin ms de una manera de reducir la cadena vac en una secuencia. Esto se e a a puede hacer directamente mediante la primera regla, o indirectamente mediante posiblepalabra y entonces la segunda regla. Podr pensar que esto es una distincin sin ninguna diferencia, porque esto no cambia si una a o entrada particular es vlida o no. Pero s afecta en las acciones que son ejecutadas. Una ordenacin a o del anlisis ejecuta la accin de la segunda regla; la otra ejecuta la accin de la primera regla y la a o o accin de la tercera regla. En este ejemplo, la salida del programa cambia. o Bison resuelve un conicto reduccin/reduccin eligiendo el uso de la regla que aparece en o o primer lugar dentro de la gramtica, pero es muy arriesgado contar con esto. Cada conicto de a reduccin/reduccin se debe estudiar y normalmente eliminar. Aqu est la manera apropiada de o o a denir secuencia: secuencia: /* vaco */ { printf ("secuencia vaca\n"); } | secuencia palabra { printf ("palabra a~adida %s\n", $2); } n ;

76

Bison 1.27

Aqu hay otro error com n que produce un conicto reduccin/reduccin. u o o secuencia: /* vaco */ | secuencia palabras | secuencia redirecciones ; palabras: /* vaco */ | palabras palabra ; redirecciones: /* vaco */ | redirecciones redireccion ; La intencin aqu es denir una secuencia que pueda contener ya sea agrupaciones palabra o o redireccion. Las deniciones individuales de secuencia, palabras y redirecciones estn libres a de errores, pero las tres juntas producen una ambig edad sutil: incluso una entrada vac puede u a analizarse en una innidad de maneras diferentes! Considere esto: la cadena vac podr ser una palabras. O podr ser dos palabras en una a a an la, o tres, o cualquier n mero. Podr igualmente ser una redirecciones, o dos, o cualquier u a n mero. O podr ser una palabras seguido de tres redirecciones y otra palabras. Y as u a sucesivamente. Aqu hay dos maneras de corregir estas reglas. Primero, convertirlo en una secuencia de un slo o nivel: secuencia: /* vaco */ | secuencia palabra | secuencia redireccion ; Segundo, prevenir bien un palabras o un redireccion de que sea vac o: secuencia: /* vaco */ | secuencia palabras | secuencia redirecciones ; palabras: palabra | palabras palabra ; redirecciones: redireccion | redirecciones redireccion ;

Capitulo 5: El Algoritmo del Analizador de Bison

77

5.7 Conictos Misteriosos de Reduccin/Reduccin o o


Algunas veces con los conictos reduccin/reduccin puede suceder que no parezcan garantizao o dos. Aqu hay un ejemplo: %token ID %% def:

espc_param espc_return , ; espec_param: tipo | lista_nombre : tipo ; espec_return: tipo | nombre : tipo ; tipo: ID ; nombre: ID ; lista_nombre: nombre | nombre , lista_nombre ;

Parecer que esta gramtica puede ser analizada con slo un unico token de preanlisis: cuando a a o a se est leyendo un espc_param, un ID es un nombre si le sigue una coma o un punto, o un tipo si a le sigue otro nombre. En otras palabras, esta gramtica es LR(1). a Sin embargo, Bison, como la mayor de los generadores de analizadores sintcticos, no pueden a a en realidad manejar todas las gramticas LR(1). En esta gramtica, los dos contextos, aqul a a e despus de un ID al principio de un espc_param y tambin al principio de un espc_return, son lo e e sucientemente similares para que Bison asuma que son el mismo. Estos parecen similares porque estar activos el mismo conjunto de reglasla regla de reduccin a un nombre y aquella para an o la reduccin de tipo. Bison es incapaz de determinar a ese nivel de procesamiento que las reglas o requerir diferentes tokens de preanlisis en los dos contextos, as que construye un solo estado an a del analizador para ambos. Combinando los dos contextos provoca un conicto ms tarde. En la a terminolog de los analizadores sintcticos, este suceso signica que la gramtica no es LALR(1). a a a En general, es mejor arreglar las deciencias que documentarlas. Pero esta deciencia en particular es intr nsecamente dif de arreglar; los generadores de analizadores sintcticos que pueden cil a manejar gramticas LR(1) son duros de escribir y tienden a producir analizadores que son muy a grandes. En la prctica, Bison es ms util como es ahora. a a Cuando el problema aparece, puede a veces arreglarlo identicando los dos estados del analizador que estn siendo confundidos, y a adir algo para hacerlos pareceer distintos. En el ejemplo anterior, a n a adiendo una regla a espc_return como a continuacin hace que el problema desaparezca: n o

78

Bison 1.27

%token BOGUS ... %% ... espc_return: tipo | nombre : tipo /* Esta regla nunca se usa. | ID BOGUS ; */

Esto corrige el problema porque introduce la posibilidad de una regla activa adicional en el contexto despus de ID al principio de un espc_param, as que los dos contextos reciben estados e distinto del analizador. Siempre que el token BOGUS no se genere nunca por yylex, la regla adicional no podr alterar la manera en la que la entrada es analizada. a En este ejemplo en particular, hay otra forma de resolver este problema: reescribir la regla de espc_return para usar ID directamente en lugar de hacerlo a travs de nombre. Esto tambin e e provoca que los dos contextos confusos tengan conjuntos de reglas activas distintas, porque la de espc_return activa la regla alterada para espc_return en vez que la de nombre. espc_param: tipo | lista_nombre : tipo ; espc_return: tipo | ID : tipo ;

5.8 Desbordamiento de Pila, y Cmo Evitarlo o


La pila del analizador de Bison puede desbordarse si se desplazan demasiados tokens y no son reducidos. Cuando esto sucede, la funcin del analizador yyparse devuelve un valor distinto de o cero, haciendo pausas solamente para llamar a yyerror para informar del desbordamiento. Deniendo la macro YYMAXDEPTH, puede controlar cun profundo puede llegar a ser la pila del a analizador antes de que suceda un desbordamiento de la pila. Dena esta macro con un valor que sea un entero. Este valor es el n mero mximo de tokens que pueden ser desplazados (y sin ser u a reducidos) antes de un desbordamiento. Debe ser una expresin constante cuyo valor se conozca o en tiempo de compilacin. o El espacio de la pila permitido no es asignado necesariamente. Si especica un valor grande para YYMAXDEPTH, el analizador realmente asigna un peque a pila al principio, y entonces la hace n mayor por etapas a medida que se necesite. Esta asignacin incremental ocurre automticamente y o a silenciosamente. Por lo tanto, no necesita hacer a YYMAXDEPTH angustiosamente peque o meramente n para ahorrar espacio para entradas ordinarias que no necesitan mucha pila. El valor por defecto de YYMAXDEPTH, si no lo dene, es 10000.

Capitulo 5: El Algoritmo del Analizador de Bison

79

Usted puede controlar cunta pila se asigna inicialmente deniendo la macro YYINITDEPTH. Este a valor tambin debe ser una constante entera en tiempo de compilacin. El valor por defecto es 200. e o

80

Bison 1.27

Capitulo 6: Recuperacin de Errores o

81

6 Recuperacin de Errores o
Normalmente no es aceptable que un programa termine ante un error de anlisis. Por ejemplo, a un compilador deber recuperarse lo suciente como para que analice el resto del archivo de entrada a y comprobar sus errores; una calculadora deber aceptar otra expresin. a o En un analizador de comandos interactivo sencillo donde cada entrada es una l nea, podr ser a suciente con permitir a yyparse devolver un 1 ante un error y hacer que la funcin invocadora o ignore el resto de la l nea de entrada cuando suceda (y entonces llamar a yyparse de nuevo). Pero esto es inadecuado para un compilador, porque olvida todo el contexto sintctico desde el comienzo a hasta donde se encontr el error. Un error de sintaxis profundo dentro de una funcin del chero o o de entrada del compilador no deber provocar que el compilador trate la l a nea siguiente como el principio de un chero fuente. Puede denir cmo recuperarse de un error de sintaxis escribiendo reglas para reconocer el o token especial error. Este es un s mbolo terminal que siempre se dene (no necesita declararlo) y reservado para tratamiento de errores. El analizador de Bison genera un token error siempre que ocurra un error de sintaxis; si ha facilitado una regla que reconozca este token en el contexto actual, el analizador puede continuar. Por ejemplo: stmnts: /* cadena vaca */ | stmnts \n | stmnts exp \n | stmnts error \n

La cuarta regla en este ejemplo dice que un error seguido de una nueva l nea forma una adicin o vlida a cualquier stmnts. a Qu sucede si aparece un error de sintaxis en medio de una exp? La regla de recuperacin de e o errores, interpretada estrictamente, se aplica a la secuencia precisa de una stmnts, un error y una nueva l nea. Si aparece un error en medio de una exp, probablemente existan tokens adicionales y subexpresiones por leer antes de la nueva l nea. De manera que la regla no es aplicable de la forma habitual. Pero Bison puede forzar la situacin para que se ajuste a la regla, descartando parte del contexto o semntico y parte de la entrada. Primero descarta estados y objetos de la pila hasta que regrese a a un estado en el que el token error sea aceptable. (Esto quiere decir que las subexpresiones ya analizadas son descartadas, retrocediendo hasta el ultimo stmnts completo.) En este punto el token error puede desplazarse. Entonces, si el antiguo token de preanlisis no es aceptable para ser a desplazado, el analizador lee tokens y los descarta hasta que encuentre un token que sea aceptable. En este ejemplo, Bison lee y descarta entrada hasta la siguiente l nea de manera que la cuarta regla puede aplicarse. La eleccin de reglas de error en la gramtica es una eleccin de estrategias para la recuperacin o a o o de errores. Una estrategia simple y util es sencillamente saltarse el resto de la l nea de entrada actual o de la sentencia actual si se detecta un error: stmnt: error ; /* ante un error, saltar hasta que se lea ; */

82

Bison 1.27

Tambin es util recuperar el delimitador de cierre que empareja con un un delimitador de e apertura que ya ha sido analizado. De otra manera el delimitador de cierre probablemente aparecer a como sin emparejar, y generar otro, esp reo mensaje de error: a u primary: ( expr ) | ( error ) ... ; Las estrategias de recuperacin de errores son por fuerza adivinanzas. Cuando estas adivinan o mal, un error de sintaxis a menudo provoca otro. En el ejemplo anterior, la regla de recuperacin de o errores sospecha que el error es debido a una mala entrada en un stmnt. Suponga que en su lugar se inserta un punto y coma accidental en medio de un stmt vlido. Despus de recuperarse del primer a e error con la regla de recuperacin de errores, se encontrar otro error de sintaxis directamente, ya o a que el texto que sigue al punto y coma accidental tambin es una stmnt invlida. e a Para prevenir una cascada de mensajes de error, el analizador no mostrar mensajes de error a para otro error de sintaxis que ocurra poco despus del primero; solamente despus de que se hayan e e desplazado con xito tres tokens de entrada consecutivos se reanudarn los mensajes de error. e a Note que las reglas que aceptan el token error podr tener acciones, al igual que cualquiera an de las otras reglas pueden tenerlas. Puede hacer que los mensajes de error se reanuden inmediatamente usando la macro yyerrok en una accin. Si lo hace en la accin de la regla de error, no se suprimir ning n mensaje de error. o o a u Esta macro no requiere ning n argumento; yyerrok; es una sentencia vlida de C. u a El token de preanlisis anterior se reanaliza inmediatamente despus de un error. Si este no a e es aceptable, entonces la macro yyclearin podr utilizarse para limpiar ese token. Escriba la a sentencia yyclearin; en la accin de la regla de error. o Por ejemplo, suponga que ante un error de anlisis, se llama a una rutina de manejo de errores que a avanza el ujo de entrada en alg n punto donde el anlisis prodr comenzar de nuevo. El prximo u a a o s mbolo devuelto por el analizador lxico ser probablemente correcto. El token de preanlisis e a a anterior convendr que se descartara con yyclearin;. a La macro YYRECOVERING representa una expresin que tiene el valor 1 cuando el analizador se o est recuperando de un error de sintaxis, y 0 durante el resto del tiempo. Un valor de 1 indica que a actualmente los mensajes de error se estn suprimiendo para nuevos errores de sintaxis. a

Capitulo 7: Manejando Dependencias del Contexto

83

7 Manejando Dependencias del Contexto


El paradigma de Bison es analizar tokens en primer lugar, entonces agruparlos en unidades sintcticas ms grandes. En muchos lenguajes, el signicado de un token se ve afectado por su a a contexto. A pesar de que esto viola el paradigma de Bison, ciertas tcnicas (conocidas como e kludges) podr permitirle escribir analizadores de Bison para tales lenguajes. an (Realmente, kludge signica cualquier tcnica que hace su trabajo pero no de una manera e limpia o robusta.)

7.1 Informacin Semntica en Tipos de Tokens o a


El lenguaje C tiene una dependencia del contexto: la manera en la que se utiliza un identicador depende de cul es su signicado. Por ejemplo, considere esto: a foo (x); Esto parece la sentencia de llamada a una funcin, pero si foo es un nombre de tipo denido, o entonces esto realmente es una declaracin de x. Cmo puede un analizador de Bison para C o o decidirse cmo analizar esta entrada? o El mtodo utilizado en GNU C es tener dos tipos diferentes de tokens, IDENTIFIER y TYPENAME. e Cuando yylex encuentre un identicador, localiza la declaracin actual del identicador para decidir o que tipo de token devolver: TYPENAME si el identicador se declara como una denicin de tipo, o IDENTIFIER en otro caso. Las reglas gramaticales pueden entonces expresar la dependencia del contexto eligiendo el tipo de token a reconocer. IDENTIFIER se acepta como una expresin, pero TYPENAME no lo es. TYPENAME o puede empezar una declaracin, pero TYPENAME no. En contextos donde el signicado del identio cador no es signicativo, tal como en declaraciones que pueden ocultar nombre de denicin de o tipo, no se acepta ni TYPENAME o IDENTIFIERhay una regla para cada uno de los dos tipos de tokens. Esta tcnica es sencilla de usar si la decisin de qu tipos de identicadores se permiten se hace e o e en un lugar cercano a donde se analiza el identicador. Pero en C esto no es siempre as C permite : en una declaracin redeclarar un nombre de tipo denido siempre que se haya especicado antes o un tipo expl cito: typedef int foo, bar, lose; static foo (bar); /* redeclara bar como variable esttica */ a static int foo (lose); /* redeclara foo como funcin */ o Por desgracia, el nombre que se est declarando se encuentra separado de la construccin de la a o declaracin por una estructura sintctica complicadael declarador. o a Como resultado, la parte del analizador de Bison para C necesita ser duplicada, con todos los nombres de los no terminales cambiados: una vez para el anlisis de una declaracin en la que se a o puede redenir un nombre de declaracin de tipo, y una vez para el anlisis de una declaracin en o a o la que no puede hacerse. Aqu hay parte de la duplicacin, con las acciones omitidas por brevedad: o

84

Bison 1.27

initdcl: declarator maybeasm = init | declarator maybeasm ; notype_initdcl: notype_declarator maybeasm = init | notype_declarator maybeasm ; Aqu initdcl puede redeclarar un nombre de denicin de tipo, pero notype_initdcl no puede. o La distincin entre declarator y notype_declarator es del mismo tipo. o Hay aqu alguna similitud entre esta tcnica y una ligadura lxica (descrita a continuacin), en e e o que la informacin que altera el anlisis lxico se cambia durante el anlisis por otras partes del o a e a programa. La diferencia es que aqu la informacin es global, y se utiliza para otros propsitos en o o el programa. Una verdadera ligadura lxica tiene una bandera de propsito especial controlada por e o el contexto sintctico. a

7.2 Ligaduras Lxicas e


Una manera de manejar las dependencias del contexto es la ligadura lxica: una bandera que se e activa en acciones de Bison, cuyo propsito es alterar la manera en la que se analizan los tokens. o Por ejemplo, soponga que tenemos un lenguaje vagamente parecido a C, pero con una construccin especial hex (hex-expr). Despus de la palabra clave hex viene una expresin entre o e o parntesis en el que todos los enteros son hexadecimales. En particular, el token a1b debe trae tarse como un entero en lugar de como un identicador si aparece en ese contexto. He aqu cmo o puede hacerlo: %{ int hexflag; %} %% ... expr: IDENTIFIER | constant | HEX ( { hexflag = 1; } expr ) { hexflag = 0; $$ = $4; } | expr + expr { $$ = make_sum ($1, $3); } ... ;

Capitulo 7: Manejando Dependencias del Contexto

85

constant: INTEGER | STRING ; Aqu asumimos que yylex mira el valor de hexflag; cuando no es cero, todos los enteros se analizan en hexadecimal, y los tokens que comiencen con letras se analizan como enteros si es posible. La declaracin de hexflag mostrada en la seccin de declaraciones en C del archivo del analizao o dor se necesita para hacerla accesible a las acciones (ver Seccion 3.1.1 [La Seccin de Declaraciones o en C], pgina 45). Debe tambin escribir el cdigo en yylex para obedecer a la bandera. a e o

7.3 Ligaduras Lxicas y Recuperacin de Errores e o


Las ligaduras lxicas hacen demandas estrictas sobre cualquier regla de recuperacin de errores e o que tenga. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a La razn de esto es que el propsito de una regla de recuperacin de errores es abortar el anlisis o o o a de una construccin y reanudar en una construccin mayor. Por ejemplo, en lenguajes como C, o o una regla t pica de recuperacin de errores es saltarse los tokens hasta el siguiente punto y coma, o y entonces comenzar una sentencia nueva, como esta: stmt: expr ; | IF ( expr ) stmt { . . . } ... error ; { hexflag = 0; } ;

Si hay aqu un error de sintaxis en medio de una construccin hex (expr), esta regla de error se o aplicar, y entonces la accin para la hex (expr) nunca se ejecutar. As que hexflag continuar a o a a activada durante el resto de la entrada, o hasta la prxima palabra clave hex, haciendo que los o identicadores se malinterpreten como enteros. Para evitar este problema la regla de recuperacin de errores por s misma desactiva hexflag. o Aqu podr existir tambin una regla de recuperacin de errores que trabaje dentro de ex a e o presiones. Por ejemplo, podr haber una regla que se aplique dentro de los parntesis y salte al a e parntesis-cerrar: e expr: ... | ( expr ) { $$ = $2; } | ( error ) ...

Si esta regla act a dentro de la construccin hex, no se va a abortar esa construccin (ya que u o o sta aparece a un nivel ms interno de parntesis dentro de la construccin). Por lo tanto, no e a e o

86

Bison 1.27

deber desactivar la bandera: el resto de la construccin hex deber analizarse con la bandera a o a a n activada. u Qu suceder si hay una regla de recuperacin de errores que pudiese abortar fuera la conse a o truccin hex o pudiese que no, dependiendo de las circunstancias? No hay manera de escribir la o accin para determinar si una construccin hex est siendo abortada o no. De manera que si est o o a a utilizando una ligadura lxica, es mejor que est seguro que sus reglas de recuperacin de errores e e o no son de este tipo. Cada regla debe ser tal que pueda estar seguro que siempre tendr que tener a que limpiar la bandera, o siempre no.

Capitulo 8: Depurando Su Analizador

87

8 Depurando Su Analizador
Si una gramtica de Bison compila adecuadamente pero no hace lo que quiere cuando se ejecuta, a la propiedad de traza del analizador yydebug puede ayudarle para darse cuenta del por qu. e Para activar la compilacin de las facilidades de traza, debe denir la macro YYDEBUG cuando o compile el analizador. Podr utilizar -DYYDEBUG=1 como una opcin del compilador o podr a o a poner #define YYDEBUG 1 en la seccin de declaraciones de C del archivo de la gramtica (ver o a Seccion 3.1.1 [La Seccin de Declaraciones en C], pgina 45). De forma alternativa, utilice la opcin o a o -t cuando ejecute Bison (ver Capitulo 9 [Invocando a Bison], pgina 89). Siempre deniremos a YYDEBUG de manera que la depuracin siempre es posible. o La facilidad de traza utiliza stderr, de manera que debe a adir #include <stdio.h> en la n seccin de declaraciones de C a menos que ya est ah o e . Una vez que haya compilado el programa con las facilidades de traza, la manera de solicitar una traza es almacenar un valor distinto de cero en la variable yydebug. Puede hacer esto poniendo cdigo C que lo haga (en main, tal vez), o puede alterar el valor con un depurador de C. o Cada paso tomado por el analizador cuando yydebug no es cero produce una l nea o dos de informacin de traza, escrita sobre stderr. Los mensajes de traza le cuentan estas cosas: o Cada vez que el analizador llama a yylex, qu tipo de token ha sido leido. e Cada vez que un token se reduce, la profundidad y contenido completo de la pila de estados. (ver Seccion 5.5 [Estados del Analizador], pgina 74). a Cada vez que se reduce una regla, qu regla es, y el contenido posterior completo de la pila de e estados Para hacerse una idea de esta informacin, ayuda el hacer referencia al listado del archivo o producido por la opcin -v de Bison (ver Capitulo 9 [Invocando a Bison], pgina 89). Este o a archivo muestra el signicado de cada estado en trminos de posicin en varias reglas, y tambin e o e qu har cada estado con cada token de entrada posible. A medida que lea los mensajes de traza e a sucesivos, puede ver que el analizador est fucionando de acuerdo a su especicacin en el achivo del a o listado. Finalmente llegar al lugar donde sucede algo indeseable, y ver qu parte de la gramtica a a e a es la culpable. El archivo del analizador es un programa en C y puede utilizar depuradores de C con ste, pero e no es fcil interpretar lo que est haciendo. La funcin del analizador es un intrprete de una a a o e mquina de estado nito, y aparte de las acciones ste ejecuta el mismo cdigo una y otra vez. a e o Solamente los valores de las variables muestran sobre qu lugar de la gramtica se est trabajando. e a a La informacin de depuracin normalmente da el tipo de token de cada token le o o do, pero no su valor semntico. Puede opcionalmente denir una macro llamada YYPRINT para facilitar una a manera de imprimir el valor. Si dene YYPRINT, esta deber tomar tres argumentos. El analizador a pasar un ujo de entrada/salida estandar, el valor numrico del tipo de token, y el valor del token a e (de yylval). Aqu hay un ejemplo de YYPRINT apropiado para la calculadora multifuncin (ver Seccion 2.4.1 o [Declaraciones para mfcalc], pgina 38): a

88

Bison 1.27

#define YYPRINT(file, type, value)

yyprint (file, type, value)

static void yyprint (file, type, value) FILE *file; int type; YYSTYPE value; { if (type == VAR) fprintf (file, " %s", value.tptr->name); else if (type == NUM) fprintf (file, " %d", value.val); }

Capitulo 9: Invocando a Bison

89

9 Invocando a Bison
La manera habitual de invocar a Bison es la siguiente: bison chero-entrada Aqu chero-entrada es el nombre del chero de la gramtica, que normalmente termina en .y. a El nombre del archivo del analizador se construye reemplazando el .y con .tab.c. As el nombre , de chero bison foo.y produce foo.tab.c, y el nombre de chero bison hack/foo.y produce hack/foo.tab.c.

9.1 Opciones de Bison


Bison soporta las opciones tradicionales de una unica letra y nombres de opcin mnemnicos o o largos. Los nombres de opcin largos se indican con -- en lugar de -. Las abreviaciones para o los nombres de opcin se permiten siempre que sean unicas. Cuando una opcin larga toma un o o argumento, como --file-prefix, se conecta el nombre de la opcion con el argumento con =. Aqu hay una lista de opciones que puede utilizar con Bison, alfabetizadas por la opcin corta. o -b prejo-chero --file-prefix=prejo Especica un prejo a ser usado por todos los nombres de archivo de salida de Bison. Los nombres se eligen como si el chero de entrada se llamase prejo.c. -d --defines Escribe un archivo extra de salida conteniendo las deniciones de las macros para los nombres de tipo de tokens denidos en la gramtica y el tipo de valor semntico a a YYSTYPE, adems de unas cuantas declaraciones de variables extern. a Si el archivo de salida del analizador se llama name.c entonces este archivo se llama name.h. Este archivo de salida es esencial si desea poner las deniciones de yylex en un archivo fuente por separado, porque yylex necesita ser capaz de hacer referencia a los cdigos o de tipo de token y las variables yylval. Ver Seccion 4.2.2 [Valores Semnticos de los a Tokens], pgina 63. a -l --no-lines No pone ning n comando #line del preprocesador en el chero del analizador. Noru malmente Bison los pone en el archivo del analizador de manera que el compilador de C y los depuradores asocien errores con su chero fuente, el achivo de la gramtica. a Esta opcin hace que asocien los errores con el archivo del analizador, tratndolo como o a un archivo fuente independiente por derecho propio. -n --no-parser No incluye ning n cdigo C en el archivo del analizador; genera unicamente las tablas. u o El archivo del analizador contiene slo directivas #define y declaraciones de variables o estticas. a

90

Bison 1.27

Esta opcin tambin le dice a Bison que escriba el cdigo C para las acciones gramatio e o cales en un archivo llamado nombrechero.act, en la forma de un cuerpo encerrado entre llaves para formar una sentencia switch. -o chero-salida --output-file=chero-salida Especica el nombre chero-salida para el archivo del analizador. El resto de los nombres de chero de salida son construidos a partir de chero-salida como se describi bajo las opciones -v y -d. o -p prejo --name-prefix=prejo Renombra los s mbolos externos utilizados en el analizador de manera que comiencen con prejo en lugar de yy. La lista precisa de s mbolos renombrados es yyparse, yylex, yyerror, yynerrs, yylval, yychar y yydebug. Por ejemplo, si utiliza -p c, los nombres sern cparse, clex, etc. a Ver Seccion 3.7 [M ltiples Analizadores en el Mismo Programa], pgina 60. u a -r --raw -t --debug Hace que parezca que haya sido especicado %raw. Ver Seccion 3.6.8 [Sumario de Decls.], pgina 59. a Produce una denicin de la macro YYDEBUG en el achivo del analizador, de manera o que las facilidades de depuracin sean compiladas. Ver Capitulo 8 [Depurando Su o Analizador], pgina 87. a

-v --verbose Escribe un archivo de salida extra conteniendo descripciones amplias de los estados del analizador y qu se hace para cada tipo de token de preanlisis en ese estado. e a Este archivo tambin describe todos los conictos, aquellos resueltos por la precedencia e de operadores y los no resueltos. Este nombre de chero se construye quitando .tab.c o .c del nombre de salida del analizador, y a adiendo .output en su lugar. n Por lo tanto, si el archivo de entrada es foo.y, entonces el archivo del analizador se llama foo.tab.c por defecto. Como consecuencia, el archivo de salida amplia se llama foo.output. -V --version Imprime el n mero de versin de Bison y termina. u o -h --help Imprime un sumario de las opciones de l nea de comando de Bison y termina.

-y --yacc --fixed-output-files Equivalente a -o y.tab.c; el archivo de salida del analizador se llama y.tab.c, y el resto de salida se llama y.output y y.tab.h. El propsito de esta opcion es la de o imitar las convenciones de los nombres de chero de Yacc. De este modo, el siguiente script de comandos puede ser sustituto de Yacc: bison -y $*

Capitulo 9: Invocando a Bison

91

9.2 Clave Cruzada de Opciones


Aqu hay una lista de opciones, alfabetizada opcin corta correspondiente. o --debug . . . . . . . . . . . . . . . --defines . . . . . . . . . . . . . . --file-prefix . . . . . . . . . . . . --fixed-output-files . . . . . . . . . --help . . . . . . . . . . . . . . . . --name-prefix . . . . . . . . . . . . --no-lines . . . . . . . . . . . . . . --no-parser . . . . . . . . . . . . . --output-file . . . . . . . . . . . . --raw . . . . . . . . . . . . . . . . --token-table . . . . . . . . . . . . --verbose . . . . . . . . . . . . . . --version . . . . . . . . . . . . . . --yacc . . . . . . . . . . . . . . . . por la opcion larga, para ayudarle a encontrar la . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -t -d -b -y -h -p -l -n -o -r -k -v -V -y

9.3 Invocando Bison bajo VMS


La sintaxis de la l nea de comandos para Bison sobre VMS es una variante de la sintaxis del comando de Bison usualadaptada para ajustarse a las convenciones de VMS. Para encontrar el equivalente VMS de cualquier opcin de Bison, comience con la opcin larga, o o y sustituya con / el -- inicial, y sustituya con _ cada - en el nombre de opcin largo. Por o ejemplo, la siguiente invocacin bajo VMS: o bison /debug/name_prefix=bar foo.y es equivalente al siguiente comando bajo POSIX. bison --debug --name-prefix=bar foo.y El sistema de archivos de VMS no permite nombre de cheros tales como foo.tab.c. En el ejemplo anterior, el archivo de salida se llamar foo_tab.c. a

92

Bison 1.27

Apndice A: S e mbolos de Bison

93

Apndice A S e mbolos de Bison


error Un nombre de token reservado para la recuperacin de errores. Este token puede ser o utilizado en reglas gramaticales para permitir al analizador de Bison reconocer un error en la gramtica sin parar el proceso. En efecto, una sentencia conteniendo un error a podr reconocerse como vlida. Ante un error de anlisis, el token error llega a a a a ser el token de preanlisis actual. Las acciones correspondientes a error se ejecutan a entonces, y el token de preanlisis se reestablace al token que originalmente provoc la a o violacin. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. o a Macro que pretende que haya ocurrido un error de sintaxis no recuperable haciendo que yyparse devuelva un 1 inmediatamente. La funcin de informe de errores yyerror o no se llama. Ver Seccion 4.1 [La Funcin del Analizador yyparse], pgina 61. o a Macro que pretende que una expresin completa del lenguaje haya sido leida, haciendo o que yyparse devuelva un 0 inmediatamente. Ver Seccion 4.1 [La Funcin del Analizador o yyparse], pgina 61. a Macro para descartar un valor de la pila del analizador y falsicar un token de preanlisis. Ver Seccion 4.4 [Propiedades Especiales para su Uso en Acciones], a pgina 66. a Macro que pretende que un error de sintaxis se haya acabado de detectar: llama a yyerror y entonces realiza una recuperacin de errores normal si es posible (ver Capio tulo 6 [Recuperacion de Errores], pgina 81), o (si la recuperacin es imposible) hace a o que yyparse devuelva un 1. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a

YYABORT

YYACCEPT

YYBACKUP

YYERROR

YYERROR_VERBOSE Macro que usted dene con #define en la seccin de declaraciones de Bison para o solicitar cadenas de mensajes de errores amplias, espec cas cuando se llame a yyerror. YYINITDEPTH Macro para especicar el tama o inicial de la pila del analizador. Ver Seccion 5.8 n [Desbordamiento de Pila], pgina 78. a YYLEX_PARAM Macro para especicar un argumento extra (o lista de argumentos extra) para que yyparse los pase a yylex. Ver Seccion 4.2.4 [Convenciones de Llamada para Analizadores Puros], pgina 64. a YYLTYPE yyltype YYMAXDEPTH Macro para especicar el tama o mximo de la pila del analizador. Ver Seccion 5.8 n a [Desbordamiento de Pila], pgina 78. a YYPARSE_PARAM Macro para especicar el nombre de un parmetro que yyparse deber aceptar. Ver a a Seccion 4.2.4 [Convenciones de Llamada para Analizadores Puros], pgina 64. a YYRECOVERING Macro cuyo valor indica si el analizador se est recuperando de un error de sintaxis. a Ver Seccion 4.4 [Propiedades Especiales para su Uso en Acciones], pgina 66. a YYSTYPE Macro para el tipo de datos de los valores semnticos; int por defecto. Ver Seccion 3.5.1 a [Tipos de Datos de los Valores Semnticos], pgina 50. a a Macro para el tipo de datos yylloc; una estructura con cuatro componentes. Ver Seccion 4.2.3 [Posiciones en el Texto de los Tokens], pgina 63. a Valor por defecto para YYLTYPE.

94

Bison 1.27

yychar

Variable entera externa que contiene el valor entero del token actual de preanlisis. a (En un analizador puro, es una variable local dentro de yyparse.) Las acciones de las reglas de recuperacin de errores podr examinar esta variable. Ver Seccion 4.4 o an [Propiedades Especiales para su Uso en Acciones], pgina 66. a Macro utilizada en acciones de reglas de recuperacin de errores. Esta borra el anterior o token de preanlisis. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a a

yyclearin

yydebug

Variable entera externa puesta a cero por defecto. Si se le da a yydebug un valor distinto de cero, el analizador sacar informacin a cerca de los s a o mbolos de entrada y acciones del analizador. Ver Capitulo 8 [Depurando Su Analizador], pgina 87. a Macro que provoca al analizador recuperar su modo normal inmediatamente despus e de un error de anlisis. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a a Funcin facilitada por el usuario para ser llamada por yyparse ante un error. La funcin o o recibe un argumento, un puntero a una cadena de caracteres conteniendo un mensaje de error. Ver Seccion 4.3 [La Funcin de Informe de Errores yyerror], pgina 65. o a Funcin del analizador lxico facilitada por el usuario, llamada sin argumentos para o e obtener el siguiente token. Ver Seccion 4.2 [La Funcin del Analizador Lxico yylex], o e pgina 61. a Variable externa en la que yylex deber poner el valor semntico asociado con un a a token. (En un analizador puro, es una variable local dentro de yyparse, y su direccin o se le pasa a yylex.) Ver Seccion 4.2.2 [Valores Semnticos de los Tokens], pgina 63. a a Variable externa en la que yylex deber poner el n mero de l a u nea y columna asociado a un token. (En un analizador puro, es una variable local dentro de yyparse, y su direccin se le pasa a yylex.) Puede ignorar esta variable si no utiliza la propiedad @ o en las acciones gramaticales. Ver Seccion 4.2.3 [Posiciones en el Texto de los Tokens], pgina 63. a Variable global que Bison incrementa cada vez que hay un error de anlisis. (En un a analizador puro, es una variable local dentro de yyparse.) Ver Seccion 4.3 [La Funcin o de Informe de Errores yyerror], pgina 65. a La funcin del analizador producida por Bison; llame a esta funcin para comenzar el o o anlisis. Ver Seccion 4.1 [La Funcin del Analizador yyparse], pgina 61. a o a Declaracin de Bison para asignar asociatividad por la izquierda a un(varios) token(s). o Ver Seccion 3.6.2 [Precedencia de Operadores], pgina 56. a Declaracin de Bison para evitar la generacin de directivas #line en el chero del o o analizador. Ver Seccion 3.6.8 [Sumario de Decls.], pgina 59. a

yyerrok yyerror

yylex

yylval

yylloc

yynerrs

yyparse %left %no_lines

%nonassoc Declaracin de Bison para asignar no-asociatividad a un(varios) token(s). Ver Seco cion 3.6.2 [Precedencia de Operadores], pgina 56. a %prec Declaracin de Bison para asignar precedencia a una regla espec o ca. Ver Seccion 5.4 [Precedencia Dependiente del Contexto], pgina 73. a

%pure_parser Declaracin de Bison para solicitar un analizador puro (reentrante). Ver Seccion 3.6.7 o [Un Analizador Puro (Reentrante)], pgina 58. a %raw Declaracin de Bison para usar los n meros de cdigo de token internos a Bison en las o u o tablas de tokens en lugar de los n meros de cdigo de tokens usuales compatibles con u o Yacc. Ver Seccion 3.6.8 [Sumario de Decls.], pgina 59. a

Apndice A: S e mbolos de Bison

95

%right %start %token

Declaracin de Bison para asignar asociatividad por la derecha a un(varios) token(s). o Ver Seccion 3.6.2 [Precedencia de Operadores], pgina 56. a Declaraciones de Bison para especicar el s mbolo de arranque. Ver Seccion 3.6.6 [El S mbolo de Arranque], pgina 58. a Declaracin de Bison para declarar un(varios) token(s) sin especicar la precedencia. o Ver Seccion 3.6.1 [Nombres de Tipo de Token], pgina 55. a

%token_table Declaracin de Bison para incluir una tabla de nombres de tokens en el archivo del o analizador. Ver Seccion 3.6.8 [Sumario de Decls.], pgina 59. a %type %union Declaracin de Bison para declarar no-terminales. Ver Seccion 3.6.4 [S o mbolos No Terminales], pgina 57. a Declaracin de Bison para especicar varios tipos de datos posibles para los valores o semnticos. Ver Seccion 3.6.3 [La Coleccin de Tipos de Valor], pgina 57. a o a

Estos son los puntuadores y delimitadores utilizados en la entrada de Bison: %% Delimitador utilizado para separar la seccin de reglas gramaticales de la seccin de o o declaraciones de Bison o la seccin de cdigo adicional en C. Ver Seccion 1.7 [El Formato o o Global de una Gramtica de Bison], pgina 27. a a Todo el cdigo listado entre %{ y %} se copia directamente al archivo de salida sin o ser interpretado. Este cdigo forma la seccin de declaraciones en C del archivo de o o entrada. Ver Seccion 3.1 [Resumen de una Gramtica de Bison], pgina 45. a a Delimitadores de comentarios, como en C. Separa el resultado de una regla de sus componentes. Ver Seccion 3.3 [Sintaxis de las Reglas Gramaticales], pgina 48. a Finaliza una regla. Ver Seccion 3.3 [Sintaxis de las Reglas Gramaticales], pgina 48. a Separa reglas alternativas para el mismo no-terminal resultante. Ver Seccion 3.3 [Sintaxis de las Reglas Gramaticales], pgina 48. a

%{ %}

/*. . .*/ : ; |

96

Bison 1.27

Apndice B: Glosario e

97

Apndice B Glosario e
Agrupacin o Una construccin del lenguaje que es (en general) gramaticalmente divisible; por ejemo plo, expresin o declaracin en C. Ver Seccion 1.1 [Lenguajes y Gramticas Indeo o a pendientes del Contexto], pgina 23. a Anlisis de izquierda a derecha a Anlisis de una frase de un lenguaje analizndolo token a token de izquierda a derecha. a a Ver Capitulo 5 [El Algoritmo del Analizador de Bison], pgina 69. a Analizador lxico (scanner) e Una funcin que lee un ujo de entrada y devuelve tokens uno por uno. Ver Seccion 4.2 o [La Funcin del Analizador Lxico yylex], pgina 61. o e a Analizador sintctico (parser) a Una funcin que reconoce frases vlidas de un lenguaje analizando la estructura o a sintctica de un conjunto de tokens pasados desde un analizador lxico. a e Asignacin dinmica o a Asignacin de memoria que ocurre durante la ejecucin, en lugar de en tiempo de o o compilacin, o a la entrada de una funcin. o o Asociatividad por la izquierda Los operadores que tienen asociatividad por la izquierda se analizan de izquierda a derecha; a+b+c primero se computa a+b y entonces se combina con c. Ver Seccion 5.3 [Precedencia de Operadores], pgina 72. a Cadena vac a Anlogo al conjunto vac en la teor de conjuntos, la cadena vac es una cadena de a o a a caracteres de longitud cero. Construccin del lenguaje o Uno de los t picos esquemas de uso del lenguaje. Por ejemplo, una de las construcciones del lenguaje C es la sentencia if. Ver Seccion 1.1 [Lenguajes y Gramticas a Independientes del Contexto], pgina 23. a Desplazamiento Un analizador se dice que desplaza cuando realiza la eleccin de analizar la entrada o que proviene del ujo en lugar de reducir inmediatamente alguna regla ya reconocida. Ver Capitulo 5 [El Algoritmo del Analizador de Bison ], pgina 69. a Error de anlisis a Un error encontrado durante el anlisis de un ujo de entrada debido a una sintaxis no a vlida. Ver Capitulo 6 [Recuperacion de Errores], pgina 81. a a Flujo de entrada Un ujo de datos continuo entre dispositivos y programas. Forma de Backus-Naur (BNF) Mtodo formal para la especicacin de gramticas independientes del contexto. La e o a BNF se utiliz en primer lugar en el informe de ALGOL-60, 1963. Ver Seccion 1.1 o [Lenguajes y Gramticas Independientes del Contexto], pgina 23. a a Gramticas independientes del contexto a Gramticas especicadas como reglas que pueden aplicarse sin considerar el contexto. a Por lo tanto, si hay una regla que dice que un entero se puede utilizar como una expresin, los enteros se permiten en cualquier lugar donde una expresin se permita. o o Ver Seccion 1.1 [Lenguajes y Gramticas Independientes del Contexto], pgina 23. a a

98

Bison 1.27

LALR(1)

La clase de gramticas independientes del contexto que Bison (como la mayor de a a los otros generadores de analizadores sintcticos) pueden manejar; un subconjunto de a las gramticas LR(1). Ver Seccion 5.7 [Misteriosos Conictos Reduccin/Reduccin], a o o pgina 77. a

Ligadura lxica e Una bandera, activada por las acciones en las reglas gramaticales, que alteran la manera en la que se analizan los tokens. Ver Seccion 7.2 [Ligaduras Lexicas], pgina 84. a Literal de caracter simple Un caracter sencillo que se reconoce e interpreta como es. Ver Seccion 1.2 [De las Reglas Formales a la Entrada de Bison], pgina 24. a LR(1) La clase de gramticas independientes del contexto en la que al menos se necesita un a token de preanlisis para eliminar la ambig edad del anlisis de cualquier parte de la a u a entrada.

Mquina de estado nito basada en pila a Una mquina que tiene estados discretos los cuales se dice que existen en cada insa tante de tiempo. A medida que la mquina procesa la entrada, la mquina se mueve a a de estado a estado como se especica en la lgica de la mquina. En el caso de un o a analizador sintctico, la entrada es el lenguaje que est siendo analizado, y los estaa a dos corresponden a varias etapas en las reglas de la gramtica. Ver Capitulo 5 [El a Algoritmo del Analizador de Bison ], pgina 69. a Notacin polaca inversa o Un lenguaje en el que todos los operadores son operadores postjos. Operador injo Un operador aritmtico que se situa entre los operandos sobre los que realiza alguna e operacin. o Operador postjo Un operador aritmtico que se coloca despus de los operandos sobre los que realiza e e alguna operacin. o Recursin por la derecha o Una regla cuyo s mbolo resultante es tambin su componente simblica nal; por ejeme o plo, expseq1: exp , expseq1;. Ver Seccion 3.4 [Reglas Recursivas], pgina 49. a Recursin por la izquierda o Una regla cuyo s mbolo resultante es tambin su primer s e mbolo componente; por ejemplo, expseq1 : expseq1 , exp;.Ver Seccion 3.4 [Reglas Recursivas], pgina 49. a Reduccin Reemplazo de una cadena de no-terminales y/o terminales con un no-terminal simple, o de acuerdo a una regla gramatical. Ver Capitulo 5 [El Algoritmo del Analizador de Bison ], pgina 69. a Reentrante Un subprograma reentrante es un subprograma que puede ser invocado cualquier n mero de veces en paralelo, sin interferir entre las distintas invocaciones. Ver Secu cion 3.6.7 [Un Analizador Puro (Reentrante) ], pgina 58. a Semntica En los lenguajes de ordenador, la semntica se especica con las acciones tomadas para a a cada instancia del lenguaje, es decir, el signicado de cada sentencia. Ver Seccion 3.5 [Deniendo la Semntica del Lenguaje], pgina 50. a a S mbolo de arranque El s mbolo no terminal que representa una expresin completa del lenguaje que se est o a analizando. El s mbolo de arranque normalmente se presenta como el primer s mbolo no terminal en la especicacin del lenguaje. Ver Seccion 3.6.6 [El S o mbolo de Arranque], pgina 58. a

Apndice B: Glosario e

99

S mbolo no terminal Un s mbolo de la gramtica que representa una contruccin gramatical que puede exprea o sarse mediante reglas en trminos de construcciones ms peque as; en otras palabras, e a n una construccin que no es un token. Ver Seccion 3.2 [Simbolos], pgina 46. o a S mbolo terminal Un s mbolo de la gramtica que no tiene reglas en la gramtica y por lo tanto es graa a maticalmente indivisible. El trozo de texto que representa es un token. Ver Seccion 1.1 [Lenguajes y Gramticas Independientes del Contexto], pgina 23. a a Tabla de s mbolos Una estructura de datos donde los nombres de los s mbolos y datos relacionados se almacenan durante el anlisis para permitir el reconocimiento y uso de informacin existente a o en usos repetidos del un s mbolo. Ver Seccion 2.4 [Calc Multi-funcion], pgina 37. a Token Una unidad bsica, gramaticalmente indivisible de un lenguaje. El s a mbolo que describe un token en la gramtica es un s a mbolo terminal. La entrada del analizador de Bison es un ujo de tokens que proviene del analizador lxico. Ver Seccion 3.2 [Simbolos], e pgina 46. a

Token de cadena literal Un token que consiste de dos o ms caracteres jos. Ver Seccion 3.2 [Simbolos], a pgina 46. a Token de preanlisis a Un token que ya ha sido le pero a n no ha sido desplazado. Ver Seccion 5.1 [Tokens do u de Preanlisis], pgina 69. a a

100

Bison 1.27

Indice

101

Indice
$
$$ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 $n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Bison, invocacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o Bison, tabla de s mbolos de . . . . . . . . . . . . . . . . . . . . . . . . Bison, utilidad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . BNF. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 93 26 23

%
%expect . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %left. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %nonassoc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %prec. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %pure_parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %right . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %start . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . %union . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 72 72 73 58 72 58 55 57 57

C
calc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . calculadora de notacin inja . . . . . . . . . . . . . . . . . . . . . . o calculadora de notacin polaca . . . . . . . . . . . . . . . . . . . . . o calculadora multi-funcin . . . . . . . . . . . . . . . . . . . . . . . . . . o calculadora simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . calculadora, notacin inja . . . . . . . . . . . . . . . . . . . . . . . . . o cdigo C, seccin para el . . . . . . . . . . . . . . . . . . . . . . . . . . . o o compilando el analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . conictos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . conictos de desplazamiento/reduccin . . . . . . . . . . . . . o conictos de reduccin/reduccin . . . . . . . . . . . . . . . . . . o o conictos, suprimiendo advertencias de . . . . . . . . . . . . . control, funcin de . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 35 35 29 37 29 35 46 35 70 70 75 57 33

@
@n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67

|
| . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

D
declaraciones de Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . declaraciones de Bison (introduccin) . . . . . . . . . . . . . . o declaraciones de precedencia . . . . . . . . . . . . . . . . . . . . . . . declaraciones, C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . declaraciones, sumario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . declarando el s mbolo de arranque. . . . . . . . . . . . . . . . . . declarando nombres de tipo de token . . . . . . . . . . . . . . . declarando precedencia de operadores . . . . . . . . . . . . . . declarando tipos de valores . . . . . . . . . . . . . . . . . . . . . . . . . declarando tipos de valores, de no terminales . . . . . . . declarando tokens de cadena literal . . . . . . . . . . . . . . . . . default action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . denienfo la semntica del lenguaje . . . . . . . . . . . . . . . . a dependencia del contexto, precedencia . . . . . . . . . . . . . . depurando . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . desbordamiento de la pila del analizador . . . . . . . . . . . desbordamiento de pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . desplazamiento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 45 56 45 59 58 55 56 57 57 55 51 50 73 87 78 78 69

A
accin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o Acciones a Media Regla . . . . . . . . . . . . . . . . . . . . . . . . . . . . acciones en mitad de una regla . . . . . . . . . . . . . . . . . . . . . acciones semnticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a acciones, sumario de propiedades de . . . . . . . . . . . . . . . . advertencias, previniendo . . . . . . . . . . . . . . . . . . . . . . . . . . agrupacin sintctica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o a algoritmo del analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . analizador lxico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e analizador lxico, escribiendo un . . . . . . . . . . . . . . . . . . . e analizador lxico, propsito . . . . . . . . . . . . . . . . . . . . . . . . e o analizador puro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . analizador reentrante . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . analizador, desbordamiento de pila del . . . . . . . . . . . . . analizador, pila . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . archivo de gramtica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a asociatividad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 52 52 26 66 57 23 69 26 61 32 26 58 58 78 69 27 72

E
ejecutando Bison (introduccin) . . . . . . . . . . . . . . . . . . . . o ejemplos simples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . else, balanceo del . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . error. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . error de anlisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a error de sintaxis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . errores, funcin de informe de . . . . . . . . . . . . . . . . . . . . . . o errores, recuperacin de . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 34 29 43 70 81 65 65 65 81

B
balanceo del else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bison, algoritmo del analizador. . . . . . . . . . . . . . . . . . . . . Bison, analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bison, declaraciones. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bison, declaraciones (introduccin) . . . . . . . . . . . . . . . . . o Bison, gramtica de . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 70 69 26 55 45 24

102

Bison 1.27

errores, rutina de informe de . . . . . . . . . . . . . . . . . . . . . . . escribiendo un analizador lxico . . . . . . . . . . . . . . . . . . . . e estado (del analizador) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . estado del analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . etapas en el uso de Bison . . . . . . . . . . . . . . . . . . . . . . . . . .

34 32 74 74 27

P
pila del analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . precedencia de operadores. . . . . . . . . . . . . . . . . . . . . . . . . . precedencia de operadores unarios . . . . . . . . . . . . . . . . . . precedencia de operadores, declarando. . . . . . . . . . . . . . precendecia dependiente del contexto . . . . . . . . . . . . . . . previniendo advertencias a cerca de conictos . . . . . . 69 72 73 56 73 57

F
Forma de Backus-Naur. . . . . . . . . . . . . . . . . . . . . . . . . . . . . formato de la gramtica de Bison . . . . . . . . . . . . . . . . . . a formato del archivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . formato del archivo de gramtica . . . . . . . . . . . . . . . . . . . a funcin de control. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o funcin de informe de errores . . . . . . . . . . . . . . . . . . . . . . o funcin main en ejemplo simple . . . . . . . . . . . . . . . . . . . . o 23 27 27 27 33 65 33

R
recuperacin de errores . . . . . . . . . . . . . . . . . . . . . . . . . . . . o recuperacin de errores, simple . . . . . . . . . . . . . . . . . . . . . o recursin mutua . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o recursin por la derecha . . . . . . . . . . . . . . . . . . . . . . . . . . . . o recursin por la izquierda . . . . . . . . . . . . . . . . . . . . . . . . . . o reduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o reduccin/reduccin, conictos . . . . . . . . . . . . . . . . . . . . . o o reglas recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . rpcalc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . rutina de informe de errores . . . . . . . . . . . . . . . . . . . . . . . . 81 37 49 49 49 69 75 49 29 34

G
glosario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . gramtica de Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a gramtica formal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a gramtica independiente del contexto . . . . . . . . . . . . . . a gramtica, independiente del contexto . . . . . . . . . . . . . . a 97 24 24 23 23

S
s mbolo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s mbolo de arranque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s mbolo de arranque por defecto. . . . . . . . . . . . . . . . . . . . s mbolo de arranque, declarando . . . . . . . . . . . . . . . . . . . s mbolo no terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s mbolo terminal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s mbolos (resumen) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . s mbolos en Bison, tabla de . . . . . . . . . . . . . . . . . . . . . . . . seccin de cdigo C adicional . . . . . . . . . . . . . . . . . . . . . . o o seccin de declaraciones en C . . . . . . . . . . . . . . . . . . . . . . o seccin de reglas gramaticales . . . . . . . . . . . . . . . . . . . . . . o seccin de reglas para la gramtica . . . . . . . . . . . . . . . . . o a semntica del lenguaje, deniendo . . . . . . . . . . . . . . . . . . a semnticas, acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a semntico, tipo de valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . a semntico, valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a sintctica, agrupacin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a o sintaxis de las reglas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . sintaxis de las reglas de la gramtica . . . . . . . . . . . . . . . a sintaxis de reglas gramaticales . . . . . . . . . . . . . . . . . . . . . sumario de declaraciones de Bison . . . . . . . . . . . . . . . . . . sumario de propiedades de accin . . . . . . . . . . . . . . . . . . o suprimiendo advertencias de conictos . . . . . . . . . . . . . 46 24 58 58 46 46 23 93 46 45 45 45 50 26 50 25 23 48 48 48 59 66 57

I
intergfaz en lenguaje C . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 o invocando a Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 invocando Bison bajo VMS . . . . . . . . . . . . . . . . . . . . . . . . 91

L
l mite por defecto de la pila . . . . . . . . . . . . . . . . . . . . . . . . LALR(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lenguaje C, interfaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . lxico, escribiendo un analizador . . . . . . . . . . . . . . . . . . . e ligadura lxica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e literal de caracter sencillo . . . . . . . . . . . . . . . . . . . . . . . . . . literal multi-caracter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LR(1) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 77 61 32 84 46 47 77

M
mquina de estado nito . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 a mfcalc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 multi-funcin, calculadora . . . . . . . . . . . . . . . . . . . . . . . . . . 37 o

N
nombres de tipo de token, declarando . . . . . . . . . . . . . . 55 notacin polaca inversa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 o

T
tabla de s mbolos, ejemplo . . . . . . . . . . . . . . . . . . . . . . . . . tipo de dato por defecto . . . . . . . . . . . . . . . . . . . . . . . . . . . tipo de datos de una accin . . . . . . . . . . . . . . . . . . . . . . . . o tipo de token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . tipo de valor semntico . . . . . . . . . . . . . . . . . . . . . . . . . . . . a tipos de datos de valores semnticos . . . . . . . . . . . . . . . . a tipos de datos en acciones . . . . . . . . . . . . . . . . . . . . . . . . . . 40 50 52 46 50 50 52

O
opciones de la invocacin de Bison . . . . . . . . . . . . . . . . . 89 o operadores unarios, precedencia . . . . . . . . . . . . . . . . . . . . 73 operadores, precedencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72

Indice

103

tipos de valores, declarando . . . . . . . . . . . . . . . . . . . . . . . . tipos de valores, no terminales, declarando . . . . . . . . . token . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . token de cadena de caracteres . . . . . . . . . . . . . . . . . . . . . . token de cadena literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . token de caracter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . token de preanlisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a token literal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . trazando el analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

57 57 23 47 47 46 69 46 87

U
utilizando Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

V
valor semntico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 a VMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

Y
YYABORT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 YYACCEPT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 YYBACKUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

yychar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yyclearin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yydebug . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYDEBUG . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYEMPTY . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yyerrok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yyerror . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYERROR . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYERROR_VERBOSE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYINITDEPTH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yylex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYLEX_PARAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yylloc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYLTYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yylval . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYMAXDEPTH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yynerrs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . yyparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYPARSE_PARAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYPRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . YYRECOVERING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

70 82 87 87 67 82 65 67 65 78 61 65 63 63 63 78 66 61 64 87 82

104

Bison 1.27

Tabla de Contenido
Introduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 o Conditions for Using Bison . . . . . . . . . . . . . . . . . . . . . . . . . 3 Condiciones para el uso de Bison . . . . . . . . . . . . . . . . . . . 5 GNU GENERAL PUBLIC LICENSE . . . . . . . . . . . . . . . 7
Preamble . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 How to Apply These Terms to Your New Programs . . . . . . . . . . . . . . . . . . . 12

LICENCIA PUBLICA GENERAL GNU . . . . . . . . . . . 15


Prembulo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 a TERMINOS Y CONDICIONES PARA LA COPIA, DISTRIBUCI ON Y MODIFICACION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Cmo aplicar estos trminos a sus nuevos programas. . . . . . . . . . . . . . . . . . 20 o e

Los Conceptos de Bison . . . . . . . . . . . . . . . . . . . . . . . . 23


1.1 1.2 1.3 1.4 1.5 1.6 1.7 Lenguajes y Gramticas independientes del Contexto . . . . . . . . . . . . a De las Reglas Formales a la Entrada de Bison . . . . . . . . . . . . . . . . . . . Valores Semnticos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a Acciones Semnticas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a La Salida de Bison: el Archivo del Analizador . . . . . . . . . . . . . . . . . . . Etapas en el Uso de Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . El Formato Global de una Gramtica de Bison . . . . . . . . . . . . . . . . . . a 23 24 25 26 26 27 27

Ejemplos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
2.1 Calculadora de Notacin Polaca Inversa . . . . . . . . . . . . . . . . . . . . . . . . . o 2.1.1 Declaraciones para rpcalc . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Reglas Gramaticales para rpcalc . . . . . . . . . . . . . . . . . . . . . . 2.1.2.1 Explicacin para input . . . . . . . . . . . . . . . . . . . . . . . o 2.1.2.2 Explicacin para line . . . . . . . . . . . . . . . . . . . . . . . . o 2.1.2.3 Explicacin para expr . . . . . . . . . . . . . . . . . . . . . . . . o 2.1.3 El Analizador Lxico de rpcalc . . . . . . . . . . . . . . . . . . . . . . . e 2.1.4 La Funcin de Control . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 2.1.5 La Rutina de Informe de Errores . . . . . . . . . . . . . . . . . . . . . . . 2.1.6 Ejecutando Bison para Hacer el Analizador . . . . . . . . . . . . . 2.1.7 Compilando el Archivo del Analizador . . . . . . . . . . . . . . . . . . Calculadora de Notacin Inja: calc . . . . . . . . . . . . . . . . . . . . . . . . . . . o Recuperacin de Errores Simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o Calculadora Multi-Funcin: mfcalc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o 2.4.1 Declaraciones para mfcalc . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Reglas Gramaticales para mfcalc . . . . . . . . . . . . . . . . . . . . . . 2.4.3 La Tabla de S mbolos de mfcalc . . . . . . . . . . . . . . . . . . . . . . . Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 29 30 30 31 31 32 33 34 34 35 35 37 37 38 39 40 43

2.2 2.3 2.4

2.5

ii

Bison 1.27

Archivos de Gramtica de Bison . . . . . . . . . . . . . . . . 45 a


3.1 Resumen de una Gramtica de Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . a 3.1.1 La Seccin de Declaraciones en C . . . . . . . . . . . . . . . . . . . . . . o 3.1.2 La Seccin de Declaraciones de Bison . . . . . . . . . . . . . . . . . . o 3.1.3 La Seccin de Reglas Gramaticales . . . . . . . . . . . . . . . . . . . . . o 3.1.4 La Seccin de Cdigo C Adicional . . . . . . . . . . . . . . . . . . . . . o o S mbolos, Terminales y No Terminales . . . . . . . . . . . . . . . . . . . . . . . . . . Sintaxis de las Reglas Gramaticales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reglas Recursivas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deniendo la Semntica del Lenguaje . . . . . . . . . . . . . . . . . . . . . . . . . . . a 3.5.1 Tipos de Datos para Valores Semnticos . . . . . . . . . . . . . . . . a 3.5.2 Ms de Un Tipo de Valor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a 3.5.3 Acciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.4 Tipos de Datos de Valores en Acciones . . . . . . . . . . . . . . . . . 3.5.5 Acciones a Media Regla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Declaraciones de Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1 Nombres de Tipo de Token . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.2 Precedencia de Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.3 La Coleccin de Tipos de Valores . . . . . . . . . . . . . . . . . . . . . . o 3.6.4 S mbolos No Terminales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.5 Suprimiendo Advertencias de Conictos . . . . . . . . . . . . . . . . 3.6.6 El S mbolo de Arranque . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.7 Un Analizador Puro (Reentrante) . . . . . . . . . . . . . . . . . . . . . . 3.6.8 Sumario de Declaraciones de Bison . . . . . . . . . . . . . . . . . . . . . M ltiples Analizadores en el Mismo Programa . . . . . . . . . . . . . . . . . . . u 45 45 45 45 46 46 48 49 50 50 50 50 52 52 55 55 56 57 57 57 58 58 59 60

3.2 3.3 3.4 3.5

3.6

3.7

Interfaz del Analizador en Lenguaje C . . . . . . . . . . 61


4.1 4.2 La Funcin del Analizador yyparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o La Funcion del Analizador Lxico yylex . . . . . . . . . . . . . . . . . . . . . . . . e 4.2.1 Convencin de Llamada para yylex . . . . . . . . . . . . . . . . . . . . o 4.2.2 Valores Semnticos de los Tokens . . . . . . . . . . . . . . . . . . . . . . a 4.2.3 Posiciones en el Texto de los Tokens . . . . . . . . . . . . . . . . . . . 4.2.4 Convenciones de Llamada para Analizadores Puros . . . . . . La Funcin de Informe de Errores yyerror . . . . . . . . . . . . . . . . . . . . . . o Propiedades Especiales para su Uso en Acciones . . . . . . . . . . . . . . . . . 61 61 61 63 63 64 65 66

4.3 4.4

El Algoritmo del Analizador de Bison . . . . . . . . . . . 69


5.1 5.2 5.3 Tokens de Preanlisis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a Conictos de Desplazamiento/Reduccin . . . . . . . . . . . . . . . . . . . . . . . . o Precedencia de Operadores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.1 Cundo se Necesita la Precedencia . . . . . . . . . . . . . . . . . . . . . a 5.3.2 Especicando Precedencia de Operadores . . . . . . . . . . . . . . . 5.3.3 Ejemplos de Precedencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5.3.4 Cmo Funciona la Precedencia. . . . . . . . . . . . . . . . . . . . . . . . . o Precedencia Dependiente del Contexto . . . . . . . . . . . . . . . . . . . . . . . . . . Estados del Analizador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Conictos de Reduccin/Reduccin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . o o Conictos Misteriosos de Reduccin/Reduccin . . . . . . . . . . . . . . . . . . o o Desbordamiento de Pila, y Cmo Evitarlo . . . . . . . . . . . . . . . . . . . . . . . o 69 70 72 72 72 73 73 73 74 75 77 78

5.4 5.5 5.6 5.7 5.8

Recuperacin de Errores . . . . . . . . . . . . . . . . . . . . . . . 81 o

iii

Manejando Dependencias del Contexto . . . . . . . . . 83


7.1 7.2 7.3 Informacin Semntica en Tipos de Tokens . . . . . . . . . . . . . . . . . . . . . . 83 o a Ligaduras Lxicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 e Ligaduras Lxicas y Recuperacin de Errores . . . . . . . . . . . . . . . . . . . . 85 e o

8 9

Depurando Su Analizador . . . . . . . . . . . . . . . . . . . . . . 87 Invocando a Bison . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89


9.1 9.2 9.3 Opciones de Bison. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Clave Cruzada de Opciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 Invocando Bison bajo VMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

Apndice A e Apndice B e

S mbolos de Bison . . . . . . . . . . . . . . . . . . . 93 Glosario. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97

Indice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101

iv

Bison 1.27

También podría gustarte