diff options
Diffstat (limited to 'libgo/go/text/template/parse/lex.go')
-rw-r--r-- | libgo/go/text/template/parse/lex.go | 90 |
1 files changed, 59 insertions, 31 deletions
diff --git a/libgo/go/text/template/parse/lex.go b/libgo/go/text/template/parse/lex.go index 94a676c..3d57708 100644 --- a/libgo/go/text/template/parse/lex.go +++ b/libgo/go/text/template/parse/lex.go @@ -107,17 +107,18 @@ type stateFn func(*lexer) stateFn // lexer holds the state of the scanner. type lexer struct { - name string // the name of the input; used only for error reports - input string // the string being scanned - leftDelim string // start of action - rightDelim string // end of action - pos Pos // current position in the input - start Pos // start position of this item - width Pos // width of last rune read from input - items chan item // channel of scanned items - parenDepth int // nesting depth of ( ) exprs - line int // 1+number of newlines seen - startLine int // start line of this item + name string // the name of the input; used only for error reports + input string // the string being scanned + leftDelim string // start of action + rightDelim string // end of action + trimRightDelim string // end of action with trim marker + pos Pos // current position in the input + start Pos // start position of this item + width Pos // width of last rune read from input + items chan item // channel of scanned items + parenDepth int // nesting depth of ( ) exprs + line int // 1+number of newlines seen + startLine int // start line of this item } // next returns the next rune in the input. @@ -210,13 +211,14 @@ func lex(name, input, left, right string) *lexer { right = rightDelim } l := &lexer{ - name: name, - input: input, - leftDelim: left, - rightDelim: right, - items: make(chan item), - line: 1, - startLine: 1, + name: name, + input: input, + leftDelim: left, + rightDelim: right, + trimRightDelim: rightTrimMarker + right, + items: make(chan item), + line: 1, + startLine: 1, } go l.run() return l @@ -275,14 +277,12 @@ func rightTrimLength(s string) Pos { // atRightDelim reports whether the lexer is at a right delimiter, possibly preceded by a trim marker. func (l *lexer) atRightDelim() (delim, trimSpaces bool) { - if strings.HasPrefix(l.input[l.pos:], l.rightDelim) { - return true, false - } - // The right delim might have the marker before. - if strings.HasPrefix(l.input[l.pos:], rightTrimMarker) && - strings.HasPrefix(l.input[l.pos+trimMarkerLen:], l.rightDelim) { + if strings.HasPrefix(l.input[l.pos:], l.trimRightDelim) { // With trim marker. return true, true } + if strings.HasPrefix(l.input[l.pos:], l.rightDelim) { // Without trim marker. + return true, false + } return false, false } @@ -366,6 +366,7 @@ func lexInsideAction(l *lexer) stateFn { case r == eof || isEndOfLine(r): return l.errorf("unclosed action") case isSpace(r): + l.backup() // Put space back in case we have " -}}". return lexSpace case r == '=': l.emit(itemAssign) @@ -418,10 +419,26 @@ func lexInsideAction(l *lexer) stateFn { } // lexSpace scans a run of space characters. -// One space has already been seen. +// We have not consumed the first space, which is known to be present. +// Take care if there is a trim-marked right delimiter, which starts with a space. func lexSpace(l *lexer) stateFn { - for isSpace(l.peek()) { + var r rune + var numSpaces int + for { + r = l.peek() + if !isSpace(r) { + break + } l.next() + numSpaces++ + } + // Be careful about a trim-marked closing delimiter, which has a minus + // after a space. We know there is a space, so check for the '-' that might follow. + if strings.HasPrefix(l.input[l.pos-1:], l.trimRightDelim) { + l.backup() // Before the space. + if numSpaces == 1 { + return lexRightDelim // On the delim, so go right to that. + } } l.emit(itemSpace) return lexInsideAction @@ -565,17 +582,28 @@ func (l *lexer) scanNumber() bool { // Optional leading sign. l.accept("+-") // Is it hex? - digits := "0123456789" - if l.accept("0") && l.accept("xX") { - digits = "0123456789abcdefABCDEF" + digits := "0123456789_" + if l.accept("0") { + // Note: Leading 0 does not mean octal in floats. + if l.accept("xX") { + digits = "0123456789abcdefABCDEF_" + } else if l.accept("oO") { + digits = "01234567_" + } else if l.accept("bB") { + digits = "01_" + } } l.acceptRun(digits) if l.accept(".") { l.acceptRun(digits) } - if l.accept("eE") { + if len(digits) == 10+1 && l.accept("eE") { + l.accept("+-") + l.acceptRun("0123456789_") + } + if len(digits) == 16+6+1 && l.accept("pP") { l.accept("+-") - l.acceptRun("0123456789") + l.acceptRun("0123456789_") } // Is it imaginary? l.accept("i") |