summaryrefslogtreecommitdiffstats
path: root/libgo/go/text/template/parse/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/text/template/parse/parse.go')
-rw-r--r--libgo/go/text/template/parse/parse.go57
1 files changed, 40 insertions, 17 deletions
diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go
index e906ee83aac..346f613b048 100644
--- a/libgo/go/text/template/parse/parse.go
+++ b/libgo/go/text/template/parse/parse.go
@@ -13,10 +13,10 @@ import (
"unicode"
)
-// Tree is the representation of a parsed template.
+// Tree is the representation of a single parsed template.
type Tree struct {
- Name string // Name is the name of the template.
- Root *ListNode // Root is the top-level root of the parse tree.
+ Name string // name of the template represented by the tree.
+ Root *ListNode // top-level root of the tree.
// Parsing only; cleared after parse.
funcs []map[string]interface{}
lex *lexer
@@ -25,6 +25,16 @@ type Tree struct {
vars []string // variables defined at the moment.
}
+// Parse returns a map from template name to parse.Tree, created by parsing the
+// templates described in the argument string. The top-level template will be
+// given the specified name. If an error is encountered, parsing stops and an
+// empty map is returned with the error.
+func Parse(name, text, leftDelim, rightDelim string, funcs ...map[string]interface{}) (treeSet map[string]*Tree, err error) {
+ treeSet = make(map[string]*Tree)
+ _, err = New(name).Parse(text, leftDelim, rightDelim, treeSet, funcs...)
+ return
+}
+
// next returns the next token.
func (t *Tree) next() item {
if t.peekCount > 0 {
@@ -58,7 +68,7 @@ func (t *Tree) peek() item {
// Parsing.
-// New allocates a new template with the given name.
+// New allocates a new parse tree with the given name.
func New(name string, funcs ...map[string]interface{}) *Tree {
return &Tree{
Name: name,
@@ -87,6 +97,15 @@ func (t *Tree) expect(expected itemType, context string) item {
return token
}
+// expectEither consumes the next token and guarantees it has one of the required types.
+func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
+ token := t.next()
+ if token.typ != expected1 && token.typ != expected2 {
+ t.errorf("expected %s or %s in %s; got %s", expected1, expected2, context, token)
+ }
+ return token
+}
+
// unexpected complains about the token and terminates processing.
func (t *Tree) unexpected(token item, context string) {
t.errorf("unexpected %s in %s", token, context)
@@ -107,7 +126,7 @@ func (t *Tree) recover(errp *error) {
return
}
-// startParse starts the template parsing from the lexer.
+// startParse initializes the parser, using the lexer.
func (t *Tree) startParse(funcs []map[string]interface{}, lex *lexer) {
t.Root = nil
t.lex = lex
@@ -143,17 +162,27 @@ func (t *Tree) atEOF() bool {
return false
}
-// Parse parses the template definition string to construct an internal
-// representation of the template for execution. If either action delimiter
-// string is empty, the default ("{{" or "}}") is used.
+// Parse parses the template definition string to construct a representation of
+// the template for execution. If either action delimiter string is empty, the
+// default ("{{" or "}}") is used. Embedded template definitions are added to
+// the treeSet map.
func (t *Tree) Parse(s, leftDelim, rightDelim string, treeSet map[string]*Tree, funcs ...map[string]interface{}) (tree *Tree, err error) {
defer t.recover(&err)
t.startParse(funcs, lex(t.Name, s, leftDelim, rightDelim))
t.parse(treeSet)
+ t.add(treeSet)
t.stopParse()
return t, nil
}
+// add adds tree to the treeSet.
+func (t *Tree) add(treeSet map[string]*Tree) {
+ if _, present := treeSet[t.Name]; present {
+ t.errorf("template: multiple definition of template %q", t.Name)
+ }
+ treeSet[t.Name] = t
+}
+
// parse is the top-level parser for a template, essentially the same
// as itemList except it also parses {{define}} actions.
// It runs to EOF.
@@ -163,7 +192,7 @@ func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
if t.peek().typ == itemLeftDelim {
delim := t.next()
if t.next().typ == itemDefine {
- newT := New("new definition") // name will be updated once we know it.
+ newT := New("definition") // name will be updated once we know it.
newT.startParse(t.funcs, t.lex)
newT.parseDefinition(treeSet)
continue
@@ -183,11 +212,8 @@ func (t *Tree) parse(treeSet map[string]*Tree) (next Node) {
// installs the definition in the treeSet map. The "define" keyword has already
// been scanned.
func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
- if treeSet == nil {
- t.errorf("no set specified for template definition")
- }
const context = "define clause"
- name := t.expect(itemString, context)
+ name := t.expectOneOf(itemString, itemRawString, context)
var err error
t.Name, err = strconv.Unquote(name.val)
if err != nil {
@@ -200,10 +226,7 @@ func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
t.errorf("unexpected %s in %s", end, context)
}
t.stopParse()
- if _, present := treeSet[t.Name]; present {
- t.errorf("template: %q multiply defined", name)
- }
- treeSet[t.Name] = t
+ t.add(treeSet)
}
// itemList:
OpenPOWER on IntegriCloud