Golang Template source code analysis(Parse)
This blog was written at go 1.3.1 version.
We know that we use template thought by followed way:
func main() {
name := "waynehu"
tmpl := template.New("test")
tmpl, err := tmpl.Parse("hello {{.}}")
if err != nil {
panic(err)
}
err = tmpl.Execute(os.Stdout, name)
if err != nil {
panic(err)
}
}
It mainly has three steps,the first is allow template,the second is tmpl.Parse,the third is tmpl.Execute(os.Stdout, name),the first step is simple.This blog introduces the second step.
- Major Class
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXAxMjB5cA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
The ListNode struct:
// ListNode holds a sequence of nodes.
type ListNode struct {
NodeType
Pos
Nodes []Node // The element nodes in lexical order.
}
The "NodeType" and "Pos" is as same as int.
- Sequence Diagram
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXAxMjB5cA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
- The key of parts of code
// lex creates a new scanner for the input string.
func lex(name, input, left, right string) *lexer {
if left == "" {
left = leftDelim
}
if right == "" {
right = rightDelim
}
l := &lexer{
name: name,
input: input,
leftDelim: left,
rightDelim: right,
items: make(chan item),
}
go l.run()
return l
}
// run runs the state machine for the lexer.
func (l *lexer) run() {
for l.state = lexText; l.state != nil; {
l.state = l.state(l)
}
}
l.emit(itemText) is handle static text information and lexLeftDelim is handle dynamic information.
// lexText scans until an opening action delimiter, "{{".
func lexText(l *lexer) stateFn {
for {
if strings.HasPrefix(l.input[l.pos:], l.leftDelim) {
if l.pos > l.start {
l.emit(itemText)
}
return lexLeftDelim
}
if l.next() == eof {
break
}
}
// Correctly reached EOF.
if l.pos > l.start {
l.emit(itemText)
}
l.emit(itemEOF)
return nil
}
lexComment is hande comment without analysis
// lexLeftDelim scans the left delimiter, which is known to be present.
func lexLeftDelim(l *lexer) stateFn {
l.pos += Pos(len(l.leftDelim))
if strings.HasPrefix(l.input[l.pos:], leftComment) {
return lexComment
}
l.emit(itemLeftDelim)
l.parenDepth = 0
return lexInsideAction
}
any syntax parsing are transmited by "chan item" is a channel.and take away it thought func (l *lexer) nextItem() item function.
put value in emit function.
// emit passes an item back to the client.
func (l *lexer) emit(t itemType) {
l.items <- item{t, l.start, l.input[l.start:l.pos]}
l.start = l.pos
}
followed function produce t.Root list thought nextNonSpace bring value to
// parse is the top-level parser for a template, essentially the same
// as itemList except it also parses {{define}} actions.
// It runs to EOF.
func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
t.Root = newList(t.peek().pos)
for t.peek().typ != itemEOF {
if t.peek().typ == itemLeftDelim {
delim := t.next()
if t.nextNonSpace().typ == itemDefine {
newT := New("definition") // name will be updated once we know it.
newT.text = t.text
newT.ParseName = t.ParseName
newT.startParse(t.funcs, t.lex)
newT.parseDefinition(treeSet)
continue
}
t.backup2(delim)
}
n := t.textOrAction()
if n.Type() == nodeEnd {
t.errorf("unexpected %s", n)
}
t.Root.append(n)
}
return nil
}
// nextNonSpace returns the next non-space token.
func (t *Tree) nextNonSpace() (token item) {
for {
token = t.next()
if token.typ != itemSpace {
break
}
}
return token
}
take away item in nextItem function
// nextItem returns the next item from the input.
func (l *lexer) nextItem() item {
item := <-l.items
l.lastPos = item.pos
return item
}
To be continued
Golang Template source code analysis(Parse)的更多相关文章
- Memcached source code analysis (threading model)--reference
Look under the start memcahced threading process memcached multi-threaded mainly by instantiating mu ...
- Memcached source code analysis -- Analysis of change of state--reference
This article mainly introduces the process of Memcached, libevent structure of the main thread and w ...
- Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis
Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...
- Redis source code analysis
http://zhangtielei.com/posts/blog-redis-dict.html http://zhangtielei.com/assets/photos_redis/redis_d ...
- linux kernel & source code analysis& hacking
https://kernelnewbies.org/ http://www.tldp.org/LDP/lki/index.html https://kernelnewbies.org/ML https ...
- 2018.6.21 HOLTEK HT49R70A-1 Source Code analysis
Cange note: “Reading TMR1H will latch the contents of TMR1H and TMR1L counter to the destination”? F ...
- The Ultimate List of Open Source Static Code Analysis Security Tools
https://www.checkmarx.com/2014/11/13/the-ultimate-list-of-open-source-static-code-analysis-security- ...
- Top 40 Static Code Analysis Tools
https://www.softwaretestinghelp.com/tools/top-40-static-code-analysis-tools/ In this article, I have ...
- Source Code Reading for Vue 3: How does `hasChanged` work?
Hey, guys! The next generation of Vue has released already. There are not only the brand new composi ...
随机推荐
- Kafka的3节点集群详细启动步骤(Zookeeper是外装)
首先,声明,kafka集群是搭建在hadoop1.hadoop2和hadoop3机器上. kafka_2.10-0.8.1.1.tgz的1或3节点集群的下载.安装和配置(图文详细教程)绝对干货 如下分 ...
- 编译安装php、nginx
以centos6.6为例 1.安装以及配置php 首先在官网下载源码包http://php.net/downloads.php 这里下载php-7.1.16 .tar.gzcd php-7.1.16 ...
- [转帖]c++ 面试整理
1. 继承方式 public 父类的访问级别不变 protected 父类的public成员在派生类编程protected,其余的不变 private 父类的所有成员变成pr ...
- dnn 添加图片
public string fileUpload() { if (fuPhoto.PostedFile != null && fuPhoto.P ...
- Vue项目优化首屏加载速度
Vue项目部署上线后经常会发现首屏加载的速度特别慢:那么有那写能做的简单优化呢 一.路由的懒加载 路由懒加载也就是 把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件. 结合 ...
- Scrapy爬虫框架 基础
1< scrapy的安装 命令行安装 pip install scrapy <常见错误是缺少 wim32api 安装win32api pip install pywin32 <还有就 ...
- 网络爬虫 robots协议 robots.txt
网络爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上 ...
- Java并发——阿里架构师是如何巧用线程池的!
一.创建线程 1.创建普通对象,只是在JVM的堆里分配一块内存而已 2.创建线程,需要调用操作系统内核的API,然后操作系统需要为线程分配一系列资源,成本很高 线程是一个重量级对象,应该避免频繁创建和 ...
- Django - 视图获取请求头
1.urls.py(url和函数对应关系) 2.通过request.evniron,返回request的所有信息,用索引的方式,获取用户请求头信息. 3.也可以通过key,value方式,来展示请求头 ...
- Asp.Mvc 常用
url转义 var address = "http://www.cnblog.com"; var a22 = Uri.EscapeDataString(address); var ...