GoF Definition: Given a language, define a representation for its grammar along with an interpreter that uses the representation to interpret sentences in the language.
Here, in general, we define a grammatical representation for a language and provide an interpreter to deal with that grammar (e.g., in our example we have interpreted a string input as binary data). In simple words, this pattern says how to evaluate sentences in a language.
A language translator who translates a language for us provides a classic example for this pattern. Or, we can also consider music notes as our grammar and musicians as our interpreters.
A Java compiler interprets the source code into byte code. This byte code is understandable by JVM (Java virtual machine). In C# also, our source code is converted to MSIL (Microsoft intermediate language) code, which is interpreted by CLR (common language runtime). Upon execution, this MSIL (intermediate code) is converted to native code (binary executable code) by a JIT (Just In time) compiler.
Here we need to create an interpreter context engine for our interpretation work. Then we need to create an expression implementation (ideally we should have more implementations—e.g., here we may also be interested in converting the data to hexadecimal or any other format) that will consume the functionality provided by the interpreter context. At last we have created the client who will accept the user input to generate the required output. The client here will also decide which expression to use if we have more than one expression. Go through the example now. Here we have two choices: we can interpret an input string (basically a decimal number) as binary data or we can simply interpret it and print the digits in the input into their equivalent English words.
High-level structure of the parts of the program is as follows:
package interpreter.pattern.demo;
import java.util.Scanner;
/*Context class: interpretation is carried out based on our implementation.*/
class Context
{
public String input;
public Context(String input)
{
this.input=input;
}
public void getBinaryForm(String input)
{
int i = Integer.parseInt(input);
//integer to its equivalent binary string representation
String binaryString = Integer.toBinaryString(i);
System.out.println("Binary equivalent of "+input+ " is "+ binaryString);
}
public void printInWords(String input)
{
this.input = input;
System.out.println("Printing the input in words:");
char c[]=input.toCharArray();
for(int i=0;i<c.length;i++)
{
switch (c[i])
{
case ’1’:
System.out.print("One ");
break;
case ’2’:
System.out.print("Two ");
break;
case ’3’:
System.out.print("Three ");
break;
case ’4’:
System.out.print("Four ");
break;
case ’5’:
System.out.print("Five ");
break;
case ’6’:
System.out.print("Six ");
break;
case ’7’:
System.out.print("Seven ");
break;
case ’8’:
System.out.print("Eight ");
break;
case ’9’:
System.out.print("Nine ");
break;
case ’0’:
System.out.print("Zero ");
break;
default:
System.out.print("* ");
break;
}
}
}
}
interface IExpression
{
void interpret(Context ic);
}
class StringToBinayExp implements IExpression
{
private String str;
public StringToBinaryExp(String s)
{
str = s;
}
@Override
public void interpret(Context ic)
{
ic.getBinaryForm(str);
}
}
class IntToWords implements IExpression
{
private String str;
public IntToWords(String str)
{
this.str = str;
}
@Override
public void interpret(Context ic)
{
ic.printInWords(str);
}
}
class InterpreterPatternEx
{
public Context clientContext=null;
public IExpression exp=null;
public InterpreterPatternEx(Context c)
{
clientContext = c;
}
public void interpret(String str)
{
//We’ll test 2 consecutive inputs at a time
for(int i=0;i<2;i++){
System.out.println(" Enter ur choice(1 or 2)");
Scanner in = new Scanner(System.in);
String c = in.nextLine();
if (c.equals("1"))
{
exp = new IntToWords(str);
exp.interpret(clientContext);
}
else
{
exp = new StringToBinaryExp(str);
exp.interpret(clientContext);
}
}
}
public static void main(String[] args)
{
System.out.println(" ***Interpreter Pattern Demo*** ");
System.out.println("Enter a number :");
Scanner in = new Scanner(System.in);
String input = in.nextLine();
Context context=new Context(input);
InterpreterPatternEx client = new InterpreterPatternEx(context);
client.interpret(input);
}
}