关闭

JSP编译成Servlet(二)语法树的遍历——访问者模式

标签: jspservlet编译语法树访问者模式
2926人阅读 评论(1) 收藏 举报
分类:

语法树可以理解成是一种数据结构,假如某些语句已经被解析成一棵语法树,那么接下来就是要对此语法树进行处理,但考虑到不将处理操作与数据结构混合在一块,我们需要一种方法将其分离。其实对于语法树的处理最典型的处理模式就是访问者模式,它能很好的将数据结构与处理分离,提供了很好的解耦作用,让我们可以在生成语法树的过程只需关注如何构建相关的数据结构,而在对语法树处理的时候只需关注处理的逻辑,是一种非常巧的设计模式,接下来通过一个简单的代码案例看看如何实现一个访问者模式。

①定义访问者操作方法接口,声明所有访问者的操作方法。

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);

}

②定义接口提供访问入口,语法树的每个节点都必须要实现此方法。

public interface NodeElement{

    public void accept(Visitor v);

}

③不同类型的Node实现NodeElement接口,稍微改下原来定义的Node类,包括RootNodeCommentNodePageNodeIncludeNodeTaglibNode,都添加accept方法。

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);

    }

}

...

④现在假设我要按顺序将语法树中的注释获取出来,那么我只需要实现一个获取注释的visitor,对于不同的处理逻辑只需实现不同的visitor即可,这里由于对其他类型的节点不进行处理,所以其他节点的visit方法留空即可。

public class CommentVisitor implements Visitor{

    public List<String> getComments(rootNode){

        List<String> comments = new ArrayList();

        List<Node> nodes = rootNode.getNodes();

        Iterator<Node> 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){}

}

⑤测试类。

public class Test{

    public static void main(String[] args){

        RootNode root = Parser.parse();

        CommentVisitor cv = new CommentVisitor();

        List<String> comments = cv.getComments();

    }

}

    通过上面一个简单的例子可以看出访问者模式将数据结构和处理逻辑很好地解耦出来了,这种模式很经常用在语法树的解析处理上,熟悉此模式有助于对编译过程的理解,JSP对语法的解析也是如此。



点击订购作者《Tomcat内核设计剖析》




0
0
查看评论

JSP编译成Servlet(一)语法树的生成——语法解析

一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述。同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语法树比较简单,只有一个父节点和n个子节点。例如node1是表示形如字符串 -->的注释节点,节...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2016-03-18 16:46
  • 3438

jsp编译成servlet文件的分析

JSP是Servlet的扩展,在没有JSP之前,就已经出现了Servlet技术。Servlet是利用输出流动态生成HTML页面,包括每一个HTML标签和每个在HTML页面中出现的内容。     由于包括大量的HTML标签、大量的静态文本及格式等,导致Servlet的开...
  • ld513508088
  • ld513508088
  • 2014-03-15 07:10
  • 4646

jsp和servlet的关系?答:jsp就是servlet,tomcat会把jsp编译成servlet,servlet就是一个java类,在tomcat下的work文件夹中

JSP与Servlet什么关系?JSP和ASP什么关系?下面我们一一来探讨。   第一个.jsp文件:                HelloWorldJSP~     ...
  • Ideality_hunter
  • Ideality_hunter
  • 2016-05-28 23:15
  • 2271

Jsp 与 Servlet的编译过程、原理、区别及使用

一、 编译过程 每一个JSP页面都会被Web容器编译成一个Java类,供web容器调用,并且生成HTML页面回馈给用户。而了解其中的编译方法和规则,对我们学习JSP是非常有好处的,可以说学习好了这个编译原理,就已经学习好了大部分的JSP知识,剩下的工作就只剩下熟记一些tablib和反复应...
  • shenlin2011
  • shenlin2011
  • 2014-06-29 17:00
  • 2150

JSP编译成Servlet(三)JSP编译后的Servlet

JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什么样。①HelloWorld.jsp     &#...
  • wangyangzhizhou
  • wangyangzhizhou
  • 2016-03-18 16:55
  • 3382

查看eclipse web项目中jsp编译后的servlet源文件

eclipse中,jsp编译后 servlet源文件的位置为: F:\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\demo\org\apache\jsp 注:我的wor...
  • chengmaoning
  • chengmaoning
  • 2013-08-07 15:51
  • 3027

请求JSP页面时,服务端会把jsp编译成java类(servlet)

很多人都会认为JSP的执行性能会和Servlet相差很多,其实执行性能上的差别只在第一次的执行。因为JSP在执行第一次后,会被编译成Servlet的类文件,即.class,当再重复调用执行时,就直接执行第一次所产生的Servlet,而不再重新把JSP编译成Servelt。 因此,除了第一次的编译会...
  • gchonghavefun
  • gchonghavefun
  • 2012-11-17 23:45
  • 2498

JSP转译为Servlet错误可能发生的3个时候

JSP终究会转译为Servlet, 所以错误可能发生在3个时候: JSP转换为Servlet源代码时. 如果在JSP页面中编写了一些错误语法, 而使得容器在转译JSP时不知道该如何将那些语法转译为Servlet的.java文件, 就会发生错误. 例如, 在page指令元...
  • u012934551
  • u012934551
  • 2016-01-14 21:42
  • 627

解释抽象语法树

解释抽象语法树   创建了抽象语法树之后,有两个选择:解释或编译。解释,简单地说,就是遍历树,同时执行操作;编译,就是改变成其他形式,对于机器执行来说可能更简单,通常可能更快。这一小节先讨论如何解释结果,下面一小节再讨论编译的内容,最后,再讨论何时应该用解释,何时应该用编译的问题。 ...
  • hadstj
  • hadstj
  • 2014-06-04 14:28
  • 2288

ANTLR教程(四)语法树遍历机制

目录 1. 方法一: 使用antlr定义的语法树遍历顺序——listener1.1. 类的继承关系 1.2. 需要与antlr遍历类ParseTreeWalker一起使用 1.3. 对同一非终结符的不同产生式进行标记1.3.1. 不标记的话实现起来复杂 1.3.2. 解决方法: 标记产生式 1.4....
  • timesir
  • timesir
  • 2017-10-05 15:11
  • 599
    作者
    https://github.com/sea-boat

    公众号:(内容包括分布式、机器学习、深度学习、NLP、Java深度、Java并发核心、JDK源码、Tomcat内核等等)



    微信:

    打赏作者

    如果您觉得作者写的文章有帮助到您,您可以打赏作者一瓶汽水(*^__^*)

    个人资料
    • 访问:1064077次
    • 积分:14086
    • 等级:
    • 排名:第1048名
    • 原创:326篇
    • 转载:5篇
    • 译文:1篇
    • 评论:348条
    博客专栏
    最新评论