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
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
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
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_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.
Driver.sv 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?