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

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

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类,包括RootNode、CommentNode、PageNode、IncludeNode、TaglibNode,都添加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对语法的解析也是如此。

喜欢java的同学可以交个朋友

JSP编译成Servlet(二)语法树的遍历——访问者模式的更多相关文章

  1. JSP编译成Servlet(四)JSP与Java行关系映射

    我们知道java虚拟机只认识class文件,要在虚拟机上运行就必须要遵守class文件格式,所以JSP编译成servlet后还需要进一步编译成class文件,但从JSP文件到java文件再到class ...

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

    一般来说,语句按一定规则进行推导后会形成一个语法树,这种树状结构有利于对语句结构层次的描述.同样Jasper对JSP语法解析后也会生成一棵树,这棵树各个节点包含了不同的信息,但对于JSP来说解析后的语 ...

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

    JSP编译后的Servlet类会是怎样的呢?他们之间有着什么样的映射关系?在探讨JSP与Servlet之间的关系时先看一个简单的HelloWorld.jsp编译成HelloWorld.java后会是什 ...

  4. JSP编译成Servlet(五)JDT Compiler编译器

    通过JSP编译器编译后生成了对应的java文件,接下去要把Java文件编译成class文件.对于这部分完全没有必要重新造轮子,常见的优秀编译工具有Eclipse JDT Java编译器和Ant编译器. ...

  5. jsp页面编译成Servlet类文件

    package org.apache.jsp; import javax.servlet.*; import javax.servlet.http.*; import javax.servlet.js ...

  6. JSP/Servlet基础语法

    相关学习资料 http://my.oschina.net/chape/blog/170247 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp ...

  7. JSP转译成Servlet详细过程【转】

    JSP转译成Servlet详细过程 JSP是Servlet的扩展,在没有JSP之前,就已经出现了Servlet技术.Servlet是利用输出流动态生成HTML页面,包括每一个HTML标签和每个在HTM ...

  8. jsp编译原理

    jsp运行时都要先转换成servlet,使用tomcat时会在tomcat安装目录下的work生成一系列的运行的项目文件夹,文件下面含有.java文件和编译后的.class文件.jsp最终转化为ser ...

  9. JSP编译指令、JSP动作指令

    JSP编译指令:通过指令中的属性配置来向JSP容器发出指令,用来控制JSP页面的某些特征 JSP指令格式:<%@ 指令名   [一个或多个指令属性]%> 1.page:用于对JSP页面中的 ...

随机推荐

  1. Jmeter_ForEach控制器实现网页爬虫

    一直以来,爬虫似乎都是写代码去实现的,今天像大家介绍一下Jmeter如何实现一个网页爬虫! Jmeter的爬虫原理其实很简单,就是对网页提交一个请求,然后把返回的所有href提取出来,利用ForEac ...

  2. python学习之路网络编程篇(第五篇)

    paramiko简介 paramiko 是基于Python实现的SSH2远程安装连接,支持认证及秘钥方式.可以实现远程命令执行.文件传输.中间SSH代理等功能. paramiko安装 #!/bin/b ...

  3. jQuery 效果 – 隐藏和显示

    在 jQuery 中可以使用 hide() 和 show() 方法来隐藏和显示 HTML 元素,以及使用 toggle() 方法能够切换 hide() 和 show() 方法. 隐藏.显示.切换,滑动 ...

  4. PHP 实例 AJAX 与 XML

    在 PHP 中,AJAX 可用来与 XML 文件进行交互式通信,具体的通信过程,请参考本文内容! AJAX XML 实例 下面的实例将演示网页如何通过 AJAX 从 XML 文件读取信息: 实例   ...

  5. git 撤销没有提交的变化

    参考: https://stackoverflow.com/questions/5807137/how-to-revert-uncommitted-changes-including-files-an ...

  6. win10+ubuntu双系统安装方案

    网上有很多教程,大多是win7,win8的,我折腾了一天,今天终于都安装好了,折腾的够呛,很多人都说挺简单的,嗯其实的确很简单,很多人回复说安装不成功,很有可能就是电脑安全权限的问题,我用的是华硕的电 ...

  7. [CSDN_Markdown] 使用LaTeX写矩阵

    简介 LaTeX 的公式功能非常强大,一次性讲全不是件容易的事情.将LaTeX 的这些功能分成较小的相互独立的部分来讲,一方面方便大家单独查阅:另一方面,所有[CSDN_Markdown]相关的文章都 ...

  8. Android的Spinner控件用法解析

    微调框 微调框提供一种方法,让用户可以从值集中快速选择一个值.默认状态下,微调框显示其当前所选的值. 触摸微调框可显示下拉菜单,其中列有所有其他可用值,用户可从中选择一个新值. 您可以使用 Spinn ...

  9. PHP和MySQL Web开发学习笔记介绍

    前言 从2016年2月1日开始,之后的几个月左右的时间里,我会写一个系列的PHP和MySQL Web开发的学习笔记.我之前一直从事Java语言的开发工作,最近这段时间非常想学习一门语言,就选择了PHP ...

  10. activiti 多实例任务

    1.1.1. 前言 个人,那么当5个人都投票的时候大概分为如下几种: 1.部门所有人都去投票,当所有人都投票完成的时候,这个节点结束,流程运转到下一个节点.(所有的人都需要投票) 2.部门所有人都去投 ...