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)的更多相关文章

  1. Memcached source code analysis (threading model)--reference

    Look under the start memcahced threading process memcached multi-threaded mainly by instantiating mu ...

  2. 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 ...

  3. Apache Commons Pool2 源码分析 | Apache Commons Pool2 Source Code Analysis

    Apache Commons Pool实现了对象池的功能.定义了对象的生成.销毁.激活.钝化等操作及其状态转换,并提供几个默认的对象池实现.在讲述其实现原理前,先提一下其中有几个重要的对象: Pool ...

  4. Redis source code analysis

    http://zhangtielei.com/posts/blog-redis-dict.html http://zhangtielei.com/assets/photos_redis/redis_d ...

  5. linux kernel & source code analysis& hacking

    https://kernelnewbies.org/ http://www.tldp.org/LDP/lki/index.html https://kernelnewbies.org/ML https ...

  6. 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 ...

  7. 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- ...

  8. Top 40 Static Code Analysis Tools

    https://www.softwaretestinghelp.com/tools/top-40-static-code-analysis-tools/ In this article, I have ...

  9. 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 ...

随机推荐

  1. Hadoop Hive概念学习系列之hive里的用户定义函数UDF(十七)

    Hive可以通过实现用户定义函数(User-Defined Functions,UDF)进行扩展(事实上,大多数Hive功能都是通过扩展UDF实现的).想要开发UDF程序,需要继承org.apache ...

  2. 消息队列 (2) java实现简单的RabbtMQ

    假设有如下问题: 1.如果消费者连接中断,这期间我们应该怎么办? 2.如何做到负载均衡? 3.如何有效的将数据发送到相关的接收者?就是怎么样过滤 4.如何保证消费者收到完整正确的数据 5.如何让优先级 ...

  3. 【MySQL】二进制分发安装

    操作系统:Red Hat Enterprise Linux Server release 6.5 Mysql安装包:mysql-5.6.34-linux-glibc2.5-x86_64.tar.gz ...

  4. 解决hash冲突的三个方法-考虑获取

    哈希表值的获取要考虑全部可能空间. 在链地址法中,可能空间就是具有相同hash值的链表.   目录 开放定址法 线性探测再散列 二次探测再散列 伪随机探测再散列 再哈希法 链地址法 建立公共溢出区 优 ...

  5. Concurrency and Application Design

    Concurrency and Application Design In the early days of computing, the maximum amount of work per un ...

  6. mybatis 简单的入门实例

    第一步:添加mybaties的架包 第二步:配置mybaties的文件 <?xml version="1.0" encoding="UTF-8" ?> ...

  7. react 父组件调用子组件方法

    import React from 'react'import '../page1/header.css'import { Table } from 'antd'import Child from ' ...

  8. 阅读《JavaScript设计模式》第二章心得

    面向对象编程 面向对象编程就是将你的需求抽象成一个对象.然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中的一个特点就是封装. 1.私有属性.私有方法.特权方 ...

  9. NOIP2018 滚粗记

    Day -2  上午,大家都在复习各种模板,zhx总结了足足67个模板(杨辉三角也算模板???),lgl死磕FFT发现cos和sin打反了,我也是复习板子和以前做过的题,几乎没有人颓. 接着jdr,l ...

  10. 关于嵌入式web服务器

    1.boa的配置文件boa.conf Port 80 //服务访问端口 User 0 Group 0 ErrorLog /var/log/boa/error_log //错误日志地址 AccessLo ...