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.
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 Main.sv
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 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 system.
Next Section: What Next?