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 ...
随机推荐
- Hadoop Hive概念学习系列之hive里的用户定义函数UDF(十七)
Hive可以通过实现用户定义函数(User-Defined Functions,UDF)进行扩展(事实上,大多数Hive功能都是通过扩展UDF实现的).想要开发UDF程序,需要继承org.apache ...
- 消息队列 (2) java实现简单的RabbtMQ
假设有如下问题: 1.如果消费者连接中断,这期间我们应该怎么办? 2.如何做到负载均衡? 3.如何有效的将数据发送到相关的接收者?就是怎么样过滤 4.如何保证消费者收到完整正确的数据 5.如何让优先级 ...
- 【MySQL】二进制分发安装
操作系统:Red Hat Enterprise Linux Server release 6.5 Mysql安装包:mysql-5.6.34-linux-glibc2.5-x86_64.tar.gz ...
- 解决hash冲突的三个方法-考虑获取
哈希表值的获取要考虑全部可能空间. 在链地址法中,可能空间就是具有相同hash值的链表. 目录 开放定址法 线性探测再散列 二次探测再散列 伪随机探测再散列 再哈希法 链地址法 建立公共溢出区 优 ...
- Concurrency and Application Design
Concurrency and Application Design In the early days of computing, the maximum amount of work per un ...
- mybatis 简单的入门实例
第一步:添加mybaties的架包 第二步:配置mybaties的文件 <?xml version="1.0" encoding="UTF-8" ?> ...
- react 父组件调用子组件方法
import React from 'react'import '../page1/header.css'import { Table } from 'antd'import Child from ' ...
- 阅读《JavaScript设计模式》第二章心得
面向对象编程 面向对象编程就是将你的需求抽象成一个对象.然后针对这个对象分析其特征(属性)与动作(方法).这个对象我们称之为类.面向对象编程思想其中的一个特点就是封装. 1.私有属性.私有方法.特权方 ...
- NOIP2018 滚粗记
Day -2 上午,大家都在复习各种模板,zhx总结了足足67个模板(杨辉三角也算模板???),lgl死磕FFT发现cos和sin打反了,我也是复习板子和以前做过的题,几乎没有人颓. 接着jdr,l ...
- 关于嵌入式web服务器
1.boa的配置文件boa.conf Port 80 //服务访问端口 User 0 Group 0 ErrorLog /var/log/boa/error_log //错误日志地址 AccessLo ...