Java Design Patterns .

Java Design Patterns Interpreter

Interpreter Overview

Define a macro language and syntax, parsing input into objects which perform the correct opertaions.


DvdInterpreterClient.java - the Client

import java.util.StringTokenizer;

public class DvdInterpreterClient { DvdInterpreterContext dvdInterpreterContext; public DvdInterpreterClient( DvdInterpreterContext dvdInterpreterContext) { this.dvdInterpreterContext = dvdInterpreterContext; } // expression syntax: // show title | actor [for actor | title ] public String interpret(String expression) { StringBuffer result = new StringBuffer("Query Result: "); String currentToken; StringTokenizer expressionTokens = new StringTokenizer(expression); char mainQuery = ' '; char subQuery = ' '; boolean forUsed = false; String searchString = null; boolean searchStarted = false; boolean searchEnded = false; while (expressionTokens.hasMoreTokens()) { currentToken = expressionTokens.nextToken(); if (currentToken.equals("show")) { continue; //show in all queries, not really used } else if (currentToken.equals("title")) { if (mainQuery == ' ') { mainQuery = 'T'; } else { if ((subQuery == ' ') && (forUsed)) { subQuery = 'T'; } } } else if (currentToken.equals("actor")) { if (mainQuery == ' ') { mainQuery = 'A'; } else { if ((subQuery == ' ') && (forUsed)) { subQuery = 'A'; } } } else if (currentToken.equals("for")) { forUsed = true; } else if ((searchString == null) && (subQuery != ' ') && (currentToken.startsWith("<"))) { searchString = currentToken; searchStarted = true; if (currentToken.endsWith(">")) { searchEnded = true; } } else if ((searchStarted) && (!searchEnded)) { searchString = searchString + " " + currentToken; if (currentToken.endsWith(">")) { searchEnded = true; } } }

if (searchString != null) { searchString = searchString.substring(1,(searchString.length() - 1)); //remove <> } DvdAbstractExpression abstractExpression; switch (mainQuery) { case 'A' : { switch (subQuery) { case 'T' : { abstractExpression = new DvdActorTitleExpression(searchString); break; } default : { abstractExpression = new DvdActorExpression(); break; } } break; } case 'T' : { switch (subQuery) { case 'A' : { abstractExpression = new DvdTitleActorExpression(searchString); break; } default : { abstractExpression = new DvdTitleExpression(); break; } } break; } default : return result.toString(); } result.append( abstractExpression.interpret(dvdInterpreterContext)); return result.toString(); } }
To download source right-click here and "Save As...".


DvdInterpreterContext.java - The Context

import java.util.ArrayList;
import java.util.ListIterator;

public class DvdInterpreterContext { private ArrayList titles = new ArrayList(); private ArrayList actors = new ArrayList(); private ArrayList titlesAndActors = new ArrayList(); public void addTitle(String title) { titles.add(title); } public void addActor(String actor) { actors.add(actor); } public void addTitleAndActor(TitleAndActor titleAndActor) { titlesAndActors.add(titleAndActor); } public ArrayList getAllTitles() { return titles; } public ArrayList getAllActors() { return actors; } public ArrayList getActorsForTitle(String titleIn) { ArrayList actorsForTitle = new ArrayList(); TitleAndActor tempTitleAndActor; ListIterator titlesAndActorsIterator = titlesAndActors.listIterator(); while (titlesAndActorsIterator.hasNext()) { tempTitleAndActor = (TitleAndActor)titlesAndActorsIterator.next(); if (titleIn.equals(tempTitleAndActor.getTitle())) { actorsForTitle.add(tempTitleAndActor.getActor()); } } return actorsForTitle; } public ArrayList getTitlesForActor(String actorIn) { ArrayList titlesForActor = new ArrayList(); TitleAndActor tempTitleAndActor; ListIterator actorsAndTitlesIterator = titlesAndActors.listIterator(); while (actorsAndTitlesIterator.hasNext()) { tempTitleAndActor = (TitleAndActor)actorsAndTitlesIterator.next(); if (actorIn.equals(tempTitleAndActor.getActor())) { titlesForActor.add(tempTitleAndActor.getTitle()); } } return titlesForActor; } }
To download source right-click here and "Save As...".


DvdAbstractExpression.java - The Abstract Expression

public abstract class DvdAbstractExpression {
   public abstract String interpret(
     DvdInterpreterContext dvdInterpreterContext);
}
To download source right-click here and "Save As...".


DvdActorExpression.java - One Of Four Terminal Expressions

DvdActorExpression.java - One Of Four Terminal Expressions

import java.util.ArrayList; import java.util.ListIterator;

public class DvdActorExpression extends DvdAbstractExpression { public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList actors = dvdInterpreterContext.getAllActors(); ListIterator actorsIterator = actors.listIterator(); StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (actorsIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)actorsIterator.next()); } return titleBuffer.toString(); } }
To download source right-click here and "Save As...".


DvdActorTitleExpression.java - Two Of Four Terminal Expressions

import java.util.ArrayList;
import java.util.ListIterator;

public class DvdActorTitleExpression extends DvdAbstractExpression { String title; public DvdActorTitleExpression(String title) { this.title = title; } public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList actorsAndTitles = dvdInterpreterContext.getActorsForTitle(title); ListIterator actorsAndTitlesIterator = actorsAndTitles.listIterator(); StringBuffer actorBuffer = new StringBuffer(""); boolean first = true; while (actorsAndTitlesIterator.hasNext()) { if (!first) { actorBuffer.append(", "); } else { first = false; } actorBuffer.append((String)actorsAndTitlesIterator.next()); } return actorBuffer.toString(); } }
To download source right-click here and "Save As...".


DvdTitleExpression.java - Three Of Four Terminal Expressions

import java.util.ArrayList;
import java.util.ListIterator;

public class DvdTitleExpression extends DvdAbstractExpression { public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList titles = dvdInterpreterContext.getAllTitles(); ListIterator titlesIterator = titles.listIterator(); StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (titlesIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)titlesIterator.next()); } return titleBuffer.toString(); } }
To download source right-click here and "Save As...".


DvdTitleActorExpression.java - Four Of Four Terminal Expressions

import java.util.ArrayList;
import java.util.ListIterator;

public class DvdTitleActorExpression extends DvdAbstractExpression { String title; public DvdTitleActorExpression(String title) { this.title = title; } public String interpret(DvdInterpreterContext dvdInterpreterContext) { ArrayList titlesAndActors = dvdInterpreterContext.getTitlesForActor(title); ListIterator titlesAndActorsIterator = titlesAndActors.listIterator(); StringBuffer titleBuffer = new StringBuffer(""); boolean first = true; while (titlesAndActorsIterator.hasNext()) { if (!first) { titleBuffer.append(", "); } else { first = false; } titleBuffer.append((String)titlesAndActorsIterator.next()); } return titleBuffer.toString(); } }
To download source right-click here and "Save As...".


TitleAndActor.java - A Helper Class

public class TitleAndActor {
    private String title;
    private String actor;
    public TitleAndActor(String title, String actor) {
        this.title = title;
        this.actor = actor;
    }
    public String getTitle() {return this.title;}
    public String getActor() {return this.actor;}
} 
To download source right-click here and "Save As...".


TestDvdInterpreter.java - testing the Interpreter

class TestDvdInterpreter {
    
   public static void main(String[] args) {
       DvdInterpreterContext dvdInterpreterContext = 
         new DvdInterpreterContext();
       dvdInterpreterContext.addTitle("Caddy Shack");
       dvdInterpreterContext.addTitle("Training Day");
       dvdInterpreterContext.addTitle("Hamlet");

dvdInterpreterContext.addActor("Ethan Hawke"); dvdInterpreterContext.addActor("Denzel Washington"); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Hamlet", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Training Day", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Caddy Shack", "Ethan Hawke")); dvdInterpreterContext.addTitleAndActor( new TitleAndActor("Training Day", "Denzel Washington")); DvdInterpreterClient dvdInterpreterClient = new DvdInterpreterClient(dvdInterpreterContext); System.out.println( "interpreting show actor: " + dvdInterpreterClient.interpret( "show actor")); System.out.println( "interpreting show actor for title : " + dvdInterpreterClient.interpret( "show actor for title ")); System.out.println( "interpreting show title: " + dvdInterpreterClient.interpret( "show title")); System.out.println( "interpreting show title for actor : " + dvdInterpreterClient.interpret( "show title for actor ")); } }
To download source right-click here and "Save As...".


Test Results

interpreting show actor: 
  Query Result: Ethan Hawke, Denzel Washington
interpreting show actor for title : 
  Query Result: Ethan Hawke, Denzel Washington
interpreting show title: 
  Query Result: Caddy Shack, Training Day, Hamlet
interpreting show title for actor : 
  Query Result: Hamlet, Training Day, Caddy Shack

UML

UML for Interpreter

References


online
Portland Pattern Repository
Books
Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
Java Design Patterns - A Tutorial by James W. Cooper
Comments Comments are left by visitors to FluffyCat.com and may or may not be accurate.
Comment by markmontymark on 2008-04-16 Rate this Comment

replace the '<' char with &lt; and the '>' char with &gt; to display properly in HTML

Comment by archive on 2007-09-28 Rate this Comment

I realy appreciate the Java Patterns on your site. Since I like to play with the examples I simply copied it into text fils and compiled them. I found a few minor problems you may want to know about:

- null pointer exception for second example, I did
not yet try to find out what the real reason is.

interpreting show actor: Query Result: Ethan
Hawke,
Denzel Washington
Exception in thread "main"
java.lang.NullPointerException at
DvdInterpreterContext.getActorsForTitle(DvdInterpreterContext.java:24)
at
DvdActorTitleExpression.interpret(DvdActorTitleExpression.java:12)
at
DvdInterpreterClient.interpret(DvdInterpreterClient.java:106)
at
TestDvdInterpreter.main(TestDvdInterpreter.java:28)

Comment by archive on 2007-09-28 Rate this Comment

Ah, I also see now why the Interpreter example
gets a null pointer exception:

two lines in main() should contain the < >
construction:
dvdInterpreterClient.interpret("show actor for
title <Training Day>"));
...
dvdInterpreterClient.interpret("show title for actor
<Ethan Hawke>"));

However, since you show it in HTML, the browser is
not displaying it since it interprets them as
tags (which it does not know how to display)

 
Sign in to comment on Java Design Patterns Interpreter.