kiama

A Scala library for language processing.

View the Project on GitHub

Documentation Home

User Manual Examples
Research Reading
Installation
Releases

How to write read-eval-print loops using Kiama

Up: User Manual, Prev: Messaging, Next: Profiling

IMPORTANT NOTE: This page describes Kiama 1.x. Much of it also applies to Kiama 2.x, but not all. Please consult the 2.x release notes for the main differences. We are currently writing comprehensive documentation for 2.x that will eventually replace these pages.

Some language processors operate most naturally as interactive software that reads user input, turns that input into a structured representation (usually an abstract syntax tree), processes it and then prints some result. In the programming languages field, this kind of interaction is called a read-eval-print loop (or REPL).

Kiama provides simple support in the org.bitbucket.inkytonik.kiama.util package for creating REPLs of various kinds. The following examples make particular use of the REPL support:

The REPL trait

File: org.bitbucket.inkytonik.kiama.util.REPL.scala

The common interface for REPLs built using Kiama is provided by the REPL trait. It provides a main function that:

Methods like setup must be provided by an implementation of the REPL trait. The complete list of things that must be provided is:

Perform any setup required before the REPL starts.

Return the prompt that should be printed before an input line is read.

Process the given line.

REPL uses the JLine library to handle prompting and to provide line editing and history.

ParsingREPL

File: org.bitbucket.inkytonik.kiama.util.REPL.scala

REPL provides a very general interface. Kiama also provides a number of more specialised instantiations of REPL for common situations.

ParsingREPL[T] provides a processline function that parses the input line using a provided parser and, if the parse is successful, passes the parsed representation to another method for processing. If the parse is unsuccessful an error message will be printed. The type parameter T is the type of the parsed representation. Instead of providing a processline implementation you should provide:

A parser that returns a value of type T.

A method to process the T values produced by the parser.

GeneratingREPL

File: org.bitbucket.inkytonik.kiama.util.REPLTests.scala

A less useful variant of REPL is GeneratingREPL[T] which provides a standard interface for REPLs that randomly generate program instances. This kind of REPL is typically used for testing so that you can check that your ScalaCheck-based random generation code is producing reasonable programs (for some definition of reasonable).

GeneratingREPL defines versions of setup and prompt that print sensible messages, although you can override them if you want. It also defines a processline that uses a provided generator to produce an instance of type T and then passes it on for processing. You should provide:

Generate a random value of type T. See the ScalaCheck documentation for how to write this method.

Process the randomly-generated T value. Default: print it.

JLine versions

Kiama implements REPLs using the JLine 2 library. In some cases, this version of the JLine library clashes with the version used by the simple build tool (sbt). In those cases you will get an incompatible class exception when you try to run a REPL. If this happens, a work-around is to configure sbt to fork runs so that they run in a different JVM to the clashing library. The following sbt configuration lines are sufficient to make this happen.

fork in run := true

connectInput in run := true

outputStrategy in run := Some (StdoutOutput)

Up: User Manual, Prev: Messaging