When you develop a computer language, you must also develop a way for your users to access it. Package sjm.examples.logic includes the class LogikusIde , which provides an interactive development environment for creating and querying Logikus programs. Chapter 13, "Logic Programming," shows this IDE many times. This class is one of five classes that collaborate to make the Logikus language available to a user , as Figure 14.4 shows.
Figure 14.4. Collaborating classes connect a user to the language. The classes shown work together to make the Logikus language available to a user.
The classes LogikusIDE and LogikusMediator work as a pair to create a Swing interface for Logikus programming. The IDE class contains methods that create Swing components , such as programArea() and proveNextButton() . The mediator class follows the mediator pattern [Gamma et al.] and contains methods that respond to Swing events. Components such as the Rest button in the IDE register the mediator as their event listener. The mediator uses LogikusFacade to simplify its use of the Logikus parser. Figure 14.5 shows a typical message sequence.
Figure 14.5. A typical message sequence. When the user clicks the Rest button on the IDE, the mediator, which is listening for button events, receives an actionPerformed() message. The mediator uses a facade, which in turns uses a parser, to convert the text to an object of class Program .
When a user clicks a button in the Logikus IDE, the button notifies its listener, which is a LogikusMediator object. The mediator determines which action the user took and responds accordingly . If the program text has changed, the mediator parses the text of both the program and the query. Instead of working directly with a Logikus parser object, the mediator uses an object of class LogikusFacade .
14.4.1 A Facade for Logikus
The intent of the facade pattern [Gamma et al.] is to provide an interface that makes a subsystem easier to use. The LogikusFacade class simplifies the parsing of a Logikus program by breaking it into separate axioms and using a Logikus parser object to parse each axiom . The facade also provides a method for parsing a query, and it handles exceptions that the parser may throw.
The Logikus parser class uses Track objects in place of Sequence objects in many of its subparsers. A Track object is identical to a Sequence object except that it throws an exception if a sequence begins but does not conclude. For example, feeding the query
to a Logikus parser causes the parser to throw a TrackException . The mediator catches this and displays:
After : city ( denver , Expected: term Found : ,
The facade also throws informative exceptions when it detects problems. For example, a query that begins with an uppercase letter is invalid. The facade checks for this common error and throws a corresponding exception. Entering the query
results in the IDE message
> Uppercase City indicates a variable and cannot begin a query.
The facade sees the problem with the capital letter and throws a LogikusException . The mediator catches this exception (and any other exception) and displays the message's text.