* What is rbison? rbison generates a Ruby parser class from a Bison-like specification file. rbison uses Bison to do all the hard work (generating state tables, transition tables, etc.), then translates the Bison-generated C code into a class for use in other Ruby code. * Why rbison? Because it uses Bison directly, rbison should produce good parsers. Bison is stable and robust. Bison produces fast parsers. rbison should inherit those attributes, once the code has stabilized a bit. Moreover, Bison users will feel at home, since rbison uses a nearly identical parser specification format (see below). * rbison DEPENDS ON Bison! !!! READ ME READ ME READ ME !!! rbison uses Bison. This version was developed using GNU Bison version 1.28. It may work with other versions. * Installation and Usage Installation is simple: cp rbison /usr/local/bin/ You may have to change the first line of the script to match ruby's location on your box (if it's something other than /usr/local/bin/ruby). Usage is equally simple: rbison <infile> <class> > <outfile> where infile is the Bison-like specification file, class is the desired name of the parser class, and outfile is where rbison should dump the Ruby code. See calc.ry for an example specification file. Using the generated parser is easy: require "FooParser" p = FooParser.new p.yyparse(<FooLexer object>) The FooLexer object can be of any class, as long as yylex is implemented and returns [token, value] pairs at each call. To tell the parser that the end of input has been reached, yylex returns [-1, nil]. See CalcFileLexer.rb for an example lexer class. If you want Bison-like debugging output, simply do: require "FooParser" p = FooParser.new p.yydebug = true ## debug p.yyparse(<FooLexer object>) * How does rbison differ from Bison? rbison uses Bison directly to generate a Ruby parser class. The specification file format is nearly identical, but there are three important differences: 1. To use Bison semantic value variables ($$, $1, $2, etc), you MUST prepend an underscore (_$$, _$1, _$2, etc). 2. Rule actions and code declarations (between %{ and %}) contain Ruby code, *not* C code. 3. yyparse takes an object argument. That object must implement yylex, which you must write yourself. Each call to yylex returns a [token, value] pair. See CalcStringLexer.rb for an lexer class that implements yylex. rbison expects yylex to raise the LexError exception on error. * How do I write a parser? See the Bison info pages. Most Bison options and features will work with rbison. Remember that you need to use Ruby code in the action, code declaration, and additional code sections. * This seems a little complicated. Can you give me an example? Sure. calc.ry contains a sample Ruby parser specification for an infix calculator (lifted from the Bison info pages). To try it out, do: rbison calc.ry CalcParser > CalcParser.rb ruby calc_test.rb * Error notification and recovery. rbison supports the Bison parse error recovery mechanism. See the Bison info page topic "Error Recovery" for more information. For example usage, see calc.ry, as it now contains several error handling rules. An irrecoverable parse error throws the exception ParseError. Errors can also occur during lexical analysis. rbison expects yylex to throw LexError on error. * Debugging your parser. After creating a parser object p, do: p.yydebug = true That will give you lots of helpful debugging output on stderr. It is possible to shift debugging output to streams other than stderr, by setting p.yyerror: p.yyerror = $stdout That will send all debugging output to stdout instead of the default stderr. * How to get rbison. The latest release of rbison is available at: http://www.cs.umass.edu/~aseltine/rbison.html * Found a bug? Let me know. Please make sure it has nothing to do with your yylex. Send the specification file (.ry), lexer, and an input file that exhibits the bug to: aseltine@cs.umass.edu I will also accept fixes for bugs. ;-) * Copying rbison is copyrighted free software by Jonathan Aseltine <aseltine@cs.umass.edu>. You can redistribute it and/or modify it under either the terms of the GPL (see COPYING file), or the conditions below: 1. You may make and give away verbatim copies of the source form of the software without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may modify your copy of the software in any way, provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or by allowing the author to include your modifications in the software. b) use the modified software only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided. d) make other distribution arrangements with the author. 3. You may distribute the software in object code or executable form, provided that you do at least ONE of the following: a) distribute the executables and library files of the software, together with instructions (in the manual page or equivalent) on where to get the original distribution. b) accompany the distribution with the machine-readable source of the software. c) give non-standard executables non-standard names, with instructions on where to get the original software distribution. d) make other distribution arrangements with the author. 4. You may modify and include part of the software into any other software (possibly commercial). 5. The scripts and library files supplied as input to or produced as output from the software do not automatically fall under the copyright of the software, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this software. 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.