Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Build an interpreter in Java -- Implement the execution engine

Here's how to take the interpreter classes and run with them

For those of you just joining us, in my "Java In Depth" column over the past couple months, I've been discussing how one might go about building an interpreter in Java. In the first interpreter column, we covered some of the desirable attributes of an interpreter; in the second column we discussed both parsing and the layout of a class package for implementing the interpreter. In this column we'll look at running the interpreter, and the support classes necessary to accomplish that. Finally, I'll wrap up the series here with a discussion of how an interpreter can be hooked into other Java classes, thus enhancing their abilities.

Reviewing the relevant bits

Let me start by sketching out what we've covered so far and point out those parts of the design that will become more important as we discuss execution mode. For a more detailed description of these classes, refer to my previous columns or to the source code links that are in the Resources section below.

There are three foundation classes in the implementation of the interpreter, Program, Statement, and Expression. The following shows how the three are related:

Program

This Program class glues together the parsing and execution components of the parser. This class defines two principal methods, load and run. The load method reads statements from an input stream and parses them into a collection of statements, the run method iterates over the collection and executes each of the statements. The Program class also provides a collection of variables for the program to use as well as a stack for storing data.


Statement

The Statement class contains a single parsed statement. This class is actually subclassed into a specific type of statement (PRINT, GOTO, IF, and so on) but all statements contain the method execute which is called to execute the statement in the context of a Program class instance.


Expression

The Expression class contains the parse tree of an expression. During execution, the value method is used to evaluate the expression and return its value. Like Statement, the Expression class is primarily designed to be subclassed by specific types of expressions.


All of these classes work together to form the basis of an interpreter. The Program class simultaneously encapsulates the parsing operation and execution operation, whereas the Statement and Expression classes encapsulate the actual computational concepts of the language we've implemented. For these three articles on building interpreters, the example language has been BASIC.

Facilities for computation

There are two executable classes in the interpreter, Statement and Expression. First let's take a look at Expression.

The instances of Expression are created by the method expression in the class ParseExpression. The ParseExpression class implements the expression parser in this interpreter. This class is a peer of the ParseStatement class, which uses the statement method to parse BASIC statements. Instances of Expression have an internal type that identifies what operator the instance represents, and two methods, value and stringValue, that return the computed value of the expression. Additionally, when an Expression instance is created, it is nominally given two parameters representing the left and right side of the expression's operation. Shown in source form, the first part of the Expression is as follows:

1 | 2 | 3 | 4 | 5 |  Next >
Resources