Presentation is loading. Please wait.

Presentation is loading. Please wait.

Unit 27 Interpreter Summary prepared by Kirk Scott 1.

Similar presentations


Presentation on theme: "Unit 27 Interpreter Summary prepared by Kirk Scott 1."— Presentation transcript:

1 Unit 27 Interpreter Summary prepared by Kirk Scott 1

2 Design Patterns in Java Chapter 25 Interpreter Summary prepared by Kirk Scott 2

3 Introduction The interpreter design pattern is related to the command pattern The Interpreter design pattern can be used to make objects where the objects are like individual commands Different kinds of commands are implemented as different classes Each of these classes has a method of the same name, something like execute() 3

4 The difference in the command objects consists of the fact that the code for the execute() method differs among the different command classes In this respect the pattern is like lots of other patterns You have many different implementations of methods with the same name Polymorphism and dynamic binding sort out which version applies 4

5 The Interpreter pattern is also related to the composite pattern A structured program consists of sequences of statements It can also contain macros or subroutines The macros or subroutines are collections of sequences of statements 5

6 A complete application of the Interpreter pattern will allow multiple commands to be put together into a composite Individual leaf items will be single statements and composite nodes will be (sub)sequences of statements 6

7 Book Definition of Pattern Book definition: The intent of the Interpreter pattern is to let you compose executable objects according to a set of composition rules that you define. 7

8 An Interpreter Example The book illustrates the Interpreter design pattern using the robots that transport material between machines and that can load and unload the machines The general idea is that the interpreter pattern makes it possible, in a general-purpose Java environment, to write/assemble/put together/compose what are conceptually programs in the domain of machine management 8

9 The UML diagram on the following overhead shows a Robot class and a small hierarchy of commands The command hierarchy is the same in structure as a composite hierarchy 9

10 10

11 There is an abstract method, execute(), at the top of the command hierarchy in the UML diagram It is concretely implemented in the two subclasses The CommandSequence class also has an add() method for building up composite sequences of instructions 11

12 The CarryCommand class has a constructor, which takes two machines as input parameters There are corresponding instance variables for these references in the CarryCommand class The execute() method of CarryCommand ultimately will cause the material to be carried from one machine to the other by a robot 12

13 What part of the UML diagram represents the interpreter? The composite command hierarchy in its entirety is in essence the interpreter 13

14 Example Code that Uses the Classes Given so Far The book does not start by showing the code for the command hierarchy It starts with the ShowIntepreter program, which uses the commands Several things happen in the program It obtains a machine composite object for the factory in Dublin, Ireland 14

15 It obtains three references to specific machines at the factory It loads bins into the machines It construct two instances of CarryCommand using these machines as input parameters 15

16 It constructs an instance of CommandSequence and adds the individual commands Finally, it calls execute() on the sequence object It is this one, final line of code which controls the robot/machines in the factory 16

17 In essence, the whole machine control program has been packaged up in the one object and the one call to the execute() method In other words, the interpreter pattern is illustrated by packaging a complete sequence of machine/robot commands in a single instance of the CommandSequence class The code is given on the following overhead 17

18 public class ShowInterpreter { public static void main(String[] args) { MachineComposite dublin = OozinozFactory.dublin(); ShellAssembler assembler = (ShellAssembler) dublin.find("ShellAssembler:3302"); StarPress press = (StarPress) dublin.find("StarPress:3404"); Fuser fuser = (Fuser) dublin.find("Fuser:3102"); assembler.load(new Bin(11011)); press.load(new Bin(11015)); CarryCommand carry1 = new CarryCommand(assembler, fuser); CarryCommand carry2 = new CarryCommand(press, fuser); CommandSequence seq = new CommandSequence(); seq.add(carry1); seq.add(carry2); seq.execute(); } 18

19 Code for the CommandSequence Class The code for the CommandSequence (composite) class will be given on the overhead following the next one The CommandSequence class has an ArrayList of commands The add() method allows commands to be added 19

20 The execute() method looks like the methods, like isTree(), in the composite design pattern It iterates over all of the elements of the ArrayList calling execute() on them If the element is a leaf, then the version of execute() in the CarryCommand class is used If the element is a composite, then the call is recursive 20

21 public class CommandSequence extends Command { protected List commands = new ArrayList(); public void add(Command c) { commands.add(c); } public void execute() { for (int i = 0; i < commands.size(); i++) { Command c = (Command) commands.get(i); c.execute(); } 21

22 Code for the CarryCommand Class The CarryCommand class has references to two machines It has a constructor that takes two machine references as input parameters It has an execute() method execute() calls carry() on the single instance of Robot maintained in the Robot class, passing the machine references as parameters to this method The code is shown on the following overhead 22

23 public class CarryCommand extends Command { protected Machine fromMachine; protected Machine toMachine; public CarryCommand(Machine fromMachine, Machine toMachine) { this.fromMachine = fromMachine; this.toMachine = toMachine; } public void execute() { Robot.singleton.carry(fromMachine, toMachine); } 23

24 Adding Different Types of Commands to the Pattern The Interpreter can be expanded by adding more subclasses to the Command hierarchy Each different command will package up a different action in its execute() method This generalizes the kind of program for machine control that the interpreter pattern can generate 24

25 In addition to the CarryCommand, there might be a StartUpCommand and a ShutDownCommand In addition to simple commands, there might be commands that reflect the structure of a programming language This is where the complexity starts to set in 25

26 A “for” Looping Command The tree-like structure of the composite makes it possible to model a macro or subroutine This is a sequence of commands which is run once when it’s called A complete programming language also allows iteration A loop consists of a sequence of commands which is potentially run more than once when it’s encountered 26

27 The book introduces the idea of a ForCommand into the Command hierarchy The ForCommand class implements the logic of a for each loop The UML diagram for the expanded interpreter is shown on the next overhead It includes the StartUpCommand, ShutDownCommand, and ForCommand classes Explanations follow 27

28 28

29 The UML diagram shows an arrow from the ForCommand class to the Command class An instance of ForCommand will have a reference to another command This other command is the body of the for each loop It can be a single command or an instance of CommandSequence 29

30 Adding Variables to the Language Which the Interpreter Handles Something that works like a for each loop depends on a variable You repeat the execution of the body But what is it you’re iterating over? You need a variable that’s a stand-in for the things you’re iterating over 30

31 The syntax of a simple Java for each loop was given in Unit 9 of CS 202 with this example: for(Cup7 someCup: mycollection) { myterminal.println(someCup); } 31

32 mycollection is an ArrayList of cups someCup is a variable that is declared as part of the syntax of the loop It represents the single instance of mycollection that you refer to during a given iteration through the loop A variable that works like someCup will be needed to making the ForCommand work 32

33 The constructor for the ForCommand class will take 3 parameters: 1. A collection (tree) of machines, the objects to iterate over 2. Something typed as a variable, to hold the reference to a machine in the collection during the execution of the loop 3. A command (possibly composite), the body of the loop 33

34 Adding Variables to the Interpreter Adding variables to the interpreter is a significant change It will take several overheads to discuss variables before returning to the implementation of ForCommand The classes needed to include variables are shown in the UML diagram on the following overhead 34

35 35

36 What is a Term? The UML diagram has an abstract Term class at the top of the hierarchy The concrete classes under it are Variable and Constant Empirically, a term is either a variable or a constant More theoretically, a term is an identifier that a programming language deals with 36

37 The system works with machines Constants are objects with references to machines Variables are objects that define an identifier and have machines associated with them 37

38 The Constant Class The Constant class is basically a wrapper for a Machine reference A constant is constructed with a machine as the input parameter The Constant class has an equals() method, which tests to see whether two constants are in fact the same machine 38

39 It also has an eval() method which is essentially like a get() method This method returns whatever machine the constant happens to contain 39

40 The code for the Constant class is given on the following overhead Most of the methods are straightforward I would observe that the coding style for the equals() method is somewhat like the orange book’s (and I don’t care for it) 40

41 public class Constant extends Term { protected Machine machine; public Constant(Machine machine) { this.machine = machine; } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj.getClass() == this.getClass())) return false; Constant that = (Constant) obj; return this.machine.equals(that.machine); } 41

42 public int hashCode() { return machine.hashCode(); } public Machine eval() { return machine; } public String toString() { return machine.toString(); } 42

43 The Variable Class The Variable class has a Term instance variable The class can be thought of as a wrapper for a Term reference The class also has a String instance variable This String is the name of the variable In other words, this is an identifier The variable class consists of a value and a name associated with it 43

44 The Term instance variable holds whatever value is assigned to the variable by a call to the assign() method A constant or the contents of another variable can be assigned to a variable in this way The variable class also has an eval() method This method returns the value of the Term that has been assigned to the variable 44

45 The Variable class has an equals() method It is important to notice that equals() is not testing for equality of the values assigned to variables It is testing for whether or not the variables themselves are the same This is done by testing for equality of the names of variables 45

46 The code for the Variable class is given on the following overhead The coding style for the equals() method is again not ideal 46

47 public class Variable extends Term { protected String name; protected Term value; public Variable(String name) { this.name = name; } public String getName() { return name; } public void assign(Term term) { this.value = term; } 47

48 public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Variable)) return false; Variable v = (Variable) o; return name.equals(v.name); } 48

49 public int hashCode() { return name.hashCode(); } public Machine eval() { return value.eval(); } public String toString() { return name + ": " + value; } 49

50 Generalizing Simpler Commands by Using Terms If you introduce variables, the whole language the interpreter implements will be affected The book isn’t ready yet to show the use of variables in the implementation of the ForCommand class First it shows how some of the simpler commands could be generalized by using references to terms 50

51 Commands can then be used with variables which refer to machines rather than with machine references themselves Whenever a term is used, it is resolved to a machine reference by calling eval() on it The CarryCommand class rewritten using terms is shown on the following overhead 51

52 public class CarryCommand extends Command { protected Term from; protected Term to; public CarryCommand(Term fromTerm, Term toTerm) { from = fromTerm; to = toTerm; } public void execute() { Robot.singleton.carry(from.eval(), to.eval()); } 52

53 On the next overhead, code for a StartUpCommand class is given which uses terms The same approach is used as for the CarryCommand Whenever a term is used, it is resolved to a machine reference by calling eval() 53

54 public class StartUpCommand extends Command { protected Term term; public StartUpCommand(Term term) { this.term = term; } public void execute() { Machine m = term.eval(); m.startup(); } 54

55 What Do You Gain from Using Terms? It’s not clear what you’ve gained by this since everything has to resolve to a machine Suppose that machines come from vendors with a proprietary control language A fully-fledged machine control language would have variables 55

56 Your goal is to parse and interpret statements in that language so that you can integrate machine control programs into your Java code base In order to translate machine control code, the interpreter would also have to have variables 56

57 Writing the Code for the ForCommand Class The motivation for introducing variables was the need to support looping The book now tackles the topic of how to write the ForCommand class Adding this to the interpreter is not trivial 57

58 The book presents partial code The most difficult part of the implementation is reserved as a challenge Rather than doing this as a challenge, the complete code will be given, broken up with explanations 58

59 An outline of the constructor for ForCommand was given earlier It is repeated on the following overhead 59

60 The constructor for the ForCommand class will take 3 parameters: 1. A collection of machines, the objects to iterate over 2. Something typed as a variable, to hold the reference to a machine in the collection during the execution of the loop 3. A command, the body of the loop 60

61 The following overhead shows the instance variables and the constructor of the ForCommand class There is an instance variable for each of the construction parameters The thing you’re iterating over is named root It is the root of a component/composite of machines 61

62 public class ForCommand extends Command { protected MachineComponent root; protected Variable variable; protected Command body; public ForCommand(MachineComponent mc, Variable v, Command body) { this.root = mc; this.variable = v; this.body = body; } 62

63 The rest of the ForCommand class consists of two execute() methods, one that takes a parameter and one that doesn’t In this sense, these execute() methods are like the isTree() methods in the composite Client code, for example, can call the version without the parameter These two methods will be considered next 63

64 Here is the execute() method that doesn’t take a parameter: public void execute() { execute(root); } 64

65 It is possible to call execute() on an instance of ForCommand without having to pass in a parameter because the root is set at construction time The parameter-less version of execute() will also be used in the implementation of execute() that does take a parameter 65

66 The version of execute() that does take a parameter is recursive It contains a base, non-recursive case It also contains a recursive case It calls the version of execute() without a parameter in the base case It calls itself, the version with the parameter, in the recursive case 66

67 More code is given on the following overhead The declaration line of the execute() method with a parameter is shown This is followed by the recursive case Some comments have been added 67

68 private void execute(MachineComponent mc) { if (mc !instanceof Machine) /* If what you’ve reached isn’t a Machine, it’s a composite. */ MachineComposite comp = (MachineComposite) mc; /* Iterate over the components in the composite. */ List children = comp.getComponents(); for (int i = 0; i < children.size(); i++) { MachineComponent child = (MachineComponent) children.get(i); /* Call execute(), passing in each component (child) in the list. If the component is a Machine, it will hit the base case. If the component is a Composite, it will hit this case and recur. The child is passed because it’s the root of the new recursion. */ execute(child); } 68

69 More code is given on the following overhead The non-recursive, base case of the version of execute() with a parameter is shown Some comments have been added 69

70 else { Machine m = (Machine) mc; /* Set the iterator variable to the individual Machine you’ve encountered. */ variable.assign(new Constant(m)); /* Execute the body of the loop (once) for this individual machine. */ body.execute(); return; } 70

71 How the Looping Variable Works The base case is where you’ve reached a leaf in the tree you’re iterating over This is where a single execution of the body of the loop occurs This is also where the loop variable appears Neither the loop variable nor the body appear in either the parameter-less execute() method or in the recursive case of the one with a parameter 71

72 Concretely, this is how the variable takes on the value of the current, leaf object that you’ve iterated to: variable.assign(new Constant(m)); The variable object is constructed in client code and passed in as a construction parameter to the ForCommand object The object that “variable” refers to exists independently of ForCommand and is merely being assigned a particular value here 72

73 Concretely, this is how the body of the loop is executed: body.execute(); The burning question is this: What is the connection between the leaf object that you’ve reached during iteration and the execution of the body? The execution of the body should depend on the leaf. If the execution of the body doesn’t depend on the leaf, then you would just be executing exactly the same body statements x times, where x is the number of leaves in the tree you’re iterating over 73

74 There should be and is a connection between the variable and the body It comes in the client code, not in the ForCommand code Recall that a ForCommand object is constructed with a root, a variable, and a body The body itself is constructed with a reference to the variable 74

75 This only becomes apparent when you reach the book’s next example, which illustrates the use of ForCommand Look at the third parameter, the construction of the body, in the construction of the ForCommand: Command c = new ForCommand(dublin, v, new ShutDownCommand(v)); 75

76 Recall that originally the ShutDownCommand took a machine as its construction parameter It was then rewritten to take a variable as its construction parameter Either way, this is the way it works: You call execute() without a parameter on a ShutDownCommand object, and it shuts down the machine that it was constructed with 76

77 Look at the lines of code in sequence again: In the client: Command c = new ForCommand(dublin, v, new ShutDownCommand(v)); In the base case of ForCommand: variable.assign(new Constant(m)); body.execute(); The effect is that the execution of the body will shut down the machine that you are currently on in the iteration 77

78 What is going on is not very easy to see The reason is that for all practical purposes, encapsulation is being violated v is passed into ShutDownCommand, but a reference to v is saved and passed on to ForCommand Then in ForCommand, a call is made which directly affects v (the assignment) without going through a method belonging to ShutDownCommand 78

79 Another way of looking at the situation is that ShutDownCommand and ForCommand share an instance variable This is intentional on the author’s part It allows them to accomplish what they want to accomplish 79

80 But it’s still a violation of encapsulation, making for code that’s hard to understand, and for that reason, dangerous It might be possible to treat v as inherently part of the body object Then in the ForCommand code, you could call a set method for v on that object rather than changing the value of a passed reference At that point, it may not be necessary to keep v as an instance variable in ForCommand 80

81 An Example Program that Uses ForCommand The book next gives the complete little program that uses the ForCommand, which the single line of code given previously was taken from The ForCommand iterates over all of the machines in the factory The body of the loop consists of a call to a ShutDownCommand with the current machine as its parameter The code is given on the next overhead 81

82 public class ShowDown { public static void main(String[] args) { MachineComposite dublin = OozinozFactory.dublin(); Variable v = new Variable("machine"); Command c = new ForCommand(dublin, v, new ShutDownCommand(v)); c.execute(); } 82

83 The previous example is mainly just a reminder of the power of iteration However, it also serves the purpose of beginning to illustrate the power of the Interpreter design pattern Instead of having to hand code the shutdown of every machine, it is possible to do this by constructing and executing a single instance of the ForCommand class 83

84 Adding More Control Commands Continuing with the development of the Interpreter design pattern: An interpreter would become even more complete by adding commands like IfCommand and WhileCommand which are additional constructs of high level languages Both of these constructs require the ability to test a condition that will give a boolean result 84

85 The book hints that the way to do this might be to develop a new hierarchy of boolean classes However, the authors opt to put the new classes into the Term hierarchy they already introduced It’s hard to say which alternative is better 85

86 The book’s approach has the obvious advantage of not requiring that a new hierarchy be developed It also has the apparent disadvantage that the classes in the hierarchy don’t necessarily seem related However, it does work because the new classes will be based on an eval() method, and that’s the method that Variable and Constant classes were based on 86

87 boolean results will be modeled using this technique: The eval() method will be typed to return a reference to a machine If eval() returns null, this will signify false If eval() returns a reference to an actual machine, that will signify true The UML diagram on the next overhead shows the new Term hierarchy with an Equals and a HasMaterial class added to it 87

88 88

89 The Equals Class The Equals class has a constructor that takes in two terms as parameters The eval() method doesn’t take in any parameters The eval() method of the Equals class uses the eval() method of the Term class to convert its instance variable terms to machine references 89

90 It then uses the equals() method of the Machine class to test for equality It returns the reference to the first machine if the two machines are equal, and returns null if they’re not equal The code is shown on the following overhead 90

91 public class Equals extends Term { protected Term term1; protected Term term2; public Equals(Term term1, Term term2) { this.term1 = term1; this.term2 = term2; } public Machine eval() { Machine m1 = term1.eval(); Machine m2 = term2.eval(); return m1.equals(m2) ? m1 : null; } 91

92 The HasMaterial Class The HasMaterial class has a constructor that takes in one Term as a parameter and initializes an instance variable named term The eval() method doesn’t take in any parameters It uses the eval() method of the Term class to convert its instance variable term to a machine reference 92

93 It then uses the hasMaterial() method of the Machine class to see whether the machine has any material It returns the reference to the machine if it has material, and returns null if it doesn’t The code is shown on the following overhead 93

94 public class HasMaterial extends Term { protected Term term; public HasMaterial(Term term) { this.term = term; } public Machine eval() { Machine m = term.eval(); return m.hasMaterial() ? m : null; } 94

95 The NullCommand Class If you’re going to have if statements, it is helpful to also have a null command This represents the situation where you have either an empty if or an empty else In practice, this is just a command where the execute() method itself is empty Code for a NullCommand class is shown on the next overhead 95

96 public class NullCommand extends Command { public void execute() { } 96

97 If and While With boolean conditions modeled, it’s possible to add an IfCommand and a WhileCommand to the Command hierarchy The UML diagram on the next overhead shows this Note that just like with ForCommand, IfCommand and WhileCommand have a reference to another command This other command will be the body of the if statement or the while statement, respectively 97

98 98

99 The IfCommand Class The book does the completion of the code for the IfCommand, and the entirety of the code for the WhileCommand as challenges As usual, it’s easiest not to bother with incomplete code and to go directly to the challenges and their solutions 99

100 Challenge 25.2 Complete the code in the execute() method of the IfCommand class. Solution 25.2 One solution is: [See the complete code on the following overhead.] 100

101 public class IfCommand extends Command { protected Term term; protected Command body; protected Command elseBody; public IfCommand(Term term, Command body, Command elseBody) { this.term = term; this.body = body; this.elseBody = elseBody; } public void execute() { if (term.eval() != null) body.execute(); else elseBody.execute(); } 101

102 The WhileCommand Class Challenge 25.3 Write the code for the WhileCommand class. Solution 25.3 One way to write WhileCommand.java is: [See the code on the following overhead.] 102

103 public class WhileCommand extends Command { protected Term term; protected Command body; public WhileCommand(Term term, Command body) { this.term = term; this.body = body; } public void execute() { while (term.eval() != null) body.execute(); } 103

104 Once you start getting used to the Interpreter design pattern, the code for these command classes doesn’t seem too difficult The execute() method “wraps” the logic for if and while, using terms and bodies as stand-ins for whatever actual items and actions come from the problem domain 104

105 The IfCommand is simple because no variable is involved The WhileCommand appears simple because no variable is involved, but it has complexity similar to that in ForCommand Execution of the body has to have some effect on the Term; otherwise, the value of the looping condition would never change 105

106 An example of the use of WhileCommand will be given next As with ForCommand, the connection between the looping elements is made in the client code, not the WhileCommand code 106

107 Using the WhileCommand Class The code for the ShowWhile program is given on the following overhead It uses the WhileCommand Its logic is that while the star press has material, that material will be carried to the fuser 107

108 public class ShowWhile { public static void main(String[] args) { MachineComposite dublin = OozinozFactory.dublin(); Term starPress = new Constant((Machine) dublin.find("StarPress:1401")); Term fuser = new Constant((Machine) dublin.find("Fuser:1101")); starPress.eval().load(new Bin(77)); starPress.eval().load(new Bin(88)); WhileCommand command = new WhileCommand( new HasMaterial(starPress), new CarryCommand(starPress, fuser)); command.execute(); } 108

109 The connection between the term and the body can be seen in the line of code where the WhileCommand is constructed The parameters for that construction are themselves constructed in place The connection consists of the fact that both the term and the body take the star press as their construction parameter This is shown on the following overhead 109

110 This is the construction of the WhileCommand WhileCommand command = new WhileCommand( new HasMaterial(starPress), new CarryCommand(starPress, fuser)); This is what happens when the WhileCommand is executed: public void execute() { while (term.eval() != null) body.execute(); } 110

111 Execution of the body means execution of the carry command Carrying material should eventually remove all material from the start press At that point, term.eval() will return null (false) 111

112 The Difference Between Command and Interpreter Challenge 25.4 Close this book and write down a short explanation of the difference between Command and Interpreter. 112

113 Solution 25.4 One answer is: The intent of the Interpreter pattern is to let you compose executable objects from a hierarchy of classes that provide various interpretations of a common operation. The intent of Command is merely to encapsulate a request in an object 113

114 Solution 25.4, cont’d. Can an interpreter object function as a command? Sure! The question of which pattern applies depends on your intent. Are you creating a toolkit for composing executable objects, or are you encapsulating a request in an object? 114

115 Comment mode on: I would summarize my own answer in this way: If you are trying to build up a hierarchy of command classes that wrap a set of programming language constructs, then you’re using the Interpeter design pattern If you are trying to wrap a single command for one-shot use, then you’re using the Command pattern 115

116 Why Use the Interpreter Pattern? The point of using the interpreter pattern may not be clear Why not just write the code for machine and robot control programs? The book’s scenario is as follows You may have a simple high-level language that was designed for machine and robot control 116

117 The book gives this as a pseudo-code example of a program in that language: for(m in factory) if(not(m is unloadBuffer)) ub = findUnload for m while(m hasMaterial) carry(m, ub) 117

118 Then, in theory, you could write a parser program that took machine control programs as input and created interpreter objects as output In other words, you wouldn’t have to handcode a program like ShowInterpreter; the parser would do it for you 118

119 Of course, this added step is not simple The reality is that the task of writing a parser that would translate into interpreter objects would be far from trivial Once you realize that a parser would be needed before the pattern could be profitably employed, you’re back to wondering how useful the pattern is 119

120 If you did have the parser, the benefit you would gain is that users would not have to code in Java They could code in the machine control language and the parser/interpreter combination would produce Java programs that implemented the machine control programs written by users 120

121 Another Example The UML diagram on the following overhead is intended to serve as a definition of a simple assembly language A program in the language consists of a sequence (an ArrayList) of commands The commands consist of things like moves, arithmetic, and jumps This visual definition is based on the ideas of composite and interpreter used in this unit 121

122 122

123 Lasater’s UML Lasater’s diagram is shown on the following overhead To its advantage, it does show a context, or client It focuses on those types of commands that have references to other commands, to the exclusion of simple commands All in all, I prefer the diagrams of the book’s examples 123

124 124

125 Summary The Interpreter design pattern is based on a hierarchy of command classes The names of the command classes suggest what it is they do Each class implements an execute() method The implementation should correspond to the name of the class 125

126 The class constructors should take the needed input parameters The execute method should then work on instance variables and not need input parameters Some of the commands will be simple actions Another (composite) command will make it possible to compose multiple simple commands into a sequence 126

127 The interpreter design pattern may be accompanied by a hierarchy that defines terms for variables, booleans, etc. This will support the addition of things like for, if, and while commands In order to be practical, interpreters may also be used along with parsers, although how parsing works wasn’t really covered in the chapter 127

128 The End 128


Download ppt "Unit 27 Interpreter Summary prepared by Kirk Scott 1."

Similar presentations


Ads by Google