diff options
Diffstat (limited to 'libgo/go/text/template/parse/parse.go')
-rw-r--r-- | libgo/go/text/template/parse/parse.go | 57 |
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: |