Beaver - a LALR Parser Generator

Beaver

How to Run Beaver's Compiler

Command Line

To compile a grammar into a parser source code you run beaver.jar with a name of the file containing grammar specification and maybe some switches:

~$ java -jar beaver.jar [options] language.grammar

If compiler finds no mistakes in the specification and is able to build parsing tables it'll write the source code of the parser into a .java file. Depending on how far off the specification is from the expected semantics compiler may issue warnings, apply an automatic correction and still produce a parser. Though one needs to pay attention to the warnings as they may indicate that the selected path is not the one author had intended to use. If, on the other hand, errors are present in parts of the specification where no reasonable substitute can be applied or the grammar itself has problems, the compiler will print error messages and a parser will not be generated.

Beaver compiler accepts several switches or options that control how a parser will be generated, or what additional information will be produced:

-a
produces additional .stat file that lists parser states and its actions, in other words - a readable form of parsing tables. This information can be handy to analyze why parser performs certain actions while parsing a source.
-c
suppresses compression of parsing tables. Quite often LALR parsers contain states where several lookaheads point to the same action - reduce a certain rule. These actions can be combined into one, which is executed if none of other lookaheads matches. Such compression makes parsing tables smaller, sometimes dramatically. Compression though brings up some issues - parser that uses compressed tables may reduce a rule even while seeing a wrong lookahead token. The issue will quickly be resolved by the parser not being able to ever shift the erroneous token, yet the syntax error will be reported after one or more incorrect reductions. This never happens if parsing tables aren't comressed - all misplaced tokens are immediately noticed and reported. Depending on the constraints of the compiler one may need to disable tables compression, which is enabled by default.
-d <dir>
Destination directory for generated files, which will be written to destdir/grammar/package/name. This behaviour is similar to javac -d.
-D
dry-run - do not generate a parser.
-e
export serialized parsing tables into a .spec file. By default Beaver stores parsing tables in an encoded form in a parser class. This option instructs Beaver to save them in a file instead. Depending on your packaging preferences you may want the latter.
-n
generate non-anonymous delegates for action routines. Usually Beaver wraps action routines in anonymous inner classes. Some debuggers/IDEs are confused by anonymous inner classes and cannot find a source line if it is inside such a class. If this is your case, try this option.
-s
sorts terminals by name. Otherwise terminals are "sorted" by their IDs. Currently this is a purely easthetic option.
-t
generate terminal names. Beaver generates a nested Terminals class as an "enum" for terminals used by a grammar. If you need to use their names in error reports this option will instruct Beaver to create, in addition, a NAMES array with terminal names indexed by terminal IDs.
-T
dumps Terminals class (an "enum" really) to a separate file. Without this option Beaver generates a nested class for them inside a parser class.
-w
use switch-ing to invoke reduce action code. Normally Beaver generates delegates. If this option is used -n will be ignored.
-v
compiler prints version number and exits.

Running with Ant

To compile grammars as part of a project build using Ant, an Ant task for the compiler needs to be declared:

<target name="beavertask" unless="beaver.available" description="creates Beaver Ant task">
    <taskdef name="beaver" classname="beaver.comp.run.AntTask" classpath="${java.libs.dir}/beaver.jar"/>
    <property name="beaver.available" value="yes"/>
</target>

Once Ant picked up beaver.jar and created the task it can be used to compile grammars:

<target name="parser" depends="beavertask" description="generate parser">
    <beaver file             = "language.grammar"
            destdir          = "dir"
            compress         = "yes"
            exportTables     = "no"
            sortTerminals    = "no"
            terminalNames    = "no"
            exportTerminals  = "no"
            useSwitch        = "no"
            anonymousActions = "yes"
            reportActions    = "no" />
</target>

This example uses all of the available task parameters with their default values. All of these attributes are optional, other than the "file". Ant task attributes have almost one-to-one correspondence with the command line arguments:

CLI option Ant task attribute Description
  file="..." name of the source file (containing grammar)
-a reportActions="yes" Create .stat file
-c compress="no" Disable parsing tables compression
-d destdir="dir" Location to store generated files
-D   Do not generate a parser
-e exportTables="yes" Put parsing tables in external file
-n anonymousActions="no" Generate named inner action classes
-s sortTerminals="yes" Sort terminals by name
-t terminalNames="yes" Generate terminal names
-T exportTerminals="yes" Create .java file for Terminals
-w useSwitch="yes" Use switch to select reduce code to run