您的位置:首页 > 其它

freemarker源码解读之一--概述

2015-09-08 17:44 323 查看
最近在思考为如何xsoup添加自定义函数支持,基于这个目的,想起了最常用的模板引擎freemarker。于是down了源码下来,开始浏览一番。本文基于https://github.com/freemarker/freemarker上的2.3.20版本。


思考

看源码前,先思考一下,一个模板引擎,到底需要哪些东西?一门模板引擎其实是一个完整的语言,只不过它只具有单纯的输入/输出,不需要考虑其他的功能。

语法解析,转换为AST(抽象语法树)

语义分析,为AST附加上执行语义

上下文环境的注入

内置函数及外部函数支持

其他外围机制(与框架/工具的集成等)


源码结构

打开freemarker的代码,core包里110个类一字排开,还有以下划线开头的“建议不要看”的类,看的人眼花缭乱啊!这一切都是因为Java规范的大师们,设计了一个“包级可见“的概念,大概就是,我写给自己用的代码,不要让你用!这一来,别人用是用不了了,好像看起来也变得很困难了…

还好现在的IDE都很强大,刷刷两下就给重构了,把一些类按照类型挪到多个包里,顿时清爽很多!可惜好多类/方法/字段都是包级可见,为了让这个重构版freemarker没那么多红叉,lz加了好几百个public,写到意识都模糊了…最后把自己的劳动成果共享出来吧:https://github.com/code4craft/freemarker-learning。主要是将freemarker.core包里内容拆开了,语法树相关的内容放到了freemarker.core.nodes包,异常放到了freemarker.core.exception包,一些模板内置功能放到了freemarker.core.buildin包,还有工具类放到了freemarker.core.util包。

顺便将freemarker的流程整理了一下:



这是一个很经典的模板引擎的执行流程:

Configuration可以理解为一个工厂,它负责产生一个对外接口Template类。它首先会从cache中查找是否已经有编译好的Template,如果不存在,则对模板进行编译。
Template实际上是一个带执行语义的语法树,树的节点是TemplateObject。
FMParser是javacc生成的语法解析类,它最终输出是以FMParser.root()为根的语法树。
dataModel是外部对模板引擎的数据输入,它会被转化为TemplateModel,并代入模板的渲染过程。
最后的步骤是根据数据,遍历编译好的语法树,并输出结果,这一步的入口时TemplateElement.accept()。


关于JavaCC

freemarker使用了JavaCC(Java Compiler Compiler)做parser。关于JavaCC,有一篇很好的入门帖,顺带复习一下编译原理:LL(0)文法,消除左递归等东西。http://cs.lmu.edu/~ray/notes/javacc/

JavaCC的下载在这里:http://javacc.java.net/,不知是我操作失误还是怎样,下载JavaCC-6.0之后,bin目录只有lib/javacc.jar文件。下载JavaCC-5.0src之后,才找到javacc脚本。难道就这么几百K的东西,还要搞增量更新?

总之下载成功之后,用javacc FTL.jj,即可生成一堆Parser文件。核心是FMParser,解析完的语法树在FMParser.root()里。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: