JSP compilation into Servlet (2) syntax tree traversal-Visitor Mode
The syntax tree can be understood as a data structure. If some statements have been parsed into a syntax tree, the next step is to process the syntax tree, however, considering that we do not mix processing operations with data structures, we need to separate them. In fact, the most typical processing mode for the syntax tree is the visitor mode. It can well separate the data structure from the processing and provide a good decoupling function, this allows us to focus only on how to build the relevant data structure in the process of generating the syntax tree, but only on the processing logic when processing the syntax tree, it is a very clever design model. Next we will use a simple code case to see how to implement a visitor mode.
① Define the visitor operation method interface and declare the operation methods of all visitors.
Public interface Visitor {
Public void visit (RootNode rootNode );
Public void visit (CommentNode commentNode );
Public void visit (PageNode pageNode );
Public void visit (IncludeNode includeNode );
Public void visit (TaglibNode taglibNode );
}
② Define an interface to provide an access entry. each node in the syntax tree must implement this method.
Public interface NodeElement {
Public void accept (Visitor v );
}
③ Different types of nodes implement the NodeElement interface. Modify the previously defined Node class slightly, including RootNode, CommentNode, PageNode, IncludeNode, and TaglibNode, and add the accept method.
Public class RootNode implements NodeElement {
Public void accept (Visitor v ){
V. visit (this );
}
}
Public class CommentNode implements NodeElement {
Public void accept (Visitor v ){
V. visit (this );
}
}
...
④ Now, if I want to obtain the comments in the syntax tree in order, I only need to implement a visitor to get the comments. For different processing logics, I only need to implement different visitor, because other types of nodes are not processed, leave the visit method of other nodes empty.
Public class CommentVisitor implements Visitor {
Public List GetComments (rootNode ){
List Comments = new ArrayList ();
List Nodes = rootNode. getNodes ();
Iterator Iter = nodes. iterator ();
While (iter. hasNext ()){
Node n = iter. next ();
N. accept (this );
}
Return comments;
}
Public void visit (RootNode rootNode ){}
Public void visit (CommentNode commentNode ){
Comments. add (commentNode. getText ());
}
Public void visit (PageNode pageNode ){}
Public void visit (IncludeNode includeNode ){}
Public void visit (TaglibNode taglibNode ){}
}
⑤ Test class.
Public class Test {
Public static void main (String [] args ){
RootNode root = Parser. parse ();
CommentVisitor cv = new CommentVisitor ();
List Comments = cv. getComments ();
}
}
The preceding simple example shows that the visitor mode decouples the data structure and processing logic. This mode is often used in parsing and processing the syntax tree, familiarity with this mode helps you understand the compilation process, as does JSP parsing the syntax.