概述
AderTemplate是一个小型的模板引擎。无论是拿来直接使用还是用来研究模板引擎实现方式,都是一个不错的选择。本文尝试对其源代码做一些分析。
数据流程
AderTemplate的数据处理流程可以总结为:
模版文件 -> 模版分析 -> Template对象 -> 分析处理Template的Element集合 -> 输出目标文本
模版语法
简化描述如下:
1,变量替换 :如#variable#
2,循环语句 :<ad:foreach var="x" collection="#values#" index=”i”></ad:foreach>
3,判断语句 :<ad:if test="#value#"> </ad:if>
详细请参看AderTemplate的相关说明.
模版分析
模版分析的过程可以分成两步:
1,把模版文件分析成Token流 ;
2,对Token流进行分析,形成Element集合
所以,首先要了解Token和Element的结构与异同。
Token的类结构:
TokenKind(Token的类型)的详细说明:
TokenKind |
说明 |
EOF |
结束符 |
Comment |
注释,但在AderTemplate没看到具体实现 |
ID |
这个比较难描述,下面会通过输出Token流来直官了解下ID |
TextData |
文本数据,不包含模版语法的独立文本区 |
TagStart |
Tag的开始标记,即<ad: 注:Tag是一个Element,后面详述 |
TagEnd |
Tag的结束符,即 > ,注意与TagClose的区别 |
TagEndClose |
Tag的自闭结束符 ,即 /> |
TagClose |
Tag的结束标记 即</ad: 与<ad:对应,所以与TagEnd很容易区别 |
TagEquals |
Tag的=符号。与Tag无关的=属于TextData,非TagEquals |
ExpStart |
在AderTemplate中,语法#v#被定义为Expression.左#为ExpStart |
ExpEnd |
在AderTemplate中,语法#v#被定义为Expression.右#为ExpEnd |
LParent |
左括号 ( |
RParent |
右括号 ) |
Dot |
即一个点 . |
Comma |
逗号 , |
Integer |
数字 |
StringStart |
文本的开始符,即” |
StringEnd |
文本的结束符,即” |
StringText |
How to description ? |
为了获得更直观的认识。下面尝试把一个简单的模版文件分析的Token流输出。
模版文件,我们暂且命名为templateFile
<ad:foreach collection="#GetBookList(3)#" var="book" index="i">
<tr>
<td>#i#</td>
<td>#book.BookName#</td>
<td>#book.BookCount#</td>
</tr>
</ad:foreach>
分析的代码:
static void
{
string data = string.Empty;
using (System.IO.StreamReader reader = new System.IO.StreamReader(templateFile))
{
data = reader.ReadToEnd();
}
//模版分析,形成Token流
TemplateLexer lexer = new TemplateLexer(data);
Console.WriteLine("=======开始输出TemplateLexer分析出Token流=======");
do
{
Token token = lexer.Next();
Console.WriteLine("\tToken类型:{0}\t行列:({1}, {2})\t数据:{3}", token.TokenKind.ToString(), token.Line, token.Col
, token.Data.Replace("\r\n", ""));
if (token.TokenKind == TokenKind.EOF)
break;
} while (true);
Console.WriteLine("=======结束输出TemplateLexer分析出Token流=======\r\n");
}
输出结果: