Implementation of custom language-interpreter mode (5)

Source: Internet
Author: User

18.5 talk about the role of Context
In the interpreter mode, Context is used to store global information other than the interpreter. It is usually passed as a parameter to the Interpretation Method interpret () of all expressions, you can store and access the state of the expression interpreter in the Context object, and provide the expression interpreter with some global and public data, in addition, you can add some functions shared by all expression interpreters in Context to reduce the responsibilities of the interpreter.
In the preceding robot control program instance, we omit the environment role. Next we will use a simple example to describe the purpose of the environment:
Sunny software company developed a set of simple character interface-based formatting commands, which can output some formatting content on the Character interface according to the input commands, for example, input "LOOP 2 PRINT Yang Guo space print little dragon girl break end print Guo Jing space print Huang Rong" and output the following results:
Young lady
Young lady
Guo Jing Huang Rong
Here, the keyword LOOP indicates "LOOP", and the subsequent number indicates the number of cycles; PRINT indicates "PRINT", and the subsequent string indicates the printed content; SPACE indicates "SPACE "; BREAK indicates "line feed"; END indicates "loop END ". Each keyword corresponds to a command, and the computer program executes corresponding processing operations based on the keyword.
The interpreter mode is used to design and interpret the formatted command, analyze the command, and call each command in the corresponding operation execution command.
Through analysis, Sunny software company Developers define the following grammar rules according to the sentence composition in the format instruction:
Expression: = command * // expression. An expression contains multiple commands.
Command: = loop | primitive // statement command
Loop: = 'loopnumber' expression 'end' // loop command, where number is a natural number
Primitive: = 'printstring' | 'space' | 'Break' // basic command, where string is a string
Based on the above grammar rules, through further analysis, draw the structure diagram shown in 18-6:

Figure 18-6 structure of the formatting command
In Figure 18-6, Context acts as the environment, Node acts as the abstract expression, ExpressionNode, CommandNode, and LoopCommandNode act as non-terminator expressions, and PrimitiveCommandNode acts as the terminator expression. The complete code is as follows:
[Java]
Import java. util .*;
 
// Environment class: used to store and operate the statements to be interpreted. In this instance, each word to be interpreted can be called an Action Token or command
Class Context {
Private StringTokenizer tokenizer; // StringTokenizer class, which is used to break a string into smaller string tokens. By default, a space is used as the separator.
Private String currentToken; // mark the current String

Public Context (String text ){
Tokenizer = new StringTokenizer (text); // creates a StringTokenizer object through an input command string
NextToken ();
}

// Return the next tag
Public String nextToken (){
If (tokenizer. hasMoreTokens ()){
CurrentToken = tokenizer. nextToken ();
}
Else {
CurrentToken = null;
}
Return currentToken;
}

// Returns the current tag
Public String currentToken (){
Return currentToken;
}

// Skip a flag
Public void skipToken (String token ){
If (! Token. equals (currentToken )){
System. err. println ("error prompt:" + currentToken + "error! ");
}
NextToken ();
}

// If the current tag is a number, the corresponding value is returned.
Public int currentNumber (){
Int number = 0;
Try {
Number = Integer. parseInt (currentToken); // converts a string to an Integer.
}
Catch (NumberFormatException e ){
System. err. println ("error prompt:" + e );
}
Return number;
}
}
 
// Abstract node class: Abstract Expression
Abstract class Node {
Public abstract void interpret (Context text); // declare a method for interpreting statements
Public abstract void execute (); // declare a method to execute the corresponding command
}
 
// Expression node class: Non-terminator expression
Class ExpressionNode extends Node {
Private ArrayList <Node> list = new ArrayList <Node> (); // defines a set to store multiple commands.

Public void interpret (Context context ){
// Cyclically process the tag in the Context
While (true ){
// Exit the explanation if there is no mark
If (context. currentToken () = null ){
Break;
}
// If it is marked as END, the END is not interpreted and the process is ended. You can continue the subsequent interpretation.
Else if (context. currentToken (). equals ("END ")){
Context. skipToken ("END ");
Break;
}
// If it is another tag, the tag is interpreted and added to the command set.
Else {
Node commandNode = new CommandNode ();
CommandNode. interpret (context );
List. add (commandNode );
}
}
}

// Execute each command in the command set cyclically
Public void execute (){
Iterator iterator = list. iterator ();
While (iterator. hasNext ()){
(Node‑iterator.next(‑cmd.exe cute ();
}
}
}
 
// Statement command node class: Non-terminator expression
Class CommandNode extends Node {
Private Node node;

Public void interpret (Context context ){
// Process the LOOP command
If (context. currentToken (). equals ("LOOP ")){
Node = new LoopCommandNode ();
Node. interpret (context );
}
// Process other basic commands
Else {
Node = new PrimitiveCommandNode ();
Node. interpret (context );
}
}

Public void execute (){
Node.exe cute ();
}
}
 
// Cyclic command node class: Non-terminator expression
Class LoopCommandNode extends Node {
Private int number; // number of cycles
Private Node commandNode; // The expression in the loop statement

// Explain the circular command
Public void interpret (Context context ){
Context. skipToken ("LOOP ");
Number = context. currentNumber ();
Context. nextToken ();
CommandNode = new ExpressionNode (); // The expression in the loop statement
CommandNode. interpret (context );
}

Public void execute (){
For (int I = 0; I <number; I ++)
CommandNode.exe cute ();
}
}
 
// Basic command node class: Terminator expression
Class PrimitiveCommandNode extends Node {
Private String name;
Private String text;

// Explain the basic commands
Public void interpret (Context context ){
Name = context. currentToken ();
Context. skipToken (name );
If (! Name. equals ("PRINT ")&&! Name. equals ("BREAK ")&&! Name. equals ("SPACE ")){
System. err. println ("invalid command! ");
}
If (name. equals ("PRINT ")){
Text = context. currentToken ();
Context. nextToken ();
}
}

Public void execute (){
If (name. equals ("PRINT "))
System. out. print (text );
Else if (name. equals ("SPACE "))
System. out. print ("");
Else if (name. equals ("BREAK "))
System. out. println ();
}
}
In the code of this instance, Context is similar to a tool class. It provides methods for processing commands, such as nextToken (), currentToken (), and skipToken, at the same time, it stores the commands to be interpreted and records the current tokens of each interpretation, and the specific interpretation process is handed over to the expression interpreter class for processing. We can also move the public methods contained in various interpreter classes to the Environment class to better reuse and expand these methods.
For this instance code, we compile the following client test code:
[Java]
Class Client {
Public static void main (String [] args ){
String text = "LOOP 2 PRINT Yang Guo space print maid ";
Context context = new Context (text );

Node node = new ExpressionNode ();
Node. interpret (context );
Node.exe cute ();
}
}
Compile and run the program. The output result is as follows:
Young lady
Young lady
Guo Jing Huang Rong
Author: Liu Wei

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.