Running Silver

Silver is run over a specified grammar and builds the language translator specified by that grammar. This will involve importing other grammars used by the specified grammar and calling Copper to build any parsers needed by the grammar. The name of this grammar is provided on the command line when calling Silver.

Silver translates the attribute grammar specification to Java code that implements it. It also extracts the concrete syntax specifications that are to be used by Copper to generate the Java-based parsers specified in the concrete syntax of the grammar.

Since Silver is distributed as a Java jar file, this amounts to executing the jar. The tutorial grammar dc comes with a script silver-compile that shows a sample invocation of Silver.

This script also calls ant, a Java-based variant of the Unix make command, that compiles the Java code generated by Silver and invokes Copper to generate the requires parsers and scanners.

Running the generated language translators

Silver, like all attribute grammar systems, can be seen as specialized forms of lazy functional programming. Thus specifying side-effecting computations such as printing to the screen or writing to a file present some challenges.

The current version of Silver has adopted a model similar to that used in Haskell before Haskell was extended with monads. Essentially an input/output token is passed into the main function main and passed between side-effecting computations to control the order in which they are evaluated. This is certainly the most unappealing aspect to Silver and new users are not expected to dive into the details of this.

As a simple example, consider in dc. The main function takes as input the command line arguments and the initial I/O token. Since the command line contains the string to be parsed this is passed to the function parse. This token is used by the calls to print in local attributes print_success and print_failure. These are attributes of type IO that represent the I/O token after the print statement has been executed.

Since Silver is a lazy functional language, these attributes are not evaluated until they are needed. It is the return statement in main that determines if the parse was successful and then demands only one of the I/O values. This causes exactly one of the print statements to be executed.

The file in simple:host:driver shows the use of other side-effecting I/O functions for reading and writing to files.

New users of Silver are encouraged to copy and paste from specifications such as these until they get more experience with Silver and develop a better understanding of its admittedly odd I/O system.

Now that parametric polymorphism has been added to Silver we expect to develop a monadic extension to Silver shortly that will bring it inline with the spirit of Haskell’s monadic I/O sytem.

Next Section: What Next?